【问题标题】:R - Per group computations - data.table and aggregate()R - 每组计算 - data.table 和 aggregate()
【发布时间】:2019-09-03 11:49:09
【问题描述】:

我想按组进行简单的计算。我经常使用aggregate。要按组gp1gp2gp3 计算我的varsum,我做了:

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)] 

我做错了什么?

【问题讨论】:

  • 试试df[, .(sum = sum(var)), by = .(gp1, gp2, gp3)],我们不需要df$var,它将选择整列而不是组中的值

标签: r data.table aggregate


【解决方案1】:

假设数据集是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))

要创建新列,请将summarise 替换为mutate

【讨论】:

  • m.temp
  • @TeYaP 通常不等价。 := 创建一个列,而 aggregate 进行汇总。问题在于aggregate,因为当您需要添加na.action = na.passna.rm = TRUE 的任何列中有一个NA 时,它会删除NA 行
  • @TeYaP 好的,我在你的代码中指的是df[, new.col := sum(var), by = list(gp1, gp2, gp3)]
  • @TeYaP 无论如何,我建议aggregate 结果不同的一个原因。你可能不同意
  • data.table 的方式是“更高效”... PS:编辑你的答案,你忘了一个“T”,第二行,“setDT”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-30
  • 2022-07-06
  • 2020-03-26
  • 1970-01-01
  • 2015-09-12
相关资源
最近更新 更多