我想一次将多个需要参数的函数传递给purrr::map调用。伪代码如下:
funs <- c(median, mean)
mtcars %>%
purrr::map(funs, na.rm = TRUE)
这段代码无法运行,但是其目的是展示我所需要的:将多个函数传递给map
并搭配一些参数。
我看过compose
,但那个函数做了不同的事情。
您想使用map()函数对数据框应用多个函数,但是(显然)没有一个能够完全实现这个功能的map()变体,只有部分变体。对于多个函数的部分,我们有invoke_map(),对于在数据框上使用多个参数的部分,我们有pmap()。
invoke_map()
允许一次使用多个函数。例如,如果我们要为均匀分布和正态分布生成5个随机变量,则代码如下:
func <- list(runif, rnorm)
invoke_map(func, n = 5)
pmap()
与 map 类似,但它允许将多个参数传递给单个函数。例如,如果我们要从平均值为 0、标准差为 1 的正态分布中生成 10 个随机变量,以及从平均值为 100、标准差为 20 的正态分布中生成 100 个随机变量,则代码如下:
args <- list(mean = c(0, 100), sd = c(1, 20), n = c(10, 100))
pmap(args, rnorm)
为了解决您的问题,我们必须以以下方式结合这两个函数:
fun <- function(f) pmap(list(x = mtcars, na.rm = TRUE), f)
param <- list(list(mean), list(median))
invoke_map(.f = fun, .x = param)
这个怎么用?
在 invoke_map() 层面,fun
的参数是 param
,它们是我们想要应用于 mtcars
的函数。
接下来,在 fun
层面,这些存储在 param
中的函数会被一个接一个地应用到 mtcars
中的每一列。
注意:要让解决方案真正有意义,请记住 invoke_map() 和 pmap() 接受的参数。
有关invoke_map()和pmap()如何工作的更多信息。
invoke()
及其map变体已被弃用,建议使用rlang::exec()
代替。根据文档:
这些函数已被弃用,建议使用exec()。它们不再处于活跃开发中,但我们将无限期地维护它们。
推荐使用简单的reexported rlang中的exec()函数来代替invoke()函数。exec()函数从输入构建一个函数调用并支持整洁点
因为理解起来比使用map()、map2()和exec()相应代码更复杂,所以invoke_map()已被废止且没有替代品
因此,现在的等效方法是:
library(dplyr)
library(purrr)
funs <- c(mean = mean, median = median)
args <- list(na.rm = TRUE, trim = .1) # trim argument non-matching and ignored for median
mtcars %>%
map_df(~ funs %>%
map(exec, .x, !!!args), .id = "var")
# A tibble: 11 x 3
var mean median
<chr> <dbl> <dbl>
1 mpg 19.7 19.2
2 cyl 6.23 6
3 disp 223. 196.
4 hp 141. 123
5 drat 3.58 3.70
6 wt 3.15 3.32
7 qsec 17.8 17.7
8 vs 0.423 0
9 am 0.385 0
10 gear 3.62 4
11 carb 2.65 2
args <- list(na.rm...)
),所有这些参数都传递给所有的函数吗?换句话说,您的函数调用将如下所示:mean(mpg, na.rm = TRUE, trim = .1)
median(mpg, na.rm = TRUE, trim = .1)
median(cyl, na.rm = TRUE, trim = .1)
...
- settytrim
不是 median()
的参数,但在这种情况下它被忽略了。 - Ritchie Sacramentomap2()
代替map()
,并同时迭代函数列表和参数列表。如果需要帮助,请随时发布新问题。 - Ritchie Sacramentomtcars %>%
map_dbl(~{mean(.x, na.rm = TRUE)}) %>%
enframe() %>%
rename(mean = value) %>%
as_tibble %>%
left_join(mtcars %>%
map_dbl(~{median(.x, na.rm = TRUE)}) %>%
enframe() %>%
as_tibble %>%
rename(median = value))
mtcars %>% purrr::map_dfr(mosaic::favstats)
- Sebastian Sauer