Lists

The most flexible of structures

Discuss with a neighbor

Which of the following four objects are the same?

seq(1, 6)
seq(1, 3) + seq(4, 6)
c(seq(1, 3), seq(4, 6))
c(c(seq(1, 3), seq(4, 6)))
01:30

Discuss with a neighbor

Which of the following four objects are the same?

seq(1, 6)
[1] 1 2 3 4 5 6
seq(1, 3) + seq(4, 6)
[1] 5 7 9
c(seq(1, 3), seq(4, 6))
[1] 1 2 3 4 5 6
c(c(seq(1, 3), seq(4, 6)))
[1] 1 2 3 4 5 6

Atomic Vectors

By atomic we mean:

  1. All elements of the same type
  2. Cannot contain other vectors

Lists: Type Heterogeneity

Lists, defined

A list is a non-atomic vector that can contain:

  1. Atomic vectors of different types
  2. Other lists

Created with list().

list(1, "rabbit")
[[1]]
[1] 1

[[2]]
[1] "rabbit"

“Contains atomic vectors of different types”

list(1, "rabbit")
[[1]]
[1] 1

[[2]]
[1] "rabbit"
list(1:3, "a", 4:6)
[[1]]
[1] 1 2 3

[[2]]
[1] "a"

[[3]]
[1] 4 5 6

Subsetting

Subsetting with []

[] extracts elements of a vector (atomic or non-atomic) using a subsetting (atomic) vector.

  • Atomic vectors and matrices return atomic vectors
vec <- 1:4
vec[1:2]
[1] 1 2
mat <- matrix(vec, nrow = 2)
mat
     [,1] [,2]
[1,]    1    3
[2,]    2    4
mat[2]
[1] 2

Subsetting with []

[] extracts elements of a vector (atomic or non-atomic) using a subsetting (atomic) vector.

  • Atomic vectors and matrices return atomic vectors
  • Lists return lists
x <- list(1:3, "a", 4:6)
x[1]
[[1]]
[1] 1 2 3
x[2:3]
[[1]]
[1] "a"

[[2]]
[1] 4 5 6

Yes, you can name elements of a list

named_x <- list("Ape" = 1:3, "Boy" = "a", "Cat" = 4:6)
named_x
$Ape
[1] 1 2 3

$Boy
[1] "a"

$Cat
[1] 4 5 6
named_x[c("Boy", "Cat")]
$Boy
[1] "a"

$Cat
[1] 4 5 6

Yes, it works with logicals too

named_x <- list("Ape" = 1:3, "Boy" = "a", "Cat" = 4:6)
named_x[c(FALSE, TRUE, FALSE)]
$Boy
[1] "a"

But what if you want the actual data structure inside the list?

Subsetting single elements with [[]]

[[i]] Extracts original object inside the list.

x <- list(1:3, "a", 4:6)
x[[1]]
[1] 1 2 3

To tell [] and [[]] apart, let’s use a metaphor of a train.

Draw the appropriate train or car for each of the following

  1. x[1:2]
  2. x[[3]]
  3. x[-2]
  4. x[c(1, 1)]
  5. c(x[[3]], x[[1]])
02:30

Subsetting single elements with $

$ will extract a single element of a list by name.

named_x <- list("Ape" = 1:3, "Boy" = "a", "Cat" = 4:6)
named_x$Cat
[1] 4 5 6
named_x$C
[1] 4 5 6

Permits partial matching.

Lists: Nesting

Lists, defined

A list is a non-atomic vector that can contain:

  1. Atomic vectors of different types
  2. Other lists
list(1, "rabbit", list(TRUE, 1:3))
[[1]]
[1] 1

[[2]]
[1] "rabbit"

[[3]]
[[3]][[1]]
[1] TRUE

[[3]][[2]]
[1] 1 2 3

Implications for subsetting

y <- list(1, "rabbit", list(TRUE, 1:3))

Draw the train:

y <- list(1, "rabbit", list(TRUE, 1:3))

Draw the train and then write the R code to extract:

  1. The list containing the character vector with "rabbit
  2. The vector "rabbit"
  3. The second element of the list element in y
  4. The vector 1:3
  5. The element 2.
02:00

References

  • Train diagrams from Advanced R by Hadley Wickham.