Группировать по нескольким столбцам и суммировать другие столбцы - PullRequest
17 голосов
/ 21 ноября 2011

У меня есть фрейм данных с примерно 200 столбцами, из которых я хочу сгруппировать таблицу по первым 10 или около того, которые являются факторами, и суммировать остальные столбцы.

У меня есть список всех имен столбцов, по которым я хочу сгруппировать, и список всех столбцов, которые я хочу объединить.

Выходной формат, который я ищу, должен быть одним и тем же кадром данных с одинаковым количеством столбцов, просто сгруппированных вместе.

Есть ли решение с использованием пакетов data.table, plyr или любого другого?

Ответы [ 6 ]

18 голосов
/ 21 ноября 2011

data.table путь:

DT[, lapply(.SD,sum), by=list(col1,col2,col3,...)]

или

DT[, lapply(.SD,sum), by=colnames(DT)[1:10]]

где .SD - (S) ubset (D) ata , исключая групповые столбцы. (В сторону: если вам нужно обратиться к групповым столбцам в общем, они находятся в .BY.)

16 голосов
/ 21 ноября 2011

В базе R это будет ...

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

EDIT : Агрегатная функция прошла долгий путь с тех пор, как я написал это. Ничто из приведенного выше не является необходимым.

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

И есть множество способов написать это. Предполагая, что первые 10 столбцов имеют имена от a1 до a10, мне нравится следующее, хотя оно многословно.

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

(Вы можете использовать вставить для построения формулы и использовать formula)

16 голосов
/ 21 ноября 2011

Это похоже на задачу для ddply (я использую набор данных 'baseball', который входит в состав plyr):

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

Это дает для каждого groupColumns сумму столбцов, указанных в dataColumns.

11 голосов
/ 22 октября 2015

Способ dplyr будет следующим:

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

Вы можете дополнительно указать столбцы, которые будут суммироваться или исключаться из summarise_each, используя специальные функции, упомянутые в файле справки ?dplyr::select.

10 голосов
/ 21 ноября 2011

Использование plyr :: ddply:

library(plyr)
ddply(dtfr, .(name1, name2, namex), numcolwise(sum))
1 голос
/ 19 марта 2018

Другой способ сделать это с помощью dplyr, который будет общим (не нужен список столбцов), будет:

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