删除data.table中的分组变量

3
我想使用data.table进行一些数据整理操作,并希望我的结果数据表中不包括分组变量。

这是一个最小化示例:

library("data.table")
DT <- data.table(x = 1:10, grp = rep(1:2,5))
DT[, .(mmm = mean(x)), by = grp]

这将产生:

   grp mmm
1:   1   5
2:   2   6

这一切都很好。但是,我希望不要出现 grp 变量。可以通过将 data.table 命令链接在一起并设置 grp := NULL,或者只是丢弃该变量来解决此问题。但是,在第一个调用中是否可以避免它,使我只返回 mmm ?


DT[, .(mmm = mean(x)), by = grp][, grp := NULL][]的替代方案可以是DT[, .(mmm = DT[, .(mmm = mean(x)), by = grp]$mmm)] - Jaap
你到底不喜欢 DT[..., by = grp][, !'grp'] 或者 DT[..., by = grp][, grp := NULL] 的哪一点呢? - eddi
我正在使用资源有限的远程系统工作,时不时地会遇到内存问题。我的理解(可能是错误的)是,链式数据表仍然保留第一次调用后的所有内容,并且在设置[, grp := NULL]之后才释放内存,因此希望节省这一初始步骤。并不是说我不同意[, grp := NULL]在美学和功能上更加令人愉悦。 - ekstroem
@ekstroem 我想不出有什么办法可以使用 by,而不使用那个额外的内存列(我也很难想象那一列会成为瓶颈)。我没有检查过,但也许 tapply 在这种特殊情况下会使用更少的内存(但你将付出严重的性能代价)。 - eddi
@eddi 你可能是对的。我刚刚处于“去除一切无关紧要的东西”的模式,并且认为有一种方法可以完全跳过在我的调用中包括by变量。tapply的时间惩罚使得我认为我无法追求这条路。 - ekstroem
1个回答

5

目前不清楚为什么你不想使用这种方法。我建议首先使用 DT[, .(mmm = mean(x)), by = grp][, grp := NULL][]

虽然我不建议这么做,但你也可以使用:

DT[, .(mmm = DT[, .(mmm = mean(x)), by = grp]$mmm)]

这将为您提供所需的结果:
   mmm
1:   5
2:   6

虽然你会得到相同的结果,但最好不要使用这种方法。其主要缺点是,当你想要总结多个值列时,你会使你的代码变得不必要地复杂。你将得到类似于以下内容:

DT[, .(mx = DT[, .(mx = mean(x)), by = grp]$mx, my = DT[, .(my = mean(y)), by = grp]$my)]

使用正常的data.table方式将是:

DT[, .(mx = mean(x), my = mean(y)), by = grp][, grp := NULL][]

总结:

使用DT[, .(mmm = mean(x)), by = grp][, grp := NULL][]方法是您最好的选择。


这样做就像用左脚挠右耳朵一样没有意义。当你的 i-expression 超过一列时,你打算怎么办? - eddi
@eddi 为什么要踩我?如我在第一句所说,使用 DT[, .(mmm = mean(x)), by = grp][, grp := NULL][] 将是我的首选。我提供的替代方法虽然可行(但不是首选方式)。回答已更新。 - Jaap
@Jaap,我认为这个答案没有用处——它不具有普适性,语法也很糟糕(重复多次相同的内容),并且没有实际功能;而且重申OP中提到的内容并不能让我觉得有用。我理解你的努力,但我看不到任何增加的价值。 - eddi
@eddi 我同意最好不要使用这种方法。我第二次更新了我的答案以更好地说明这一点。向人们解释为什么最好不要做某事似乎非常有用。 - Jaap

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接