9.2 Subsetting and Accessing

You can subset lists in the same way that you subset a vector: simply use the [ sub-setting operator. Let’s pick out the first two elements of lst3:

lst3[1:2]
## $nums
##  [1] 10 11 12 13 14 15 16 17 18 19 20
## 
## $bools
## [1]  TRUE FALSE FALSE

We get a new list consisting of the desired two elements.

Suppose we want to access just one element from lst3: the numbers, for instance. We could try this:

justNumbers <- lst3[1]
justNumbers
## $nums
##  [1] 10 11 12 13 14 15 16 17 18 19 20

Now suppose that we want to access the third number in the nums vector. You might think this would work fine:

justNumbers[3]
## $<NA>
## NULL

Wait a minute! The third number in nums is 12: so why are we getting NA?

Look carefully again at the printout for justNumbers:

justNumbers
## $nums
##  [1] 10 11 12 13 14 15 16 17 18 19 20

The $nums give us the clue: justNumbers is not just the vector nums—in fact it’s not an atomic vector at all. It is a list whose only element is a vector with the name nums. Another way to see this is to check the length of justNumbers:

length(justNumbers)
## [1] 1

The fact is that the sub-setting operator [, applied to lists, always returns a list. If you want access to an individual element of a list, then you need to use the double-bracket [[ operator:

reallyJustNumbers <- lst3[[1]]
reallyJustNumbers
##  [1] 10 11 12 13 14 15 16 17 18 19 20

Of course if an element of a list is named, then you may also access it with the dollar sign:

lst3$nums
##  [1] 10 11 12 13 14 15 16 17 18 19 20

From time to time it’s useful to “flatten out” a list into a vector of values of its elements. This is accomplished by the function unlist() :

unlist(lst1)
##      name       age 
## "Dorothy"      "12"

As the example above shows, you have to exercise caution with unlist(). Since unlist() returns an atomic vector, when it encounters values of different types then it has to coerce them to be of the same type. In the competition between double and character types, character wins, so you end up with a vector of strings.

9.2.1 Practice Exercises

These exercises involve the following list:

grabBag <- list(letters = letters,
                as.character(1:10),
                df = bcscr::fuel)

Observe that the second element of this list was NOT given a name.

  1. Describe in words what grabBag[2:3] is.

  2. Describe in words what grabBag[3] is.

  3. Describe in words what `grabBag[[3]] is.

  4. Find two ways to access the letter "d" in the first element of grabBag.

  5. Find a way to access the last five elements of the second element of grabBag.

  6. Find two ways to access the variable speed in the data frame in grabBag.

9.2.2 Solutions to the Practice Exercises

  1. grabBag[2:3] is a list containing two elements: the vector of whole numbers from 1 to 10 turned into strings, and the data frame fuel from the bcscr package.

  2. grabBag[3] is a list containing just one element: the data frame fuel from the bcscr package.

  3. grabBag[[3]] is the data frame fuel from the bcscr package.

  4. Here are two ways:

    grabBag$letters[4]
    grabBag[[1]][4]
  5. Try this:

    grabBag[[2]][6:10]
  6. Here are two ways:

    grabBag$df$speed
    grabBag[[3]]$speed