如何在 R 数据框中用两个不同的函数聚合两个不同的列

How to aggregate two different columns with two different functions in R dataframe

我有一个数据框,其中有一些重复的记录,我需要聚合重复项,以便每行有一个唯一的记录。

一个例子:

Col1    Col2    Col3    Col4
A       0.170   83     0.878
B       0.939   103    0.869
C       0.228   80     0.935
D       0.566   169    0.851
D       0.566   137    0.588
E       0.703   103    0.636

我需要用 Col3 加权 Col4 的平均值,然后对 Col3 求和。所以我的结果是:

Col1    Col2    Col3    Col4
A      0.17     83     0.878
B      0.939    103    0.869
C      0.228    80     0.935
D      0.566    306    0.733
E      0.703    103    0.636

通常我会使用聚合函数,但我似乎找不到包含两种不同函数类型的解决方案。还有另一种方法可以做到这一点吗?我实际上忽略了 Col 2,因为在与引入 Col3 和 Col4 的数据合并之前的粒度是每行一个记录,现在它被复制了。

谢谢!!

使用 dplyr,您可以使用 group_by 保留 "Col1" 的所有唯一行,然后将所有不同的函数传递给 summarise。以您的示例为例,它可以是这样的。

注意:要通过Col3计算Col4的weighted.mean,你需要在计算Col3的sum之前传递这个函数,否则Col4和Col3的长度会不同。

然后您可以使用 select:

以正确的顺序重新组织数据框
library(dplyr)
df %>% group_by(Col1) %>%
  summarise(Col2 = mean(Col2),
            Col4 = weighted.mean(Col4,Col3),
            Col3 = sum(Col3)) %>%
  select(Col1,Col2,Col3,Col4)

# A tibble: 5 x 4
  Col1   Col2  Col3  Col4
  <chr> <dbl> <int> <dbl>
1 A     0.17     83 0.878
2 B     0.939   103 0.869
3 C     0.228    80 0.935
4 D     0.566   306 0.733
5 E     0.703   103 0.636

数据

structure(list(Col1 = c("A", "B", "C", "D", "D", "E"), Col2 = c(0.17, 
0.939, 0.228, 0.566, 0.566, 0.703), Col3 = c(83L, 103L, 80L, 
169L, 137L, 103L), Col4 = c(0.878, 0.869, 0.935, 0.851, 0.588, 
0.636)), row.names = c(NA, -6L), class = c("data.table", "data.frame"
), .internal.selfref = <pointer: 0x561706072cc0>)

基础 R 解决方案:

aggregated_df <- data.frame(do.call("rbind", lapply(split(df, df$Col1), function(x){
        list(Col1 = unique(x$Col1), Col2 = mean(x$Col2), Col3 = sum(x$Col3), 
                   Col4 = weighted.mean(x$Col4, x$Col3))
      }
    )
  ),
stringsAsFactors = FALSE)

数据:

df <-
  structure(
    list(
      Col1 = c("A", "B", "C", "D", "D", "E"),
      Col2 = c(0.17,
               0.939, 0.228, 0.566, 0.566, 0.703),
      Col3 = c(83L, 103L, 80L,
               169L, 137L, 103L),
      Col4 = c(0.878, 0.869, 0.935, 0.851, 0.588,
               0.636)
    ),
    row.names = c(NA,-6L),
    class = c("data.frame"
    ))