按多个列分组并求其他多个列的总和

25

我有一个包含约200列的数据框,其中我想按前10个因子进行分组,并求其余列的总和。

我有要分组的所有列名列表和要聚合的所有列列表。

我需要的输出格式是相同的数据框,具有相同数量的列,只是已经分组在一起了。

是否可以使用data.tableplyr或其他任何包来解决问题?

7个回答

23

data.table 的方式是:

DT[, lapply(.SD,sum), by=list(col1,col2,col3,...)]
或者
DT[, lapply(.SD,sum), by=colnames(DT)[1:10]]

其中.SD是(D)ata的子集,不包括组列。(顺便说一下:如果你需要泛指组列,它们在.BY中。)


23

请看下面使用dplyr::across的更现代化的回答。

dplyr的方法是:

library(dplyr)
df %>%
  group_by(col1, col2, col3) %>%
  summarise_each(funs(sum))

您可以使用在?dplyr::select的帮助文件中提到的特殊函数进一步指定要汇总或排除的列,以便使用summarise_each


20

在基础R中,这将是...

aggregate( as.matrix(df[,11:200]), as.list(df[,1:10]), FUN = sum)

编辑: 自从我写这篇文章以来,聚合函数已经取得了长足的进步。上述的转换已经不再必要。

aggregate( df[,11:200], df[,1:10], FUN = sum )

有很多种方法可以编写这个。假设前10列的名称为a1a10,我喜欢以下方式,即使它有些啰嗦。

aggregate(. ~ a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10, data = dat, FUN = sum)

(您可以使用paste函数构造公式并使用formula


19

这似乎是使用ddply的一个任务(我使用包含在plyr中的“baseball”数据集):

library(plyr)
groupColumns = c("year","team")
dataColumns = c("hr", "rbi","sb")
res = ddply(baseball, groupColumns, function(x) colSums(x[dataColumns]))
head(res)

这将为每个groupColumns计算在dataColumns中指定的列的总和。


10

使用plyr::ddply:

library(plyr)
ddply(dtfr, .(name1, name2, namex), numcolwise(sum))

9
让我们来考虑这个例子:
df <- data.frame(a = 'a', b = c('a', 'a', 'b', 'b', 'b'), c = 1:5, d = 11:15,
                 stringsAsFactors = TRUE)

从dplyr 1.1.0版本开始更新

您可以使用pick来选择列 -

df %>% 
  group_by(pick(where(is.factor))) %>% 
  summarise(across(everything(), sum))

或者使用.by参数。
df %>% summarise(across(everything(), sum), .by = where(is.factor))

dplyr 1.1.0 之前, _all_at_if 动词现已被取代,我们现在使用 across 来对所有因子列进行分组,并对所有其他列求和,我们可以这样做:
library(dplyr)

df %>% 
   group_by(across(where(is.factor))) %>% 
   summarise(across(everything(), sum))

#  a     b         c     d
#  <fct> <fct> <int> <int>
#1 a     a         3    23
#2 a     b        12    42

将所有因子列分组并求和数值列:
df %>% 
  group_by(across(where(is.factor))) %>% 
  summarise(across(where(is.numeric), sum))

我们也可以通过位置来做,但是要小心数量,因为它不计算分组列。
df %>% group_by(across(1:2)) %>% summarise(across(1:2, sum))

2

使用dplyr进行通用操作的另一种方法(不需要列的列表)是:

df %>% group_by_if(is.factor) %>% summarize_if(is.numeric,sum,na.rm = TRUE)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接