What is a List?
Vectors and matrices are incredibly useful data structure in R, but they have one distinct limitation: they can store only one type of data.
Lists, however, can store multiple types of values at once. A list can contain a numeric matrix, a logical vector, a character string, a factor object and even another list.
Create a List
Creating a list is much like creating a vector; just pass a comma-separated sequence of elements to the list()
function.
# A list of integers
lst <- list(1, 2, 3)
# A list of characters
lst <- list("red", "green", "blue")
# A list of mixed datatypes
lst <- list(1, "abc", 1.23, TRUE)
The best way to understand the contents of a list is to use the structure function str()
. It provides a compact display of the internal structure of a list.
lst <- list(1, "abc", 1.23, TRUE)
str(lst)
List of 4
$ : num 1
$ : chr "abc"
$ : num 1.23
$ : logi TRUE
Nested List
A list can contain sublists, which in turn can contain sublists themselves, and so on. This is known as nested list or recursive vectors.
lst <- list(1, "abc", list("a","b","c"), TRUE)
str(lst)
List of 4
$ : num 1
$ : chr "abc"
$ :List of 3
..$ : chr "a"
..$ : chr "b"
..$ : chr "c"
$ : logi TRUE
Subsetting List by Position
There are two ways to extract elements from a list:
- Using
[[]]
gives you the element itself. - Using
[]
gives you a list with the selected elements.
Using []
You can use []
to extract either a single element or multiple elements from a list. However, the result will always be a list.
lst <- list(1, "abc", 1.23, TRUE, 1:3)
# extract 2nd element
lst[2]
[[1]]
[1] "abc"
# extract 5th element
lst[5]
[[1]]
[1] 1 2 3
# select 1st, 3rd and 5th element
lst[c(1,3,5)]
[[1]]
[1] 1
[[2]]
[1] 1.23
[[3]]
[1] 1 2 3
# exclude 1st, 3rd and 5th element
lst[c(-1,-3,-5)]
[[1]]
[1] "abc"
[[2]]
[1] TRUE
Using [[]]
You can use [[]]
to extract only a single element from a list. Unlike []
, [[]]
gives you the element itself.
lst <- list(1, "abc", 1.23, TRUE, 1:3)
# extract 2nd element
lst[[2]]
[1] "abc"
# extract 5th element
lst[[5]]
[1] 1 2 3
You can’t use logical vectors or negative numbers as indices when using [[]]
Difference Between Single Bracket [] and Double Bracket [[]]
The difference between []
and [[]]
is really important for lists, because [[]]
returns the element itself while []
returns a list with the selected elements.
The difference becomes clear when we inspect the structure of the output – one is a character and the other one is a list.
lst <- list("a","b","c","d","e","f")
class(lst[[1]])
[1] "character"
class(lst[1])
[1] "list"
The difference becomes annoyingly obvious when we cat the value. As you know cat()
can print any value except the structured object.
cat(lst[[1]], "\n")
a
cat(lst[1], "\n")
Error in cat(lst[1], "\n") :
argument 1 (type 'list') cannot be handled by 'cat'
Subsetting List by Names
Each list element can have a name. You can access individual element by specifying its name in double square brackets [[]]
or use $
operator.
months <- list(JAN=1, FEB=2, MAR=3, APR=4)
# extract element by its name
months[["MAR"]]
[1] 3
# same as above but using the $ operator
months$MAR
[1] 3
# extract multiple elements
months[c("JAN","APR")]
$JAN
[1] 1
$APR
[1] 4
$
works similarly to [[]]
except that you don’t need to use quotes.
Subsetting Nested List
You can access individual items in a nested list by using the combination of [[]]
or $
operator and the []
operator.
lst <- list(item1 = 3.14,
item2 = list(item2a = 5:10,
item2b = c("a","b","c")))
# preserve the output as a list
lst[[2]][1]
$item2a
[1] 5 6 7 8 9 10
# same as above but simplify the output
lst[[2]][[1]]
[1] 5 6 7 8 9 10
# same as above with names
lst[["item2"]][["item2a"]]
[1] 5 6 7 8 9 10
# same as above with $ operator
lst$item2$item2a
[1] 5 6 7 8 9 10
# extract individual element
lst[[2]][[2]][3]
[1] "c"
Modify List Elements
Modifying a list element is pretty straightforward. You use either the [[]]
or the $
to access that element, and simply assign a new value.
# Modify 3rd list element
lst <- list("a","b","c","d","e","f")
lst[[3]] <- 1
str(lst)
List of 6
$ : chr "a"
$ : chr "b"
$ : num 1
$ : chr "d"
$ : chr "e"
$ : chr "f"
You can modify components using []
as well, but you have to assign a list of components.
# Modify 3rd list element using []
lst <- list("a","b","c","d","e","f")
lst[3] <- list(1)
str(lst)
List of 6
$ : chr "a"
$ : chr "b"
$ : num 1
$ : chr "d"
$ : chr "e"
$ : chr "f"
Using []
allows you to modify more than one component at once.
# Modify first three list elements
lst <- list("a","b","c","d","e","f")
lst[1:3] <- list(1,2,3)
str(lst)
List of 6
$ : num 1
$ : num 2
$ : num 3
$ : chr "d"
$ : chr "e"
$ : chr "f"
Add Elements to a List
You can use same method for modifying elements and adding new one. If the element is already present in the list, it is updated else, a new element is added to the list.
lst <- list(1, 2, 3)
lst[[4]] <- 4
str(lst)
List of 4
$ : num 1
$ : num 2
$ : num 3
$ : num 4
By using append()
method you can append one or more elements to the list.
lst <- list(1, 2, 3)
lst <- append(lst,c("a","b","c"))
str(lst)
List of 6
$ : num 1
$ : num 2
$ : num 3
$ : chr "a"
$ : chr "b"
$ : chr "c"
Remove an Element from a List
To remove a list element, select it by position or by name, and then assign NULL to it.
lst <- list("a","b","c","d","e")
lst[[3]] <- NULL
str(lst)
List of 4
$ : chr "a"
$ : chr "b"
$ : chr "d"
$ : chr "e"
Using []
, you can delete more than one component at once.
# Remove first four element from a list
lst <- list("a","b","c","d","e")
lst[1:4] <- NULL
str(lst)
List of 1
$ : chr "e"
By using a logical vector, you can remove list elements based on the condition.
# Remove all negative list elements
lst <- list(-4,-3,-2,-1,0,1,2,3,4)
lst[lst <= 0] <- NULL
str(lst)
List of 4
$ : num 1
$ : num 2
$ : num 3
$ : num 4
Combine Lists
The c()
does a lot more than just creating vectors. It can be used to combine lists into a new list as well.
lst1 <- list("a","b","c")
lst2 <- list(1,2,3)
lst <- c(lst1, lst2)
str(lst)
List of 6
$ : chr "a"
$ : chr "b"
$ : chr "c"
$ : num 1
$ : num 2
$ : num 3
Flatten a List into a Vector
Basic statistical functions work on vectors but not on lists.
For example, you cannot directly compute the mean of list of numbers. In that case, you have to flatten the list into a vector using unlist()
first and then compute the mean of the result.
# Flatten the list into a vector and compute mean
lst <- list(5, 10, 15, 20, 25)
mean(unlist(lst))
[1] 15
Find List Length
To find the length of a list, use length()
function.
lst <- list(5, 10, 15, 20)
length(lst)
[1] 4