data.table中出现意外的.GRP序列

时间:2016-10-27 19:54:40

标签: r data.table

给出data.table,例如:

library(data.table)
n = 5000
set.seed(123)
pop = data.table(id=1:n, age=sample(18:80, n, replace=TRUE))

和将数字向量转换为有序因子的函数,例如:

toAgeGroups <- function(x){
  groups=c('Under 40','40-64','65+')
  grp = findInterval(x, c(40,65)) +1
  factor(groups[grp], levels=groups, ordered=TRUE)
}

在将此函数的输出分组为关键字并使用.GRP建立索引时,我看到了意外的结果。

pop[, .(age_segment_id = .GRP, pop_count=.N), keyby=.(age_segment = toAgeGroups(age))]

返回:

   age_segment age_segment_id pop_count
1:    Under 40              1      1743
2:       40-64              3      2015
3:         65+              2      1242

我原本期望age_segment_id值为c(1,2,3),而不是c(1,3,2),但.GRP似乎按基础数据中的出现顺序设置(如{{1} }}而不是排序顺序(如在by=中)。

我打算使用keyby=作为一些额外标签的索引,但我需要做类似的事情:

.GRP

得到我想要的东西。

这是预期的行为吗?如果是这样,是否有更好的解决方法?

(v.1.9.6)

1 个答案:

答案 0 :(得分:3)

data.table的版本1.9.8 +中不再出现此问题。

library(data.table) #1.9.8+
pop[, .(age_segment_id = .GRP, pop_count=.N),
    keyby=.(age_segment = toAgeGroups(age))]
#    age_segment age_segment_id pop_count
# 1:    Under 40              1      1743
# 2:       40-64              2      2015
# 3:         65+              3      1242

还有更多内容,请参阅讨论here。基本上,by如何在内部工作返回每个组的已排序行,然后将表重新排序回其原始顺序。

如果指定keyby,则更改会认识到不需要重新排序,因此现在您的方法可以按预期工作。

之前(通过1.9.6),keyby只会按照setkey中记录的?data.table运行keyby重新对答案进行排序:

  

[bysetkey()的s],但在结果的by列上额外data.table次运行。

因此,对于pop[(order(age), .(age_segment_id = .GRP, pop_count=.N), keyby=.(age_segment = toAgeGroups(age))] 的全新版本,您必须将代码修改为:

{{1}}