在 data.table 中按 n 个不同的组创建 n 个新列
Create n new columns by n distinct groups in data.table
我有以下数据 table,我想对 y 求和两次,将 first 时间按 g1 和 second[=33 分组=] 时间按 g2.
通常我只是将计算链接在一起,但我希望能够通过 n[=33= 进行不同时间的分组总和 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 方法来做到这一点? 像 提供 .SD 的东西(这本身似乎不起作用)?
编辑:将 y 从 c(1,1) 更改为 c(3,5)
编辑理由:y = c(1,1) 时的实际输出和期望输出给人的印象是我想计算每个组中的观察值,而实际上我想对每个组求和 (y)。
分组应分开,因为 a a
和 a 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
您可以像下面那样尝试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
我有以下数据 table,我想对 y 求和两次,将 first 时间按 g1 和 second[=33 分组=] 时间按 g2.
通常我只是将计算链接在一起,但我希望能够通过 n[=33= 进行不同时间的分组总和 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 方法来做到这一点? 像 提供 .SD 的东西(这本身似乎不起作用)?
编辑:将 y 从 c(1,1) 更改为 c(3,5)
编辑理由:y = c(1,1) 时的实际输出和期望输出给人的印象是我想计算每个组中的观察值,而实际上我想对每个组求和 (y)。
分组应分开,因为 a a
和 a 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
您可以像下面那样尝试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