2

I am trying to extract the last element of nested lists. How can I do this with purrr? In the example below the results should be all the elements with the value "c". I have seen this, but I am particularly interested in a solution with purrr.

Many thanks

x <- list(list(1,2,"c"), list(3,"c"), list("c"))
x
#> [[1]]
#> [[1]][[1]]
#> [1] 1
#> 
#> [[1]][[2]]
#> [1] 2
#> 
#> [[1]][[3]]
#> [1] "c"
#> 
#> 
#> [[2]]
#> [[2]][[1]]
#> [1] 3
#> 
#> [[2]][[2]]
#> [1] "c"
#> 
#> 
#> [[3]]
#> [[3]][[1]]
#> [1] "c"

map(x, purrr::pluck, tail)
#> Error in map(x, purrr::pluck, tail): could not find function "map"
map(x, purrr::pluck, length(x))
#> Error in map(x, purrr::pluck, length(x)): could not find function "map"

Created on 2021-05-21 by the reprex package (v2.0.0)

zoowalk
  • 2,018
  • 20
  • 33

4 Answers4

5

Using purrr::pluck simply:

library(purrr)

map(x, ~ pluck(.x, length(.x)))

Or even easier use dplyr::last:

library(purrr)
library(dplyr)

map(x, last)

In just base R, reverse each list element and take the first item:

lapply(x, function(y) rev(y)[[1]])

lapply(x, \(y) rev(y)[[1]]) # R >= 4.1.0

Or

mapply(`[[`, x, sapply(x, length), SIMPLIFY = F)

Which would return a single vector if remove the argument SIMPLIFY = F because the default is TRUE.

This works by iterating through your list x and the output of sapply(x, length) in parallel and applying it to the function `[[` which is an extraction operator.

LMc
  • 12,577
  • 3
  • 31
  • 43
4

Will this work:

map(x, function(y) y[[length(y)]])
[[1]]
[1] "c"

[[2]]
[1] "c"

[[3]]
[1] "c"
Karthik S
  • 11,348
  • 2
  • 11
  • 25
4

Using base R (R 4.1.0)

lapply(x, \(y) tail(y, 1)[[1]])
#[[1]]
#[1] "c"

#[[2]]
#[1] "c"

#[[3]]
#[1] "c"
akrun
  • 874,273
  • 37
  • 540
  • 662
3

You have a nested list inside every list, I am not sure if it is intentional. In the current state, this would work -

library(purrr)

map(x, ~.x %>% unlist(recursive = FALSE) %>% tail(1))

#[[1]]
#[1] "c"

#[[2]]
#[1] "c"

#[[3]]
#[1] "c"

Also with pluck -

map(x, ~.x %>% unlist(recursive = FALSE) %>% pluck(length(.)))
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213