我试图回答这个很好的问题,它涉及创建一个非标准的评估函数以对数据表对象进行分组汇总。Akrun提供了一个很棒的答案,我在此简化如下:
akrun <- function(data, var, group){
var <- substitute(var)
group <- substitute(group)
data[, sum(eval(var)), by = group]
}
library(data.table)
mt = as.data.table(mtcars)
akrun(mt, cyl, mpg)
# group V1
# 1: 6 138.2
# 2: 4 293.3
# 3: 8 211.4
我也在考虑一个答案,几乎是相同的答案,但将substitute
与其余内容内联。我的结果会导致错误:
gregor = function(data, var, group) {
data[, sum(eval(substitute(var))), by = substitute(group)]
}
gregor(mt, mpg, cyl)
# Error in `[.data.table`(data, , sum(eval(substitute(var))), by = substitute(group)) :
# 'by' or 'keyby' must evaluate to vector or list of vectors
# (where 'list' includes data.table and data.frame which are lists, too)
外表看起来,我的函数只是Akrun的简单替换。为什么它不起作用?
请注意,这两种替换都会引起问题,如下所示:
gregor_1 = function(data, var, group) {
var = substitute(var)
data[,sum(eval(var)),
by = substitute(group)]
}
gregor_1(mt, mpg, cyl)
# Same error as above
gregor_2 = function(data, var, group) {
group = substitute(group)
data[,sum(eval(substitute(var))),
by = group]
}
gregor_2(mt, mpg, cyl)
# Error in eval(substitute(var)) : object 'mpg' not found
data.table
调用中,无论你传递给substitute
的变量是什么,它们都保持为符号(例如,如果你将其包装在rleid
或as.integer
中,则警告对像我这样的新手来说更加清晰)。这是正确的吗?因此,在数据表调用内部使用substitute
时,它不会查找函数环境吗?另外,我对所有与 data.table 相关的事情都很陌生,所以如果这已经很明显了,我很抱歉。 - Andrewsubstitute(var, env = parent.frame(environment()))
这样的版本,但没有成功。但这似乎很可能是正确的方向。 - Gregor Thomas