我想使用R中的data.table包来动态生成聚合,但我遇到了错误.下面,让我们my.dt为类型data.table.
sex <- c("M","F","M","F")
age <- c(19, 23, 26, 21)
dependent.variable <- c(1400, 1500, 1250, 1100)
my.dt <- data.table(sex, age, dependent.variable)
grouping.vars <- c("sex", "age")
for (i in 1:2) {
my.dt[,sum(dependent.variable), by=grouping.vars[i]]
}
Run Code Online (Sandbox Code Playgroud)
如果我运行这个,我会收到错误:
Error in `[.data.table`(my.dt, , sum(dependent.variable), by = grouping.vars[i] :
by must evaluate to list
Run Code Online (Sandbox Code Playgroud)
然而以下工作没有错误:
my.dt[,sum(dependent.variable), by=sex]
Run Code Online (Sandbox Code Playgroud)
我知道错误发生的原因,但我没有看到如何使用带by参数的向量.
[更新]提问后2年......
在运行问题中的代码时,data.table现在更有帮助并返回此(使用1.8.2):
Error in `[.data.table`(my.dt, , sum(dependent.variable), by = grouping.vars[i]) :
'by' appears to evaluate to column names but isn't c() or key(). Use by=list(...)
if you can. Otherwise, by=eval(grouping.vars[i]) should work. This is for efficiency
so data.table can detect which columns are needed.
Run Code Online (Sandbox Code Playgroud)
并遵循错误第二句中的建议:
my.dt[,sum(dependent.variable), by=eval(grouping.vars[i])]
sex V1
1: M 2650
2: F 2600
Run Code Online (Sandbox Code Playgroud)
从2010年(月古答案by,现在可以double和character,虽然):
严格地说,by需要评估一个向量列表,每个向量都有存储模式整数.因此,数字向量age也可以使用强制转换为整数as.integer().这是因为data.table使用基数排序(非常快),但基数算法仅适用于整数(请参阅维基百科的'基数排序'条目).关键列和ad hoc的整数存储by是data.table快速的原因之一.一个因素当然是对唯一字符串的整数查找.
背后的想法by是一个list()表达的是,你是不是仅限于列名.通常直接在列中写出列名的表达式by.一个常见的是按月汇总; 例如 :
DT[,sum(col1), by=list(region,month(datecol))]
Run Code Online (Sandbox Code Playgroud)
或者一个非常快速的按年分组的方法是使用非基于历元的日期,例如yyyymmddL,如包中的一些示例所示,如下所示:
DT[,sum(col1), by=list(region,month=datecol%/%100L)]
Run Code Online (Sandbox Code Playgroud)
请注意如何命名list()中的列.
要定义和重用复杂的分组表达式:
e = quote(list(region,month(datecol)))
DT[,sum(col1),by=eval(e)]
DT[,sum(col2*col3/col4),by=eval(e)]
Run Code Online (Sandbox Code Playgroud)
或者,如果您不想by每次都重新评估表达式,可以将结果保存一次并重复使用结果以提高效率; 如果by表达式本身需要很长时间来计算/分配,或者您需要多次重复使用它:
byval = DT[,list(region,month(datecol))]
DT[,sum(col1),by=byval]
DT[,sum(col2*col3/col4),by=byval]
Run Code Online (Sandbox Code Playgroud)
有关最新信息和状态,请参阅http://datatable.r-forge.r-project.org/.很快就会有一个新的演示文稿,希望很快就能将v1.5发布到CRAN.这包含几个错误修复和NEWS文件中详述的新功能.datatable-help列表每个月有大约30-40个帖子,这些帖子也可能很有意思.
小智 4
我对您的原始代码做了两处更改:
sex <- c("M","F","M","F")
age <- c(19, 23, 26, 21)
age<-as.factor(age)
dependent.variable <- c(1400, 1500, 1250, 1100)
my.dt <- data.table(sex, age, dependent.variable)
for ( a in 1:2){
print(my.dt[,sum(dependent.variable), by=list(sex,age)[a]])
}
Run Code Online (Sandbox Code Playgroud)
数值向量age应该被强制转化为因子。至于by参数,不要对列名使用引号,而是将它们分组到 list(...) 中。至少这是作者所建议的。