A list is an array of objects, which is to say that the elements in a list are themselves objects. Unlike other data storage types we’ve discussed, the objects in a list can belong to different classes. In short, lists are a collection of objects of different types and lengths.
mylist <- list(10, c("abc", "item"), c(1.23, 1.5, 6), c(TRUE, FALSE))
mylist
## [[1]]
## [1] 10
##
## [[2]]
## [1] "abc" "item"
##
## [[3]]
## [1] 1.23 1.50 6.00
##
## [[4]]
## [1] TRUE FALSE
We can examine the contents of a list using str
:
A list can contain all sorts of objects, so why not have a list that contains other lists? These are called nested lists or recursive vectors.
lst2 <- list(1, 3, c("abc", "ABC"), mylist, TRUE)
str(lst2)
## List of 5
## $ : num 1
## $ : num 3
## $ : chr [1:2] "abc" "ABC"
## $ :List of 4
## ..$ : num 10
## ..$ : chr [1:2] "abc" "item"
## ..$ : num [1:3] 1.23 1.5 6
## ..$ : logi [1:2] TRUE FALSE
## $ : logi TRUE
It’s lists all the way down.
Even though lists are a little different from vectors, a lot of the same basic features apply.
This tells us how many objects are in the list, but does not tell us anything about those objects or how many elements might be in each.
We can also use the concatenate function to combine lists, like we used it to combine numbers and strings into vectors.
lst_char <- list("a", "b", "c")
lst_num <- list(100, 99, 0)
lst <- c(lst_num, lst_char)
str(lst)
## List of 6
## $ : num 100
## $ : num 99
## $ : num 0
## $ : chr "a"
## $ : chr "b"
## $ : chr "c"
We can convert vectors and factors to lists using
as.list
.
v1 <- c(5,9,3.6,4.9,pi)
l1 <- as.list(v1)
str(l1)
## List of 5
## $ : num 5
## $ : num 9
## $ : num 3.6
## $ : num 4.9
## $ : num 3.14
How does this conversion take place? What does R do with the vector when turning it into a list?
We can also convert lists to other types using as.*
, but
this will only work if the conversion is sensible.
as.numeric(l1) # works
## [1] 5.000000 9.000000 3.600000 4.900000 3.141593
# The next line doesn't work.
# You will need to comment this out to knit the document.
# as.numeric(lst2)
We can also use unlist
, where R will just guess what
type of vector is most appropriate.
unlist(l1)
## [1] 5.000000 9.000000 3.600000 4.900000 3.141593
unlist(lst2)
## [1] "1" "3" "abc" "ABC" "10" "abc" "item" "1.23" "1.5"
## [10] "6" "TRUE" "FALSE" "TRUE"
How did R deal with the mix of vector types in lst2
?
As with vectors, we can determine if an object is a list using
is.list
or class
.
is.list(l1)
## [1] TRUE
class(l1)
## [1] "list"
Names start to get more important as we move into lists and matrices because it starts to get more difficult to keep track of what everything means. For example, I might want a list with vectors containing first names, last names, and years of birth.
lst3 <- list(first = c("Dwayne","Nicolas"),
second = c("Johnson","Cage"),
birthyear = c(1972,1964))
lst3
## $first
## [1] "Dwayne" "Nicolas"
##
## $second
## [1] "Johnson" "Cage"
##
## $birthyear
## [1] 1972 1964
List output is structured to identify each object in the list using [[]] instead of [].
mylist
## [[1]]
## [1] 10
##
## [[2]]
## [1] "abc" "item"
##
## [[3]]
## [1] 1.23 1.50 6.00
##
## [[4]]
## [1] TRUE FALSE
We can use this to access objects from the list.
mylist[[2]]
## [1] "abc" "item"
This isolates that object, which can then be interacted with as an object of whatever type it is:
class(mylist[[2]])
## [1] "character"
# returns the first item from the second object in the list "mylist"
mylist[[2]][1]
## [1] "abc"
With named lists, we can also access elements using the dollar sign and the desired object’s name:
lst3$second
## [1] "Johnson" "Cage"
Create a list containing a numeric vector named “num1” and a
character vector named “cha1”. Then access the first element in
cha1
from your list.