使用do.call和dplyr标准评估版

时间:2015-11-14 22:54:13

标签: r dplyr

如何获得带有变量参数和函数列表的do.call,以便在dplyr中使用summarise_的标准评估版本?

## Some sample data, function, and variables to interpolate
set.seed(0)
dat <- data.frame(a=runif(10), b=runif(10))
fn <- function(x, y) IQR(x / y, na.rm = TRUE)
funs <- list(fn="fn")
targs <- list("a", "b")

这是我正在尝试工作的lazyeval::interp

library(dplyr)
interp(~do.call(fn, xs), .values=list(fn=funs$fn, xs=targs))
# ~do.call("fn", list("a", "b"))

但它不起作用,

dat %>%
  summarise_(out = interp(~do.call(fn, xs), .values=list(fn=funs$fn, xs=targs)))

预期结果

dat %>%
  summarise(out = do.call(fn, list(a, b)))
#        out
# 1 1.084402

如果我添加一些打印语句,我知道问题是“a”和“b”没有被正确解释,但我无法弄清楚如何正确引用它们。

fn <- function(x, y) { print(x); print(y); IQR(x / y, na.rm = TRUE) }
dat %>%
  summarise_(out = interp(~do.call(fn, xs), fn=funs$fn, xs=targs))
# [1] "a"
# [1] "b"
# Error: non-numeric argument to binary operator

1 个答案:

答案 0 :(得分:6)

targs参数必须是call类。 callab)中的变量必须是name类。所有这些都在下面的第二行(和第三行)中完成。 ?call?as.name?is.language可能会使该行更容易理解。

dat <- data.frame(a=runif(10), b=runif(10), grp=rep(1:2, each=5))
targs_quoted = do.call(call, c("list", lapply(targs, as.name)), quote=TRUE)
# In hardcoded form, targs_quoted = quote(list(a, b))
dat %>%
  group_by(grp) %>%
  summarise_(out = interp(~do.call(fn, xs), 
                          .values=list(fn=funs$fn, xs=targs_quoted)))

# Source: local data frame [2 x 2]
#     
#       grp       out
#     (int)     (dbl)
#  1     1  1.0754497
#  2     2  0.9892201

dplyr&#34; nse&#34; (非标准评估)vignette在这里非常有帮助。我发现.总是指整个表,而不是分组表。这就是为什么评论中的一些建议没有工作&#34;如所希望的那样。