17

我有一个 data.table,其中包含空级别的因子列。我需要获取其他变量的行数和总和,所有变量都按多个因素分组,包括具有空级别的因素。我的问题与此类似,但在这里我需要考虑多个因素

例如,让 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”),如 in 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))]不包括所有组合

4

2 回答 2

18
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(交叉连接)。在聚合之后执行此操作可以避免为大表设置键,并且应该更快。

setkey(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
于 2013-09-18T08:16:08.777 回答
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()使用交叉连接进行基准测试。

于 2018-09-25T02:53:38.293 回答