7

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

4

2 回答 2

6

[更新] 提出问题 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现在可以是doubleand character):

不过,严格来说,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 个帖子,这可能也很有趣。

于 2010-07-27T12:56:25.873 回答
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参数,列名不要使用引号,而是将它们分组到 list(...) 中。至少这是作者所建议的。

于 2010-07-15T04:40:52.637 回答