web-dev-qa-db-fra.com

Grouper par plusieurs colonnes et additionner d'autres colonnes

J'ai un bloc de données avec environ 200 colonnes, sur lesquelles je veux regrouper la table par environ 10 premières qui sont des facteurs et additionner les autres colonnes.

J'ai la liste de tous les noms de colonnes que je veux regrouper et la liste de tous les colonnes que je veux agréger.

Le format de sortie que je recherche doit être la même image de données avec le même nombre de colonnes, mais simplement regroupé.

Existe-t-il une solution utilisant les packages data.table, plyr ou un autre?

17
user1042267

Le data.table way est:

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

ou

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

.SD est le sous-ensemble (S) des colonnes du groupe (D) ata exclusion. (De plus, si vous devez faire référence de manière générique aux groupes de colonnes, ils sont en .BY.)

18
Matt Dowle

En base R ce serait ...

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

EDIT: La fonction d'agrégation a parcouru un long chemin depuis que j'ai écrit ceci. Aucune de la coulée ci-dessus n'est nécessaire. 

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

Et il y a une variété de façons d'écrire cela. En supposant que les 10 premières colonnes sont nommées a1 à a10 J'aime ce qui suit, même s'il est détaillé.

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

(Vous pouvez utiliser une pâte pour construire la formule et utiliser formula)

16
John

Cela semble être une tâche pour ddply (j'utilise le jeu de données 'baseball' qui est inclus avec plyr):

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

Cela donne à groupColumns la somme des colonnes spécifiées dans dataColumns.

16
Paul Hiemstra

Utilisation de plyr :: ddply:

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

La manière dplyr serait:

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

Vous pouvez également spécifier les colonnes à récapituler ou à exclure du summarise_each en utilisant les fonctions spéciales mentionnées dans le fichier d'aide de ?dplyr::select.

9
docendo discimus

Une autre façon de faire cela avec dplyr qui serait générique (pas besoin de liste de colonnes) serait:

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