pluck()

  • pluck() will pull a single element from a list

I like the example from the book because the starting object is not particularly easy to work with (as many JSON objects might not be).

my_list <- list(
  list(-1, x = 1, y = c(2), z = "a"),
  list(-2, x = 4, y = c(5, 6), z = "b"),
  list(-3, x = 8, y = c(9, 10, 11))
)
my_list
#> [[1]]
#> [[1]][[1]]
#> [1] -1
#> 
#> [[1]]$x
#> [1] 1
#> 
#> [[1]]$y
#> [1] 2
#> 
#> [[1]]$z
#> [1] "a"
#> 
#> 
#> [[2]]
#> [[2]][[1]]
#> [1] -2
#> 
#> [[2]]$x
#> [1] 4
#> 
#> [[2]]$y
#> [1] 5 6
#> 
#> [[2]]$z
#> [1] "b"
#> 
#> 
#> [[3]]
#> [[3]][[1]]
#> [1] -3
#> 
#> [[3]]$x
#> [1] 8
#> 
#> [[3]]$y
#> [1]  9 10 11

Notice that the “first element” means something different in standard pluck() versus mapped pluck().

pluck(my_list, 1)
#> [[1]]
#> [1] -1
#> 
#> $x
#> [1] 1
#> 
#> $y
#> [1] 2
#> 
#> $z
#> [1] "a"

map(my_list, pluck, 1)
#> [[1]]
#> [1] -1
#> 
#> [[2]]
#> [1] -2
#> 
#> [[3]]
#> [1] -3

map_dbl(my_list, pluck, 1)
#> [1] -1 -2 -3

The map() functions also have shortcuts for extracting elements from vectors (powered by purrr::pluck()). Note that map(my_list, 3) is a shortcut for map(my_list, pluck, 3).

# Select by name
map_dbl(my_list, "x")
#> [1] 1 4 8

# Or by position
map_dbl(my_list, 1)
#> [1] -1 -2 -3

# Or by both
map_dbl(my_list, list("y", 1))
#> [1] 2 5 9

# You'll get an error if you try to retrieve an inside item that doesn't have 
# a consistent format and you want a numeric output
map_dbl(my_list, list("y"))
#> Error in `map_dbl()`:
#> ℹ In index: 2.
#> Caused by error:
#> ! Result must be length 1, not 2.


# You'll get an error if a component doesn't exist:
map_chr(my_list, "z")
#> Error in `map_chr()`:
#> ℹ In index: 3.
#> Caused by error:
#> ! Result must be length 1, not 0.
#> Error: Result 3 must be a single string, not NULL of length 0

# Unless you supply a .default value
map_chr(my_list, "z", .default = NA)
#> [1] "a" "b" NA
#> [1] "a" "b" NA