似乎是一个基本问题,也许我只是错过了一些明显的东西......但是有没有办法
pluck
子列表(带有purrr
)?
更具体地说,这是一个初始列表:
l <- list(a = "foo", b = "bar", c = "baz")
我想返回一个仅包含元素
a
和 b
的新(子)列表。
通常,我只会做“基本”R 子列表:
l[c("a", "b")]
但这并不能提供对
.default
的良好 pluck
处理。
我的理解是 pluck '替换' [[
,但是是否有 purrr
相当于替换 [
?
与jzadra的帖子类似,你也可以这样做:
l %>% keep(names(.) %in% c("a","b"))
这是我的看法。不是基于
purrr
,因此有点偏离主题,但与 tidyverse
与管道完美配合的一般界面原则兼容。
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
我认为
purrr::keep()
可以满足您的需求。
l %>% keep(names(.) == "a" | names(.) == "b")
显然需要“多价值勇气”。它实际上归结为扩展“pluck”的灵活性,以从同一级别的列表中检索多个值,如this github问题中所述。对于上面的例子,你可能可以逃脱:
> purrr::map(purrr::set_names(c("a", "b")),
~purrr::pluck(l, .x, .default = NA_character_))
#> $a
#> [1] "foo"
#>
#> $b
#> [1] "bar"
模仿 Rappster,如果你不介意丑陋,你可以一次性使用提取运算符的函数形式:
> list(a = 1, b = 2, c = list(x = TRUE, y = FALSE)) %>% `[`(c('a', 'b'))
$a
[1] 1
$b
[1] 2
> list(a = 1, b = 2, c = list(x = TRUE, y = FALSE)) %>% `[`(2:3)
$b
[1] 2
$c
$c$x
[1] TRUE
$c$y
[1] FALSE