Reputation: 2134
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)
Upvotes: 2
Views: 1528
Reputation: 18752
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.
Upvotes: 5
Reputation: 887991
Using base R
(R 4.1.0
)
lapply(x, \(y) tail(y, 1)[[1]])
#[[1]]
#[1] "c"
#[[2]]
#[1] "c"
#[[3]]
#[1] "c"
Upvotes: 3
Reputation: 389355
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(.)))
Upvotes: 3
Reputation: 11548
Will this work:
map(x, function(y) y[[length(y)]])
[[1]]
[1] "c"
[[2]]
[1] "c"
[[3]]
[1] "c"
Upvotes: 4