MakingAndUsingLists
A list is a generic vector for storing objects that could be unrelated or could have different classes.
1 Creating a List
We can create a list by defining what will be in the list within the list function.
x <- list(numbers = 1:3, letters = c("A", "B", "C", "D", "E"))
x
## $numbers
## [1] 1 2 3
##
## $letters
## [1] "A" "B" "C" "D" "E"
We can also add objects to a list by defining those objects and then adding them to a list.
mat = matrix(1:20, nrow= 4, ncol=5)
x$matrix <- mat
x
## $numbers
## [1] 1 2 3
##
## $letters
## [1] "A" "B" "C" "D" "E"
##
## $matrix
## [,1] [,2] [,3] [,4] [,5]
## [1,] 1 5 9 13 17
## [2,] 2 6 10 14 18
## [3,] 3 7 11 15 19
## [4,] 4 8 12 16 20
You can also add and use a function from a list.
x$mean <- mean
x$mean
## function (x, ...)
## UseMethod("mean")
## <bytecode: 0x7ffe848ed588>
## <environment: namespace:base>
x$mean(x$matrix)
## [1] 10.5
Notice that these two commands create very different lists:
m <- list(1:4)
n <- list(1,2,3,4)
The list m contains one numeric vector. The list n contains 4 numeric vectors, each with a length of 1.
m
## [[1]]
## [1] 1 2 3 4
n
## [[1]]
## [1] 1
##
## [[2]]
## [1] 2
##
## [[3]]
## [1] 3
##
## [[4]]
## [1] 4
2 List Slicing
List objects are always numbered and can be referred to that way.
This gives us a copy of the list object “letters” stored in x.
x[2]
## $letters
## [1] "A" "B" "C" "D" "E"
We can also select several objects at the same time.
x[c(1,3)]
## $numbers
## [1] 1 2 3
##
## $matrix
## [,1] [,2] [,3] [,4] [,5]
## [1,] 1 5 9 13 17
## [2,] 2 6 10 14 18
## [3,] 3 7 11 15 19
## [4,] 4 8 12 16 20
The length function gives the length of the top level objects within a list.
length(x)
## [1] 4
3 Member Reference
Entering x[3]
displays the sublist of x, but it doesn’t give us access to the elements within the list object. For example we can’t print out the second column of the matrix like this: x[3][,2]
x[3]
## $matrix
## [,1] [,2] [,3] [,4] [,5]
## [1,] 1 5 9 13 17
## [2,] 2 6 10 14 18
## [3,] 3 7 11 15 19
## [4,] 4 8 12 16 20
#x[3][,2] #This returns an error.
Changing it to x[[3]]
does work. This is because using a single set of brackets, []
produces only the sublist, not the list object itself. The double brackets [[]]
produces the object in the list.
x[[3]]
## [,1] [,2] [,3] [,4] [,5]
## [1,] 1 5 9 13 17
## [2,] 2 6 10 14 18
## [3,] 3 7 11 15 19
## [4,] 4 8 12 16 20
x[[3]][,2]
## [1] 5 6 7 8
You can call list objects a few different ways.
x[["letters"]]
## [1] "A" "B" "C" "D" "E"
x$letters
## [1] "A" "B" "C" "D" "E"
Notice that calling x["letters"]
will display the sublist of x, but it doesn’t give us access to the elements within the list object.
x["letters"]
## $letters
## [1] "A" "B" "C" "D" "E"
x["letters"][[1]][3]
## [1] "C"
And you can call elements within a list object. In this case we’re calling for a column and row from the matrix within the list “x”.
x$matrix[,4]
## [1] 13 14 15 16
x[[3]][4,]
## [1] 4 8 12 16 20
4 Objects in the list are copies of the original object
Significantly the objects in the list are copies of the original object but it is not a slice containing the original object or its copy. In the example below an integer vector is added to the list, then the list object is modified. The modification doesn’t affect the original vector “additionalNumbers”.
additionalNumbers <- c(10:15)
x$additionalNumbers <- additionalNumbers
x$additionalNumbers[3] <- "This is not a number"
This shows the list object is changed.
x$additionalNumbers
## [1] "10" "11" "This is not a number"
## [4] "13" "14" "15"
But the original integer vector is still the same.
additionalNumbers
## [1] 10 11 12 13 14 15
5 Attach()
We can also attach a list to the search path and search for list objects within the list.
From the documentation for attach
:
The database is attached to the R search path. This means that the database is searched by R when evaluating a variable, so objects in the database can be accessed by simply giving their names.
attach(x)
## The following object is masked _by_ .GlobalEnv:
##
## additionalNumbers
## The following objects are masked from package:base:
##
## letters, mean
Notice the warning:
##The following object is masked _by_ .GlobalEnv:
## additionalNumbers
This means that the list object additionalNumbers in x
is masked by the original additionalNumbers
vector that’s still in the Global Environment.
additionalNumbers
## [1] 10 11 12 13 14 15
The second warning says:
The following objects are masked from package:base:
letters, mean
This means that calling both letters
and mean
will return values stored in the x list and not their original commands from the base package.
letters
## [1] "A" "B" "C" "D" "E"
By detaching x
we can get the original object letters
stored in base.
detach(x)
letters
## [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q"
## [18] "r" "s" "t" "u" "v" "w" "x" "y" "z"
6 Adding a new list object to an existing list.
Just create a name by using the $ symbol and assign whatever data you want to that new object.
x$time <- as.Date(c("1jan1960", "2jan1960", "31mar1960", "30jul1960"), "%d%b%Y")
x
## $numbers
## [1] 1 2 3
##
## $letters
## [1] "A" "B" "C" "D" "E"
##
## $matrix
## [,1] [,2] [,3] [,4] [,5]
## [1,] 1 5 9 13 17
## [2,] 2 6 10 14 18
## [3,] 3 7 11 15 19
## [4,] 4 8 12 16 20
##
## $mean
## function (x, ...)
## UseMethod("mean")
## <bytecode: 0x7ffe848ed588>
## <environment: namespace:base>
##
## $additionalNumbers
## [1] "10" "11" "This is not a number"
## [4] "13" "14" "15"
##
## $time
## [1] "1960-01-01" "1960-01-02" "1960-03-31" "1960-07-30"
class(x[[6]])
## [1] "Date"
To add data to a matrix within a list.
x$matrix <- cbind(x$matrix, c(21:24))
x$matrix
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] 1 5 9 13 17 21
## [2,] 2 6 10 14 18 22
## [3,] 3 7 11 15 19 23
## [4,] 4 8 12 16 20 24
Also a data frame is a list of variables with the same number of rows with a class data.frame.