使用 data.table[,,by=...] 时包括所有排列
Posted
技术标签:
【中文标题】使用 data.table[,,by=...] 时包括所有排列【英文标题】:Including all permutations when using data.table[,,by=...] 【发布时间】:2014-01-21 18:00:56 【问题描述】:我有一个大的data.table
,我正在使用,by
将其折叠到月级别。
有 5 个按变量,级别数为:c(4,3,106,3,1380)
。 106 是月份,1380 是地理单位。事实证明有一些 0,因为一些单元格没有值。 by
丢弃这些,但我希望它保留它们。
可重现的例子:
require(data.table)
set.seed(1)
n <- 1000
s <- function(n,l=5) sample(letters[seq(l)],n,replace=TRUE)
dat <- data.table( x=runif(n), g1=s(n), g2=s(n), g3=s(n,25) )
datCollapsed <- dat[ , list(nv=.N), by=list(g1,g2,g3) ]
datCollapsed[ , prod(dim(table(g1,g2,g3))) ] # how many there should be: 5*5*25=625
nrow(datCollapsed) # how many there are
是否有一种有效的方法可以用 0 填充这些缺失值,以便 by var 的所有排列都在生成的折叠 data.table 中?
【问题讨论】:
【参考方案1】:我也会使用交叉连接,但会在对 [.data.table
的原始调用的 i
-slot 中使用它:
keycols <- c("g1", "g2", "g3") ## Grouping columns
setkeyv(dat, keycols) ## Set dat's key
ii <- do.call(CJ, sapply(dat[, ..keycols], unique)) ## CJ() to form index
datCollapsed <- dat[ii, list(nv=.N)] ## Aggregate
## Check that it worked
nrow(datCollapsed)
# [1] 625
table(datCollapsed$nv)
# 0 1 2 3 4 5 6
# 135 191 162 82 39 13 3
这种方法被称为“by-without-by”,正如?data.table
中所述,它与通过by
参数传递分组指令一样有效和快速:
高级:已知组子集的聚合是 在
i
中传递这些组时特别有效。什么时候i
是data.table
,DT[i,j]
为每一行计算j
的i
。我们将其称为不带by
或按i
分组。 因此,自加入DT[data.table(unique(colA)),j]
是 等同于DT[,j,by=colA]
。
【讨论】:
请注意:有一个FR here,我们计划将by-without-by
移动到by
。也就是说,X[Y]
应该只是加入,如果想要复制旧的行为,那么需要这样做:X[, j, by=Y, mult=, nomatch=]
(或类似的东西)。这是为了保持与by
始终执行by
的工作的一致性,并且不会被i
污染在仅一种情况下执行by
。
谢谢!这很好用。返回一个稍微不同的答案(在忽略它为缺失排列添加的所有 NA 之后),因为任何 keycol
值是 NA
它将包括但 nv
的值将是 NA
。我可以猜到为什么会发生这种情况,但在这种情况下返回警告可能会很好。解决方案只是预先在keycol
vars 中重新编码NA
s。【参考方案2】:
对唯一值进行笛卡尔连接,并使用它连接回您的结果
dat.keys <- dat[,CJ(g1=unique(g1), g2=unique(g2), g3=unique(g3))]
setkey(datCollapsed, g1, g2, g3)
nrow(datCollapsed[dat.keys]) # effectively a left join of datCollapsed onto dat.keys
# [1] 625
请注意,现在缺少的值为 NA,但如果需要,您可以轻松地将其更改为 0。
【讨论】:
以上是关于使用 data.table[,,by=...] 时包括所有排列的主要内容,如果未能解决你的问题,请参考以下文章
R语言data.table导入数据实战:data.table使用by函数进行数据分组(aggregate)并获取分组的第一个数值或者最后一个数值
使用.BY,.GRP或其他方法添加data.table的多列聚合
R语言data.table导入数据实战:data.table设置键值(key)复合键设置删除键设置键值之后的数据连接(join)更加方便设置了键值之后可以使用keyby语法代替by语法