我想一次将多个函数传递给一个purrr :: map调用,其中函数需要一些参数。作为伪代码:
funs <- c(median, mean)
mtcars %>%
purrr::map(funs, na.rm = TRUE)
此代码不运行,但旨在显示我要查找的内容:将多个函数传递给map
以及一些参数。
我查看了compose
,但该功能有所不同。
答案 0 :(得分:13)
您希望使用map()将多个函数应用于数据框,但(显然)没有map()变体可以完成此操作,只有部分函数。对于多功能部分,我们有invoke_map(),对于数据帧上的多参数部分,我们有pmap()。
invoke_map()
允许一次使用多个功能。例如,如果我们想为均匀和正态分布生成5个随机变量,则代码为:
func <- list(runif, rnorm)
invoke_map(func, n = 5)
pmap()
就像map一样,但它允许将多个参数传递给单个函数。例如,如果我们想要从均值为0且sd = 1的正态分布生成10个随机变量,而且还要从正态分布生成100个随机变量,其中均值= 100且sd = 20,则代码如下所示:
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
中存储的这些函数由pmap()
一次一个地应用于mtcars
中的每一列。
注意:要使解决方案真正有意义,请记住invoke_map()和pmap()的参数。
有关invoke_map()和pmap()工作原理的详细信息。
答案 1 :(得分:11)
invoke()
及其地图变体已经淘汰,而支持rlang::exec()
。从文档中:
这些函数已退出使用exec()。他们不再 正在积极开发中,但我们会将其保留在软件包中 无限期地。
invoke()被淘汰,转而使用更简单的exec()函数 从rlang重新导出。 exec()评估从其构建的函数调用 输入并支持整洁的点
invoke_map()无需替换就可以退出,因为它更多 比使用map(),map2()的相应代码更难理解 和exec()
所以现在等效的方法是:
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
答案 2 :(得分:2)
这是我的宝贝解决方案(取决于您“一次”的意思):
mtcars %>%
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))