我有一个大的data.table
,正在使用,by
折叠到月度水平。
[vars共有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中?
我也想使用交叉联接,但会在对i
的原始调用的[.data.table
插槽中使用它:
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-with-by-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]
相同。
将唯一值进行笛卡尔联接,然后使用该联接来返回结果