我有一个data.table,其因子列为空级别。我需要得到行计数和其他变量的总和,所有变量都按多个因素分组,包括空级别的变量。 我的问题类似于one,但在这里我需要考虑多个因素。
例如,让data.table为:
library('data.table')
dtr <- data.table(v1=sample(1:15),
v2=factor(sample(letters[1:3], 15, replace = TRUE),levels=letters[1:5]),
v3=sample(c("yes", "no"), 15, replace = TRUE))
我想做以下事情:
dtr[,list(freq=.N,mm=sum(v1,na.rm=T)),by=list(v2,v3)]
#Output is:
v2 v3 freq mm
1: b yes 4 22
2: b no 1 13
3: c no 3 10
4: a no 4 49
5: c yes 1 10
6: a yes 2 16
我希望输出包括v2的空级别(“d”和“e”),就像在table(dtr$v2,dtr$v3)
中一样,所以最终输出看起来像(顺序无关紧要):
v2 v3 freq mm
1: b yes 4 22
2: b no 1 13
3: c no 3 10
4: a no 4 49
5: c yes 1 10
6: a yes 2 16
7: d yes 0 0
8: d no 0 0
9: e yes 0 0
10: e no 0 0
我尝试使用链接中使用的方法,但是当使用多个列时,我不确定如何使用联合J()函数。
这适用于仅用1列灌浆:
setkey(dtr,v2)
dtr[J(levels(v2)),list(freq=.N,mm=sum(v1,na.rm=T))]
但是,dtr[J(levels(v2),v3),list(freq=.N,mm=sum(v1,na.rm=T))]
不包含所有组合
答案 0 :(得分:13)
library(data.table)
set.seed(42)
dtr <- data.table(v1=sample(1:15),
v2=factor(sample(letters[1:3], 15, replace = TRUE),levels=letters[1:5]),
v3=sample(c("yes", "no"), 15, replace = TRUE))
res <- dtr[,list(freq=.N,mm=sum(v1,na.rm=T)),by=list(v2,v3)]
您可以使用CJ
(交叉加入)。在聚合之后执行此操作可以避免为大表设置密钥,并且应该更快。
setkeyv(res,c("v2","v3"))
res[CJ(levels(dtr[,v2]),unique(dtr[,v3])),]
# v2 v3 freq mm
# 1: a no 1 9
# 2: a yes 2 11
# 3: b no 2 11
# 4: b yes 3 23
# 5: c no 4 40
# 6: c yes 3 26
# 7: d no NA NA
# 8: d yes NA NA
# 9: e no NA NA
# 10: e yes NA NA
答案 1 :(得分:1)
table()
还将捕获为零的频率值。要获得“ mm”列,您可以进行基本连接。例如,
library(data.table)
set.seed(42)
dtr <- data.table(v1=sample(1:15),
v2=factor(sample(letters[1:3], 15, replace = TRUE),levels=letters[1:5]),
v3=sample(c("yes", "no"), 15, replace = TRUE))
res <- as.data.table(dtr[,table(v2,v3)])
setnames(res,'N','freq')
setkey(res,v2,v3)
setkey(dtr,v2,v3)
res <- dtr[,.(mm=sum(v1,na.rm=TRUE)),by=c('v2','v3')][res]
我不确定table()
如何通过交叉联接进行基准测试。