将多个函数传递给purrr:map

Seb*_*uer 6 r purrr tidyverse

我想一次将多个函数传递给一个purrr :: map调用,其中函数需要一些参数.作为伪代码:

funs <- c(median, mean)

mtcars %>% 
  purrr::map(funs, na.rm = TRUE) 
Run Code Online (Sandbox Code Playgroud)

此代码并没有跑,而是意在展示我在寻找:多种功能穿越到map了一些争论一起.

我看了一下,compose但那个功能做了不同的事情.

Jos*_*ado 14

您希望使用map()将多个函数应用于数据框,但(显然)没有map()变体可以完成此操作,只有部分函数.对于多功能部分,我们有invoke_map(),对于数据帧上的多参数部分,我们有pmap().

invoke_map()允许一次使用多个功能.例如,如果我们想为统一和正态分布生成5个随机变量,则代码为:

func <- list(runif, rnorm) 
invoke_map(func, n = 5)
Run Code Online (Sandbox Code Playgroud)

pmap()就像map一样,但它允许将多个参数传递给单个函数.例如,如果我们想要从均值为0且sd = 1的正态分布生成10个随机变量,而且还要从均值为100且sd = 20的正态分布生成100个随机变量,则代码如下所示:

args <- list(mean = c(0, 100), sd = c(1, 20), n = c(10, 100))
pmap(args, rnorm)
Run Code Online (Sandbox Code Playgroud)

要解决您的问题,我们必须以下列方式组合这两个函数:

fun <- function(f) pmap(list(x = mtcars, na.rm = TRUE), f)
param <- list(list(mean), list(median))

invoke_map(.f = fun, .x = param)
Run Code Online (Sandbox Code Playgroud)

这是如何运作的?

  1. 在invoke_map()级别,fun接受作为参数param,这是我们想要应用的函数mtcars.

  2. 接着,在fun电平,存储在这些功能param是由施加pmap(),一次一个,在每列中mtcars.

注意:要使解决方案真正有意义,请记住invoke_map()和pmap()采用的参数.

有关invoke_map()pmap()如何工作的更多信息.


H 1*_*H 1 12

invoke()并且它的地图变体已被淘汰,以支持rlang::exec(). 从文档:

这些函数被 exec() 所取代。它们不再处于积极开发状态,但我们将无限期地将它们保留在包中。

invoke() 已退休,取而代之的是从 rlang 重新导出的更简单的 exec() 函数。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  
Run Code Online (Sandbox Code Playgroud)