【问题标题】:Unexpected .GRP sequence in data.tabledata.table 中的意外 .GRP 序列
【发布时间】:2016-10-27 19:54:39
【问题描述】:

给定一个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 似乎是按照基础数据中出现的顺序(如by= 顺序)而不是排序顺序(如在keyby=)。

我正计划使用.GRP 作为一些额外标签的索引,但我需要做一些类似的事情:

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

得到我想要的。

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

(第 1.9.6 节)

【问题讨论】:

  • 你的 toAgeGroups 函数被 base 函数 cut 包含,不是吗?

标签: r data.table


【解决方案1】:

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 中所述:

[keybyby 相同,但在结果的by 列上运行了额外的setkey()

因此,在data.table 的新版本中,您必须将代码修复为:

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

【讨论】:

  • @MattDowle 我想这意味着应该修改文档?
  • Ping @Arun 也是如此。
猜你喜欢
  • 2021-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-20
  • 1970-01-01
  • 2020-12-14
  • 2021-12-11
  • 1970-01-01
相关资源
最近更新 更多