17.5 The list object
Lists and loops go hand in hand. The more you program with R, the more you’ll find yourself using loops.
Let’s say you are conducting a loop where the outcome of each index is a vector. However, the length of each vector could change - one might have a length of 1 and one might have a length of 100. How can you store each of these results in one object? Unfortunately, a vector, matrix or dataframe might not be appropriate because their size is fixed. The solution to this problem is to use a list()
. A list is a special object in R that can store virtually anything. You can have a list that contains several vectors, matrices, or dataframes of any size. If you want to get really Inception-y, you can even make lists of lists (of lists of lists….).
To create a list in R, use the list()
function. Let’s create a list that contains 3 vectors where each vector is a random sample from a normal distribution. We’ll have the first element have 10 samples, the second will have 5, and the third will have 15.
# Create a list with vectors of different lengths
number.list <- list(
"a" = rnorm(n = 10),
"b" = rnorm(n = 5),
"c" = rnorm(n = 15))
number.list
## $a
## [1] -1.24 0.17 -1.19 -0.58 -1.23 0.92 1.62 -2.02 -0.25 0.92
##
## $b
## [1] -1.627 -1.103 -0.524 0.072 -2.351
##
## $c
## [1] -0.6539 0.4062 -0.6126 -0.3552 -1.0043 -0.4276 -2.3236 -0.6905 -0.4258 -1.0483 0.7000 0.7408 -0.0878 0.6970 -0.0016
To index an element in a list, use double brackets [[]] or $ if the list has names. For example, to get the first element of a list named number.list
, we’d use number.ls[[1]]
:
# Give me the first element in number.list
number.list[[1]]
## [1] -1.24 0.17 -1.19 -0.58 -1.23 0.92 1.62 -2.02 -0.25 0.92
Ok, now let’s use the list object within a loop. We’ll create a loop that generates 5 different samples from a Normal distribution with mean 0 and standard deviation 1 and saves the results in a list called samples.ls
. The first element will have 1 sample, the second element will have 2 samples, etc.
First, we need to set up an empty list container object. To do this, use the vector
function:
Now, let’s run the loop. For each run of the loop, we’ll generate i
random samples and assign them to the ith element in samples.ls
Let’s look at the result:
samples.ls
## [[1]]
## [1] 0.062
##
## [[2]]
## [1] 0.96 2.06
##
## [[3]]
## [1] 0.490 0.946 -0.023
##
## [[4]]
## [1] 1.45 0.28 0.67 -0.97
##
## [[5]]
## [1] 0.614 -0.098 0.778 -0.209 0.288
Looks like it worked. The first element has one sample, the second element has two samples and so on (you might get different specific values than I did because the samples were drawn randomly!).