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

时间:2010-07-15 02:21:41

标签: 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]]
}

如果我运行这个,我会收到错误:

Error in `[.data.table`(my.dt, , sum(dependent.variable), by = grouping.vars[i] :
  by must evaluate to list

然而以下工作没有错误:

my.dt[,sum(dependent.variable), by=sex]

我知道错误发生的原因,但我没有看到如何使用带有by参数的向量。

2 个答案:

答案 0 :(得分: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.

并遵循错误第二句中的建议:

my.dt[,sum(dependent.variable), by=eval(grouping.vars[i])] 
   sex   V1
1:   M 2650
2:   F 2600



2010年7月的旧答案(by现在可以是doublecharacter

严格地说,by需要评估一个向量列表,每个向量都有存储模式整数。因此,使用age也可以将数字向量as.integer()强制转换为整数。这是因为data.table使用基数排序(非常快)但是基数算法专门用于整数(参见维基百科的'基数排序'条目)。关键列和临时by的整数存储是data.table快速的原因之一。一个因素当然是对唯一字符串的整数查找。

by作为list()表达式背后的想法是,您不仅限于列名。通常直接在by中编写列名的表达式。一个常见的是按月汇总;例如:

DT[,sum(col1), by=list(region,month(datecol))]

或者一个非常快速的按年分组的方法是使用非基于纪元的日期,例如yyyymmddL,如包中的一些示例所示,如下所示:

DT[,sum(col1), by=list(region,month=datecol%/%100L)]

请注意如何命名list()中的列。

定义和重用复杂的分组表达式:

e = quote(list(region,month(datecol)))
DT[,sum(col1),by=eval(e)]
DT[,sum(col2*col3/col4),by=eval(e)]

或者如果您不想每次都重新评估by个表达式,您可以保存一次结果并重复使用结果以提高效率;如果by表达式本身需要很长时间来计算/分配,或者您需要多次重复使用它们:

byval = DT[,list(region,month(datecol))]
DT[,sum(col1),by=byval]
DT[,sum(col2*col3/col4),by=byval]

请参阅http://datatable.r-forge.r-project.org/了解最新信息和状态。很快就会有一个新的演示文稿,希望很快就能将v1.5发布到CRAN。这包含几个错误修复和NEWS文件中详述的新功能。数据表帮助列表每个月有大约30-40个帖子,这些帖子也可能很有用。

答案 1 :(得分: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]]) 
}

数字向量age应该被强制为因子。对于by参数,不要对列名使用quote,而是将它们分组到list(...)中。至少这是作者所建议的。