R 如何使用data.table';不同子集上的sj

R 如何使用data.table';不同子集上的sj,r,data.table,subset,R,Data.table,Subset,我想创建多个变量,这些变量聚合数据集的不同子集。例如,假设您拥有以下数据: DT = data.table(Group1 = c(1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4), Group2 = c(1,1,1,2,2,1,1,2,2,2,1,1,1,1,2,1,1,2,2,2), Var1 = c(1,1,0,0,0,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0)) 我想

我想创建多个变量,这些变量聚合数据集的不同子集。例如,假设您拥有以下数据:

DT = data.table(Group1 = c(1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4), 
                Group2 = c(1,1,1,2,2,1,1,2,2,2,1,1,1,1,2,1,1,2,2,2), 
                  Var1 = c(1,1,0,0,0,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0))
我想找到变量
Var1
的几个平均值。我想知道:

  • 平均值(Var1)
    Group1
  • 平均值(Var1)
    仅适用于
    Group2==1的人群,按
    Group1
  • 平均值(Var1)
    仅适用于
    Group2==2
    的人群,按
    Group1
或者,用data.table的说法

DT[, mean(Var1), by=Group1]
DT[Group2==1, mean(Var1), by=Group1]
DT[Group2==2, mean(Var1), by=Group1]
显然,计算其中任何一个都非常简单。但是我找不到一个好方法来计算这三个变量,因为它们在
I
中使用不同的子集。到目前为止,我使用的解决方案是单独生成它们,然后将它们合并到一个统一的表中

DT_all <- DT[, .(avgVar1_all = mean(Var1)), by = Group1]
DT_1 <- DT[Group2 == 1, .(avgVar1_1 = mean(Var1)), by = Group1]
DT_2 <- DT[Group2 == 2, .(avgVar1_2 = mean(Var1)), by = Group1]
group_info <- merge(DT_all, DT_1, by = "Group1")
group_info <- merge(group_info, DT_2, by = "Group1")

group_info
#    Group1 avgVar1_all avgVar1_1 avgVar1_2
# 1:      1         0.4 0.6666667 0.0000000
# 2:      2         0.6 1.0000000 0.3333333
# 3:      3         0.2 0.2500000 0.0000000
# 4:      4         0.0 0.0000000 0.0000000

DT_all只需使用
.SD
在一个分组操作中完成所有操作:

DT[, .(
        all  = mean(Var1),
        grp1 = .SD[Group2==1, mean(Var1)],
        grp2 = .SD[Group2==2, mean(Var1)]
      ),
  by = Group1,
  .SDcols=c("Group2","Var1")
  ]

#   Group1 all      grp1      grp2
#1:      1 0.4 0.6666667 0.0000000
#2:      2 0.6 1.0000000 0.3333333
#3:      3 0.2 0.2500000 0.0000000
#4:      4 0.0 0.0000000 0.0000000

您可以使用
重塑2::dcast

reshape2::dcast(DT, Group1 ~ Group2, fun=mean, margins="Group2")


  Group1         1         2 (all)
1      1 0.6666667 0.0000000   0.4
2      2 1.0000000 0.3333333   0.6
3      3 0.2500000 0.0000000   0.2
4      4 0.0000000 0.0000000   0.0
@该邮件在下面的评论中指出,这种方法不能很好地扩展。最终,在data.table的
dcast
中,这可能会更有效

一个丑陋的解决办法:

DT[, c(
  dcast(.SD, Group1 ~ Group2, fun=mean), 
  all = .(dcast(.SD, Group1 ~ ., fun=mean)$.)
)]


   Group1         1         2 all
1:      1 0.6666667 0.0000000 0.4
2:      2 1.0000000 0.3333333 0.6
3:      3 0.2500000 0.0000000 0.2
4:      4 0.0000000 0.0000000 0.0

虽然不是子集,但这确实起到了作用。SD通常不赞成这样做,是为了提高性能吗?或者这仅仅是从.SD@ConnorJ获取了一部分专栏?我在这方面还远远不是权威,但我认为
.SD
子集设置已经优化了很多,因为这是一个问题。如果我错了,很高兴被阿伦或马特拍打头部。@ConnorJ-现在我查看了一些细节,也许你是对的,这并不理想-是的,它很有效,(速度也不是不可行的慢),但可能不是最好的。我使用
.SDcols
使它尽可能快,这很有帮助。奇怪的是,我看到了为什么不将
.SD
子集的例子,但它们总是看起来像
.SD[,someCol]
,而不是
.SD[someRows]
。不确定后者是否更容易接受,但由于我们有
i
j
这两个链接,根据您的链接,这并不好。这是一个非常简洁的代码,但它似乎被真正的大数据阻塞了。我在10M记录上测试了它,在我杀死它之前,它几乎吃掉了我所有的16GB内存。很高兴知道,@thelatemail,谢谢。我想我们应该期待data.table在这种情况下的实现。是的,我的真实数据集大约有300万行,所以我会坚持数据。table's
dcast
来实现这一点。谢谢