List in R
What is a list in R? A list in R programming language is an ordered collection of any R objects. Thus, although the elements of vectors, matrix and arrays must be of the same type, in the case of the R list the elements can be of different type. Therefore, you can mix several data types with this structure.
Create a list in R
If you don’t know how to create a list in R, you just need to use the list
function as follows, specifying the objects you want to join inside your list.
x <- c(45, 12, 56, 14, 16)
y <- c("Car", "Bike")
z <- matrix(1:12, ncol = 4)
# Creating a list
my_list <- list(x, y, z)
my_list
[[1]]
[1] 45 12 56 14 16
[[2]]
[1] "Car" "Bike"
[[3]]
[, 1] [, 2] [, 3] [, 4]
[1, ] 1 4 7 10
[2, ] 2 5 8 11
[3, ] 3 6 9 12
Naming lists in R
As other R data structures, you can name your list element objects in order to identify or having an easier access to the elements. The following block of code shows how to create a named list in R.
named_list <- list(A = x, B = y, C = z)
named_list
$`A`
[1] 45 12 56 14
$B
[1] "Car" "Bike"
$C
[, 1] [, 2] [, 3] [, 4]
[1, ] 1 4 7 10
[2, ] 2 5 8 11
[3, ] 3 6 9 12
Extract elements from list in R
Now, we are going to index the list elements in order to access the data we want. For that purpose, you can extract the list elements with single or double brackets.
# First element of the list
my_list[1]
# First element of the list, simplifying the output
my_list[[1]]
# First element of the first element of the list
my_list[[1]][1]
unlist(my_list[1])[1]
# First column of the third element
my_list[[3]][, 1]
# Second element of the first column
# of the third element of the list
my_list[[3]][, 1][2]
my_list[[3]][2, 1] # Equivalent
However, in case you have named your list elements you can use the previous way to get values, specify the names of the elements of the list you want to access inside brackets, or use the $
operator as in the following examples:
# First element of the list
named_list["A"]
# First element of the list (simplified)
named_list[["A"]]
# First element of the list (simplified)
named_list$A
# First element of the first element
named_list$A[1]
unlist(named_list[1])[1]
# First column of the third element
named_list$C[, 1]
named_list$`C`[, 1] # Equivalent
# Second element of the first column
# of the third element of the list
named_list$C[, 1][2]
named_list$C[2, 1] # Equivalent
If you use double square brackets instead of single square brackets for subsetting a list, the output class will be simplified as much as possible.
Length of a list in R
The length of a list is the number of R objects inside the list. With this in mind, you can obtain the number of list elements with the length
function. However, if you want to know the length of any object inside the list, first you will need to extract the corresponding element.
# Number of elements of the list
length(my_list) # 3
# Number of elements of the first object
length(my_list[[1]]) # 5
Create empty list in R
Sometimes you need to fill a list inside a for loop. For that purpose, it is interesting to create an empty list in R. Although you can create an empty list with the list
function, if you want a prespecified length you need to use the vector
function and specify the final length in the length
argument to create a list of length n.
# Empty list
empty_list <- list()
# Creating an empty list with 3 elements
empty_list <- vector("list", length = 3)
So if you want to fill this list within a for loop, you could do as follows:
for (j in 1:3) {
empty_list[[j]] <- c(1, 2, 3 * j)
}
[[1]]
[1] 1 2 3
[[2]]
[1] 1 2 6
[[3]]
[1] 1 2 9
Append to list in R
If you need to add an element to a list, you can specify the object you want to add at the next index of the length of the list. If the list length is 3, you can add the new object to the fourth slot.
my_list[[4]] <- data.frame(X = c(8, 5, 3), Y = c(7, 9, 1))
# Equivalent, general case
my_list[[length(my_list) + 1]] <- data.frame(X = c(8, 5, 3), Y = c(7, 9, 1))
Now, print your new list and you will have the following output:
[[1]]
[1] 45 12 56 14
[[2]]
[1] "Car" "Bike"
[[3]]
[, 1] [, 2] [, 3] [, 4]
[1, ] 1 4 7 10
[2, ] 2 5 8 11
[3, ] 3 6 9 12
[[4]]
X Y
1 8 7
2 5 9
3 3 1
Remove element from list in R
In order to delete some elements from a list you can set the index of the element of the list you want to remove as NULL
, or indicate inside brackets the index with the -
operator. If you want to remove several elements at once, combine them with the c
function.
my_list[[2]] <- NULL
my_list[-2] # Equivalent
# Removing the element 1 and 2 of the list at once
my_list[-c(1, 2)]
Creating a list of lists
You can also nest lists in R. This means that in all or some elements of your root list you will have a list. That list can also store other lists or other types of objects. You can achieve this with the list
function, adding new lists as list elements. In this example we are going to add our two previously created lists inside a new list.
list_of_lists <- list(my_list, named_list)
list_of_lists
Printing the nested list will result into the following:
[[1]]
[[1]][[1]]
[1] 45 12 56 14 16
[[1]][[2]]
[1] "Car" "Bike"
[[1]][[3]]
[, 1] [, 2] [, 3] [, 4]
[1, ] 1 4 7 10
[2, ] 2 5 8 11
[3, ] 3 6 9 12
[[2]]
[[2]]$`A`
[1] 45 12 56 14 16
[[2]]$B
[1] "Car" "Bike"
[[2]]$C
[, 1] [, 2] [, 3] [, 4]
[1, ] 1 4 7 10
[2, ] 2 5 8 11
[3, ] 3 6 9 12
Accessing list of list elements
Accessing elements of lists inside lists is similar to access the elements to one list. In fact, if you access one list and store it inside an object, the process is the same as presented in the single-list element extraction section. If not, you will have to know and follow the level of hierarchy of the list. You have some examples in the following code block:
# Accessing the first list
list_of_lists[[1]]
# Accessing the second list
list_of_lists[[2]]
# First object of the second list
list_of_lists[[2]][[1]] # 45 12 56 14 16
# Third element of the first object
# of the second list
list_of_lists[[2]][[1]][3] # 56
list_of_lists[[2]]$A[3] # Equivalent
# You can store the lists on objects
# and access the elements of that list
# like in one of the previous sections
list_1 <- list_of_lists[[1]]
# This is the first object
# of the first list
list_1[[1]]
Combine lists in R
Two or more R lists can be joined together. For that purpose, you can use the append
, the c
or the do.call
functions. When combining the lists this way, the second list elements will be appended at the end of the first list.
# Original data
my_list <- list(x, y, z)
named_list <- list(A = x, B = y, C = z)
# Concatenate lists
append(my_list, named_list)
c(my_list, named_list) # Equivalent
do.call(c, list(my_list, named_list)) # Equivalent
[[1]]
[1] 45 12 56 14 16
[[2]]
[1] "Car" "Bike"
[[3]]
[, 1] [, 2] [, 3] [, 4]
[1, ] 1 4 7 10
[2, ] 2 5 8 11
[3, ] 3 6 9 12
$A
[1] 45 12 56 14 16
$B
[1] "Car" "Bike"
$C
[, 1] [, 2] [, 3] [, 4]
[1, ] 1 4 7 10
[2, ] 2 5 8 11
[3, ] 3 6 9 12
Merge list with same names
When you have two or more lists with the same element names, you can merge the list elements withing a list of the same length as the previous ones, where the elements with the same name will be concatenated. First, we are going to copy our named list in other variable:
# Copy of the list with names
named_list_2 <- named_list
Now, you can use the Map
or the mapply
functions with those lists the following way.
Map(c, named_list, named_list_2)
mapply(c, named_list, named_list_2, SIMPLIFY = FALSE) # Equivalent
You can see the output of the list with concatenated elements:
$`A`
[1] 45 12 56 14 16 45 12 56 14 16
$B
[1] "Car" "Bike" "Car" "Bike"
$C
[1] 1 2 3 4 5 6 7 8 9 10 11 12 1 2 3 4 5 6 7 8 9 10 11 12
Note that the element C is no longer a matrix.
Compare two lists in R
You can compare two lists in different ways. This include obtaining the common elements, the different elements or comparing the equal ones. Before each explanation we are going to copy our first list and change its first element.
my_list_2 <- my_list
my_list_2[[1]] <- c(4, 1, 9)
Common elements in two R lists
First, if you want to obtain the same elements in two lists you can use the intersect
function, that will return a list with the common elements of the lists.
# Return the elements in common of two lists
intersect(my_list, my_list_2)
[[1]]
[1] "Car" "Bike"
[[2]]
[, 1] [, 2] [, 3] [, 4]
[1, ] 1 4 7 10
[2, ] 2 5 8 11
[3, ] 3 6 9 12
Different elements in two R lists
Second, with the setdiff
function you will obtain the different items between your lists. Note that the order you pass the lists is important.
# What is in my_list that is not in my_list_2?
setdiff(my_list, my_list_2) # 45 12 56 14 16
# What is in my_list_2 that is not in my_list?
setdiff(my_list_2, my_list) # 4 1 9
Compare equal elements in two R lists
Third, you can also compare the equal items of two lists with %in%
operator or with the compare.list
function of the useful
library. The result will be a logical vector.
my_list %in% my_list_2 # FALSE TRUE TRUE
library(useful)
compare.list(my_list, my_list_2) # Equivalent
List to vector
Sometimes you need to convert your list to other object types. The most common conversion is converting a list to vector. For that purpose, you can use the unlist
function.
# First element of the list to vector
unlist(my_list[[1]], use.names = FALSE)
45 12 56 14 16
If you prefer to convert the full list to vector, set the use.names
to FALSE
.
# Full list to vector
unlist(my_list, use.names = FALSE)
"45" "12" "56" "14" "16" "Car" "Bike" "1" "2" "3"
"4" "5" "6" "7" "8" "9" "10" "11" "12"
Note that in this case all the elements are now a characters.
In addition, the purrr
library have some functions similar to the unlist
function but in this case you can specify the output class. In this example we are converting our new list to double and then to character.
my_list_3 <- list(c(1, 4), 2, 3)
library(purrr)
flatten_dbl(my_list_3) # 1 4 2 3
flatten_chr(my_list_3) # "1.000000" "4.000000" "2.000000" "3.000000"
List to dataframe
Suppose you have a list containing data of some variables. In that case, you may want to convert your list to a data frame. In order to achieve it, you can use the unlist
, matrix
and data.frame
functions or the do.call
function as follows.
my_list_4 <- list(c(1, 7, 3), c(9, 8, 1))
data.frame(matrix(unlist(my_list_4), nrow = length(my_list_4), byrow = TRUE))
do.call(rbind.data.frame, my_list_4) # Similar
X1 X2 X3
1 1 7 3
2 9 8 1
If you are working with characters, set stringsAsFactors = FALSE
to avoid character columns converted to factor.