首页 > 解决方案 > R - 每组计算 - data.table 和 aggregate()

问题描述

我想按组进行简单的计算。正如我经常使用的那样aggregate。要按组计算我的,sumvargp1了:gp2gp3

m.temp  <- aggregate(var ~ gp1 + gp2 + gp3, df, sum)

它运作良好,但速度很慢。在数据表中执行此操作之前,我想尝试更改函数的语法以加快处理速度。然后我做了:

m.temp2 <- aggregate(df$var, 
                     list(df$gp1, df$gp2, df$gp3), 
                     sum)

对我来说不幸的是,一个简单的验证告诉我这些计算是不等价的。

> identical(m.temp, m.temp2)
[1] FALSE

变量名称不同,但更糟糕的是,这 2 个结果之间存在 19 477 个观察值(行)的差异,这不是因为某些NAs存在......

那么我的第一个问题来了:怎么会?这两种语法有什么区别?

为了了解哪种语法更好,我尝试使用简单的 data.table 过程来完成。不幸的是,由于我的语法不正确,我无法得到任何结果,但我不明白我错过了什么。我绑:

m.temp4 <- df[, list(sum = sum(df$var)), 
                      by = list(gp1, gp2, gp3)]

最后,我也尝试直接聚合一个新列,同样没有结果...

df[, new.col := sum(var), by = list(gp1, gp2, gp3)] 

我做错了什么?

标签: rdata.tableaggregate

解决方案


假设数据集是data.table或者转换为一个setDT

library(data.table)
setDT(df)[, new_col := sum(var), by = .(gp1, gp2, gp3)]

在 OP 的帖子中,sum是在整个列df$var而不是组内的“var”元素上完成的,从而产生一个sum值。删除df$并使用不带引号的列名。

注意::=创建一个新列。如果目的是总结,请将其放在list.()

setDT(df)[, .(new_col =  sum(var)), by = .(gp1, gp2, gp3)]

另一种选择是tidyverse

library(tidyverse)
df %>%
    group_by(gp1, gp2, gp3) %>%
    summarise(new_col = sum(var))

要创建新列,请替换summarisemutate


推荐阅读