【问题标题】:Aggregate with output length same as Data Frame length输出长度与数据帧长度相同的聚合
【发布时间】:2020-01-11 19:33:36
【问题描述】:

我需要在两个因子之间聚合一个数字,但是我需要聚合的输出是一个与原始数据帧长度相同的向量,而不是一个汇总表,所以我可以附加它并最终将其输出为.xlsx 报告。

data <- data.frame(A = c("A","A","A","A","A","A","B","B","B","B","B","B","B","B","C","C","C","C","C","C"), 
                   B = c(1,1,2,2,2,3,1,1,1,1,2,2,2,3,3,1,1,1,1,2), 
X=c(0.17,0.15,0.30,0.36,0.47,0.43,0.50,0.38,0.38,0.47,0.40,0.29,0.46,0.14,0.03,0.34,0.42,0.35,0.19,0.27))

我需要对按 A 和 A 和 B 的唯一组合分组的 X 求和,并将其附加到数据框中,使其看起来像这样

我知道聚合函数,它计算我需要的数量,但以汇总表格式输出它们,然后我无法将其附加到数据框。

到目前为止,这是我想出的唯一方法 - 在我的实际 13000 行数据帧上运行需要 10 分钟,这似乎很 hacky,而且似乎还导致了我遇到的其他一些错误希望重做这一点可以解决。

TBL <- as.data.frame(table(data$A, data$B))
colnames(TBL) <- c("A", "B", "Freq")
#contains every unique combination of A and B

for (i in 1:NROW(TBL)){
  INDEX <- which(data$A == TBL$A[i] & data$B == TBL$B[i])
  Data$`X by AB`[INDEX] <- sum(data$X[INDEX])
}

【问题讨论】:

  • 您的输入数据和预期输出似乎不匹配。 data 有两行 A = A(列名选择不当),而您的输出有 6 行。那是错字吗?除此之外,听起来你在追求ave
  • 是的,这是一个错字 - 现在已修复。为了更好地说明我想要实现的目标,我在写到一半时更改了虚构的数据,忘记在帖子中更改它。

标签: r


【解决方案1】:

似乎您需要 group_by A AND AB 并获得 sumX。使用dplyr,我们可以使用两个group_by 语句和mutate

library(dplyr)

data %>%
  group_by(A, B) %>%
  mutate(XbyAB = sum(X)) %>%
  group_by(A) %>%
  mutate(XbyA = sum(X))

#  A       B    X XbyAB  XbyA
# <fct> <dbl> <dbl> <dbl> <dbl>
# 1 A      1  0.12  0.12  0.46
# 2 A      2  0.34  0.34  0.46
# 3 B      1  0.5   0.9   1.59
# 4 B      1  0.4   0.9   1.59
# 5 B      3  0.69  0.69  1.59
# 6 C      1  0.42  0.42  0.5 
# 7 C      2  0.08  0.08  0.5 
# 8 D      2  0.9   0.9   0.9 
# 9 E      3  0.74  0.74  0.94
#10 E      4  0.2   0.2   0.94

或者在基数 R 中两个 avetransform

transform(data, XbyAB = ave(X, A, B, FUN = sum), XbyA = ave(X, A, FUN = sum))

【讨论】:

  • 打败我吧:-) (+1)
【解决方案2】:

data.table 解决方案。

library("data.table")
data <- as.data.table(data)

首先,让我们将 X 与 A 相加:

data[, .( `X by A`=sum(X) ), by=A]
# A X by A
# 1: A   1.88
# 2: B   3.02
# 3: C   1.60

我们将此汇总 data.table 与 A 列上的原始数据表合并:

data[data[, .( `X by A`=sum(X) ), by=A], on=.(A)]

我们也可以在两列上汇总然后合并:

 data[data[, .( `X by AB`=sum(X) ), by=.(A, B)], on=.(A, B)]

问题是,对于外行来说,data.table 语法不是很可读,但我发誓它的速度(与 dplyr 相比,尤其是 data.frame)。虽然 13K 行的差异应该不会很明显。

【讨论】:

    猜你喜欢
    • 2023-03-16
    • 2012-12-15
    • 2016-11-03
    • 2020-04-10
    • 2019-02-27
    • 2021-07-13
    • 2011-01-20
    • 1970-01-01
    • 2022-01-23
    相关资源
    最近更新 更多