将dplyr和lazyeval与';一起使用'; 简化编辑:

将dplyr和lazyeval与';一起使用'; 简化编辑:,r,R,归结起来就是: df = data.frame(a = 1:10) #example function that takes optional arguments mymean <- function(x, w = 1, s = 0) { s + mean(w * x) } summarize_(df, m = "mean(a)") #> m #> 1 5.5 summarize_(df, m = "mymean(a)")

归结起来就是:

df = data.frame(a = 1:10)

#example function that takes optional arguments
mymean <- function(x, w = 1, s = 0) { s + mean(w * x) }

summarize_(df, m = "mean(a)")
#>     m
#> 1 5.5

summarize_(df, m = "mymean(a)")
#> Error: could not find function "mymean"
工作函数允许我调用:

my_summary(df, a)
#> 5.5

my_summary(df, a, w=5, s=2)
#> 29.5

这个非常粗糙、可怕的函数起到了作用,但是如果
mymean
包含许多可选参数呢

mymean 15.5
我的总结(df,“a”,s=5)
#>m
#> 1 10.5
我的总结(df,“a”,w=2)
#>m
#> 1 11
我的总结(df,“a”,w=2,s=5)
#>m
#> 1 16

由于问题是将
..
传递给函数,一种解决方案是通过
call
do.call
构造调用(是,两者都有):

库(dplyr)
df=数据帧(a=1:10)
mymean=函数(x,w=1,s=0)
s+平均值(w*x)
my_summary=函数(df,x,…){
x=as.name(替换为(x))
mycall=do.call(call,c('mymean',引号(x),list(…))
总结(df,,
m=lazyeval::interp(~平均值(x),x=x),
w=lazyeval::lazy(mycall,environment())
}
我的总结(df,a)
#>m w
#> 1 5.5 5.5
我的总结(df,a,w=5,s=2)
#>m w
#> 1 5.5 29.5

顺便说一句,上面的方法也修复了传递列名的问题-我无法让代码正常工作,我认为这样做是行不通的。

为什么不能只做
摘要(df,m=mymean(a))
?为什么要将函数指定为字符串?这几乎肯定不是必需的,也不是一个好主意。@KonradRudolph,我正在尝试替换“…”中的变量。另一个选项是将其作为
~mymean(a,…)
传递,但是
..
没有正确解释。如果我可以将其作为字符串传递,我可以显式地在
summary\uCall
之前构建字符串,然后将扩展后的
作为字符串的一部分传递。@potterzot看不到我的答案。不需要字符串,但它确实有点复杂。
call
do.call
是我需要进一步研究的内容。。。谢谢你的伟大解决方案!老实说,我自己并不完全清楚为什么这里需要
do.call
。我最初的想法是你需要它,但现在我想起来了,
call('mymean',quote(x),…)
也应该可以用。但事实并非如此。显然,我的第一直觉是正确的。我在这方面花了更多的时间,并得出了以下结论,这似乎与您代码的输出相匹配。我想你可能会感兴趣:
my_summary(df, a)
#> 5.5

my_summary(df, a, w=5, s=2)
#> 29.5