给出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)
答案 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
重新对答案进行排序:
[
by
是setkey()
的s],但在结果的by
列上额外data.table
次运行。
因此,对于pop[(order(age), .(age_segment_id = .GRP, pop_count=.N),
keyby=.(age_segment = toAgeGroups(age))]
的全新版本,您必须将代码修改为:
{{1}}