是否存在多值的 purrr::pluck 函数?

19

看起来这是一个基础问题,也许我只是错过了一些显而易见的东西...但是否有任何方法可以使用purrrpluck子列表呢? 更具体地说,这是一个初始列表:

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

我希望返回一个只包含元素ab的新(子)列表。 通常,我会使用“基本”的R子列表:

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

但是这并不能提供像 pluck 那样好的 .default 处理。

我的理解是 pluck '替换' 了[[,但是是否有一个 purrr 的等效函数可以替换 [ 呢?


2
我认为在purrr中没有直接替代[的函数存在。我猜一个解决方法是使用map(set_names(c("a", "b", "z")), partial(pluck, l), .default = "Not found!"),但这不是很简洁! - Mikko Marttila
4个回答

9

与jzadra的帖子类似,您也可以这样做:

l %>% keep(names(.) %in% c("a","b"))

这是一个很好的解决方案,但是请注意,当使用本地管道运算符“|>”时,它目前无法工作(难过)。 - Jessica Burnett

7

以下是我的看法。虽然与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

2
我认为purrr :: keep()可以满足您的需求。 l %>% keep(names(.) == "a" | names(.) == "b")

1
或者 keep(names(.) %in% c("a", "b")) - Phil

2

很明显需要“多值pluck”。这实际上是扩展“pluck”的灵活性,以从列表的同一层次中检索多个值,正如 github问题中所述。对于上面的示例,您可以尝试使用以下方法:

> purrr::map(purrr::set_names(c("a", "b")), 
          ~purrr::pluck(l, .x, .default = NA_character_))
#> $a
#> [1] "foo"
#> 
#> $b
#> [1] "bar"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接