如何对按一列分组的一组列求和

How to sum a set of columns grouped by one column

我有一个这样的数据框

ID <- c('John', 'Bill', 'Alice','Paulina')
Type1 <- c(1,1,0,1)
Type2 <- c(0,1,1,0)     
cluster <- c(1,2,3,1)

test <- data.frame(ID, Type1, Type2, cluster)

我想按簇分组并对所有其他列中的值求和,除了应该删除的 ID。

我通过

实现了
test.sum <- test %>%
  group_by(cluster)%>%
  summarise(sum(Type1), sum(Type2)) 

但是,我有几千种类型,我无法手动写出摘要中的每一列。你能帮帮我吗?

这就是 across()contains 对 select 您想要汇总的列非常有用的地方:

test %>% 
    group_by(cluster) %>% 
    summarise(across(contains("Type"), sum))
  cluster Type1 Type2
    <dbl> <dbl> <dbl>
1       1     2     0
2       2     1     1
3       3     0     1

或者,将数据集转为长数据集,然后再转为宽数据集,这意味着您可以轻松地同时分析所有组和集群:

library(dplyr)
library(tidyr)

test %>% 
    pivot_longer(-c(ID, cluster)) %>% 
    group_by(cluster, name) %>% 
    summarise(sum_value = sum(value)) %>% 
    pivot_wider(names_from = "name", values_from = "sum_value")
  cluster Type1 Type2
    <dbl> <dbl> <dbl>
1       1     2     0
2       2     1     1
3       3     0     1

基础 R

您可以利用 split,它等同于 group_by()。无论您有多少 Type,这都会给您想要的东西。

my_split <- split(subset(test, select = grep('^Ty', names(test))), test[, -1]$cluster)
my_sums <- sapply(my_split, \(x) colSums(x))
my_sums <- data.frame( cluster = as.numeric(gsub("\D", '', colnames(my_sums))),
                       t(my_sums) )

输出

> my_sums
  cluster Type1 Type2
1       1     2     0
2       2     1     1
3       3     0     1

注意:如果您使用 R <4.1.0

版本,请使用 function(x) 而不是 \(x)