【问题标题】:Create n new columns by n distinct groups in data.table在 data.table 中由 n 个不同的组创建 n 个新列
【发布时间】:2021-08-05 19:43:06
【问题描述】:

我有以下数据表,想对 y 求和两次,将 first 时间按 g1 分组,将 second 时间按 g2 分组。

通常我会将计算链接在一起,但我希望能够按 n 个组在不同时间进行分组总和。

library(data.table)
  DT <- data.table(
    g1 = c("a", "b"),
    g2 = c("a", "a"),
    y = c(3,5)
  )

new_cols <- paste0("sum_by_", c("g1", "g2"))
group_cols <- c("g1", "g2")

# Supplying cols to by like this groups by g1 AND g2, when in reality I want it to 
# take g1 the first time and g2 the second time. 
DT[, paste(new_cols) := lapply(rep(y, length(new_cols)), sum),
   by = .(group_cols)][]

这给了我:

#    g1 g2 y sum_by_g1 sum_by_g2
# 1:  a  a 3         3         3
# 2:  b  a 5         5         5

当我真正想要的时候:

#    g1 g2 y sum_by_g1 sum_by_g2
# 1:  a  a 3         3         8
# 2:  b  a 5         5         8

是否有任何巧妙的 data.table 方法可以做到这一点? 类似的东西向 by 提供 .SD(这本身似乎不起作用)?

编辑:将 y 从 c(1,1) 更改为 c(3,5)

编辑原理:当 y = c(1,1) 时的实际和期望输出给人的印象是我想计算每个组中的观察值,而实际上我想为每个组求和(y)。

【问题讨论】:

  • @akrun 因为第二个的 sum_by_g2 是组 g2 == "a" 的 y 的总和。 (length() 只是为了给 y lapply 正确的次数。也许这也是不好的形式?)
  • 我知道您想要的结果是 wide 格式,但我只想提一下data.table 工具箱中的另一项:groupingsets,它给出了答案long 格式。在这里我们可以做类似groupingsets(DT, j = sum(y), by = c("g1", "g2"), sets = list("g1", "g2"))的事情。

标签: r data.table


【解决方案1】:

分组应该分开,因为a aa b 被视为唯一元素,因此每个组只有一个观察值

for(i in seq_along(group_cols)) DT[, (new_cols[i]) := sum(y), by = c(group_cols[i])]

-输出

DT
   g1 g2 y sum_by_g1 sum_by_g2
1:  a  a 3         3         8
2:  b  a 5         5         8

【讨论】:

  • 使用这个 for(i in seq_along()) 完美地解决了我的问题。唯一的问题是,我想要的和实际的示例输出对于我是想要总和还是按组计算的行数是模棱两可的。我已经编辑了我的输入数据,试图让它更清楚。
  • @gvan 你想要的同时显示sum 即 3 5 和 8 8
【解决方案2】:

您可以尝试Reduce,如下所示

> Reduce(function(dt, g) dt[, paste0("sum_by_", g) := .N, g], list(DT, "g1", "g2"))[]
   g1 g2 y sum_by_g1 sum_by_g2
1:  a  a 1         1         2
2:  b  a 1         1         2

> Reduce(function(dt, g) dt[, paste0("sum_by_", g) := .N, g], c("g1", "g2"),init = DT)[]
   g1 g2 y sum_by_g1 sum_by_g2
1:  a  a 1         1         2
2:  b  a 1         1         2

【讨论】:

    猜你喜欢
    • 2022-01-05
    • 2011-07-03
    • 1970-01-01
    • 1970-01-01
    • 2021-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-13
    相关资源
    最近更新 更多