将函数列表应用于值列表

Bro*_*ieG 26 r apply

在参考这个问题时,我试图找出将函数列表应用于值列表的最简单方法.基本上是嵌套的lapply.例如,这里我们应用sdmean内置数据集trees:

funs <- list(sd=sd, mean=mean)
sapply(funs, function(x) sapply(trees, x))
Run Code Online (Sandbox Code Playgroud)

要得到:

              sd     mean
Girth   3.138139 13.24839
Height  6.371813 76.00000
Volume 16.437846 30.17097
Run Code Online (Sandbox Code Playgroud)

但我希望避免内心,function并有类似的东西:

sapply(funs, sapply, X=trees)
Run Code Online (Sandbox Code Playgroud)

哪个不起作用,因为X匹配第一个sapply而不是第二个.我们可以这样做functional::Curry:

sapply(funs, Curry(sapply, X=trees))
Run Code Online (Sandbox Code Playgroud)

但是我希望也许有一种聪明的方法可以通过我缺少的位置和名称匹配来做到这一点.

Jul*_*rre 26

由于mapply使用省略号...传递向量(原子或列表)而不是命名参数(X),因为如果使用mapply而不是sapply,则sapply, lapply, etc ...不需要命名参数X = trees:

funs <- list(sd = sd, mean = mean)

x <- sapply(funs, function(x) sapply(trees, x))

y <- sapply(funs, mapply, trees)

> y
              sd     mean
Girth   3.138139 13.24839
Height  6.371813 76.00000
Volume 16.437846 30.17097
> identical(x, y)
[1] TRUE
Run Code Online (Sandbox Code Playgroud)

你差一点就能得到你想要的东西!:)

请注意,我使用了一个列表,funs因为我无法创建函数的数据帧,我收到了一个错误.

> R.version.string
[1] "R version 3.1.3 (2015-03-09)"
Run Code Online (Sandbox Code Playgroud)

  • 非常聪明,将来肯定会使用它; 我认为关键特征是`mapply`碰巧接受函数参数作为第一个参数,所以这一切都有效. (3认同)

MrF*_*ick 14

你基本上需要某种匿名函数,因为没有其他方法可以将命名参数区分为两个不同的sapply调用.您已经显示了一个显式的匿名函数和Curry方法.你也可以用magrittr

 library(magrittr)
 sapply(funs, . %>%  sapply(trees, .))
 # or .. funs %>% sapply(. %>%  sapply(trees, .))
Run Code Online (Sandbox Code Playgroud)

但重点是你需要一些东西去做分裂."问题"是sapply分派到lapply这是一个内部功能是似乎决心将变化值作为函数调用的开始.你需要一些东西来重新排序参数,并且由于相同的参数名称集合,如果没有辅助函数来处理消歧,就不可能将它分开.

mapply函数允许您将列表传递给"MoreArgs",这允许一种方法来绕过命名参数冲突.这是为了在您应该向量化的项目和已修复的项目之间进行拆分.这样你就可以做到

mapply(sapply, funs, MoreArgs=list(X=trees))
#               sd     mean
# Girth   3.138139 13.24839
# Height  6.371813 76.00000
# Volume 16.437846 30.17097
Run Code Online (Sandbox Code Playgroud)


Ren*_*rop 5

使用的另一种方法purrr是:

require(purrr)

funs <- list(sd=sd, mean=mean)
trees %>% map_df(~invoke_map(funs, ,.), .id="id")
Run Code Online (Sandbox Code Playgroud)

重要提示:请注意invoke_map按位置匹配的空第二个参数.见?purrr::invoke_map例子.

这给你:

Source: local data frame [3 x 3]

      id        sd     mean
   <chr>     <dbl>    <dbl>
1  Girth  3.138139 13.24839
2 Height  6.371813 76.00000
3 Volume 16.437846 30.17097
Run Code Online (Sandbox Code Playgroud)

此方法不是rownames,而是为您提供id包含原始列的列.