10.3 Lists

In this course, we have stored large amounts of data in two types of objects: vectors and data frames. These have some inherent limitations:

  • A vector can only contain one type of value. This means, for example, that one vector can’t contain both numeric values AND character values.
  • In a data frame, all columns need to be of the same length. In addition, a column can only contain a single type of value.

A list in R, on the other hand, has none of these limitations. It can contain values of multiple types and different lengths. This makes it ideal for storing more complex objects. In fact, much of the complex data you have encountered in these tutorials, like the phylogenetic trees last week, are based on lists.

You can make a list with the list() function:

my_list <- list(names = c("Ask", "Embla"),
                numbers = c(11, 15, 6, 8),
                condition = TRUE)
my_list
#> $names
#> [1] "Ask"   "Embla"
#> 
#> $numbers
#> [1] 11 15  6  8
#> 
#> $condition
#> [1] TRUE

You can access list elements with $, or with double square brackets [[]]:

# access list element 1
my_list$names
#> [1] "Ask"   "Embla"
my_list[[1]]
#> [1] "Ask"   "Embla"

You can access elements within the vector within the list by adding a second set of (single) square brackets.

# access element 1 of the vector in list element 1
my_list[[1]][1]
#> [1] "Ask"

Since a list can contain any type of data (even data frames and other lists), there are times when they are very useful. We won’t go into much more detail about lists here, but it is important that you know that this structure exists and a bit about how to work with them.