Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does a multi-value purrr::pluck exist?

Tags:

r

purrr

tidyverse

Seems like a basic question and perhaps I'm just missing something obvious ... but is there any way to pluck a sublist (with purrr)? More specifically, here's an initial list:

l <- list(a = "foo", b = "bar", c = "baz")

And I want to return a new (sub-)list with only elements a and b. Normally, I'd just do 'base' R sub-listing:

l[c("a", "b")]

But this doesn't provide the nice .default handling of pluck. My understanding is that pluck 'replaces' [[, but is there a purrr equivalent for replacing [?

like image 320
mmuurr Avatar asked Oct 27 '17 21:10

mmuurr


4 Answers

Similar to jzadra's post, you could also do:

l %>% keep(names(.) %in% c("a","b"))
like image 167
Arjun Baghela Avatar answered Nov 13 '22 22:11

Arjun Baghela


Here's my take on it. Not based on purrr thus slightly off topic, but compatible with the tidyverse's general interface principle of playing nicely with pipes.

pluck_multiple <- function(x, ...) {
  `[`(x, ...)
}

x <- list(a = 1, b = 2, c = list(x = TRUE, y = FALSE))

pluck_multiple(x, c("a", "b"))
#> $a
#> [1] 1
#> 
#> $b
#> [1] 2
pluck_multiple(x, 2:3)
#> $b
#> [1] 2
#> 
#> $c
#> $c$x
#> [1] TRUE
#> 
#> $c$y
#> [1] FALSE
like image 25
Rappster Avatar answered Nov 14 '22 00:11

Rappster


There's clearly a need for "muti-value pluck". It really comes down to extending flexibility of "pluck" to retrieving multiple values from the same level of list, as described in this github issue. For the example above, you can probably get away with:

> purrr::map(purrr::set_names(c("a", "b")), 
          ~purrr::pluck(l, .x, .default = NA_character_))
#> $a
#> [1] "foo"
#> 
#> $b
#> [1] "bar"
like image 2
dmi3kno Avatar answered Nov 14 '22 00:11

dmi3kno


I think that purrr::keep() does what you want.

l %>% keep(names(.) == "a" | names(.) == "b")

like image 1
jzadra Avatar answered Nov 14 '22 00:11

jzadra