data.table和"必须评估列表"错误

Rya*_*rio 7 r data.table

我想使用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参数的向量.

Mat*_*wle 5

[更新]提问后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,现在可以doublecharacter,虽然):

严格地说,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(...) 中。至少这是作者所建议的。