【问题标题】:Empty factors in "by" data.table“by” data.table 中的空因子
【发布时间】:2013-09-18 07:59:27
【问题描述】:

我有一个 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))] 不包括所有组合

【问题讨论】:

  • 我发现如果我更改值的顺序并设置 setkey(dtr,v3,v2)unique(dtr[J(v3,levels(v2)),list(freq=.N,mm=sum(v1,na.rm=T))]) 将起作用,但任何人都可以解释为什么以及它是否适用于大于 2 的大 data.table组?
  • 谢谢@Asayat。我在这里提交了 FR #4914:r-forge.r-project.org/tracker/…
  • R-Forge 的链接已损坏。现在可以在 github github.com/Rdatatable/data.table/issues/562 上找到功能请求。

标签: r data.table


【解决方案1】:
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

【讨论】:

  • 具有 >5*10^6 行和 > 300 个因子水平的 tapply 将永远运行 :)
  • @Arun 从统计的角度来看,像这样处理空因子水平是有意义的。
  • @Asayat 不,Arun 正在讨论改进 data.table 以处理像 tapply 这样的因素。
  • 对不起,@Arun,刚刚明白了 :) 可惜我没有 data.table 包来处理这个问题 :)
【解决方案2】:

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() 如何使用交叉连接进行基准测试。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-14
    • 2015-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-21
    • 1970-01-01
    相关资源
    最近更新 更多