web-dev-qa-db-fra.com

Agréger/résumer plusieurs variables par groupe (par exemple, somme, moyenne)

À partir d'un bloc de données, existe-t-il un moyen simple d'agréger (sum, mean, max et c) plusieurs variables simultanément?

Voici quelques exemples de données:

library(lubridate)
days = 365*2
date = seq(as.Date("2000-01-01"), length = days, by = "day")
year = year(date)
month = month(date)
x1 = cumsum(rnorm(days, 0.05)) 
x2 = cumsum(rnorm(days, 0.05))
df1 = data.frame(date, year, month, x1, x2)

Je voudrais regrouper simultanément les variables x1 et x2 à partir du bloc de données df2 par année et par mois. Le code suivant agrège la variable x1, mais est-il également possible d'agréger simultanément la variable x2?

### aggregate variables by year month
df2=aggregate(x1 ~ year+month, data=df1, sum, na.rm=TRUE)
head(df2)

Toutes les suggestions seraient grandement appréciées.

124
MikeTP

D'où vient cette fonction year()?

Vous pouvez également utiliser le package reshape2 pour cette tâche:

require(reshape2)
df_melt <- melt(df1, id = c("date", "year", "month"))
dcast(df_melt, year + month ~ variable, sum)
#  year month         x1           x2
1  2000     1  -80.83405 -224.9540159
2  2000     2 -223.76331 -288.2418017
3  2000     3 -188.83930 -481.5601913
4  2000     4 -197.47797 -473.7137420
5  2000     5 -259.07928 -372.4563522
42
EDi

Oui, dans votre formula, vous pouvez cbind les variables numériques à agréger:

aggregate(cbind(x1, x2) ~ year + month, data = df1, sum, na.rm = TRUE)
   year month         x1          x2
1  2000     1   7.862002   -7.469298
2  2001     1 276.758209  474.384252
3  2000     2  13.122369 -128.122613
...
23 2000    12  63.436507  449.794454
24 2001    12 999.472226  922.726589

Voir ?aggregate, l'argument formula et les exemples.

175
Andrie

Utilisation du package data.table, qui est rapide (utile pour les grands ensembles de données)

https://github.com/Rdatatable/data.table/wiki

library(data.table)
df2 <- setDT(df1)[, lapply(.SD, sum), by=.(year, month), .SDcols=c("x1","x2")]
setDF(df2) # convert back to dataframe

Utiliser le paquet plyr

require(plyr)
df2 <- ddply(df1, c("year", "month"), function(x) colSums(x[c("x1", "x2")]))

Utilisation de resume () du paquetage Hmisc

# need to detach plyr because plyr and Hmisc both have a summarize()
detach(package:plyr)
require(Hmisc)
df2 <- with(df1, summarize( cbind(x1, x2), by=llist(year, month), FUN=colSums))
46
numbercruncher

Avec le package dplyr, vous pouvez utiliser les fonctions summarise_all, summarise_at ou summarise_if pour regrouper simultanément plusieurs variables. Pour l'exemple de jeu de données, vous pouvez procéder comme suit:

library(dplyr)
# summarising all non-grouping variables
df2 <- df1 %>% group_by(year, month) %>% summarise_all(sum)

# summarising a specific set of non-grouping variables
df2 <- df1 %>% group_by(year, month) %>% summarise_at(vars(x1, x2), sum)
df2 <- df1 %>% group_by(year, month) %>% summarise_at(vars(-date), sum)

# summarising a specific set of non-grouping variables based on condition (class)
df2 <- df1 %>% group_by(year, month) %>% summarise_if(is.numeric, sum)

Le résultat de ces deux dernières options:

    year month        x1         x2
   <dbl> <dbl>     <dbl>      <dbl>
1   2000     1 -73.58134  -92.78595
2   2000     2 -57.81334 -152.36983
3   2000     3 122.68758  153.55243
4   2000     4 450.24980  285.56374
5   2000     5 678.37867  384.42888
6   2000     6 792.68696  530.28694
7   2000     7 908.58795  452.31222
8   2000     8 710.69928  719.35225
9   2000     9 725.06079  914.93687
10  2000    10 770.60304  863.39337
# ... with 14 more rows

Remarque: summarise_each est déconseillé au profit de summarise_all, summarise_at et summarise_if.


Comme mentionné dans mon commentaire ci-dessus , vous pouvez également utiliser la fonction recast du paquetage reshape2-:

library(reshape2)
recast(df1, year + month ~ variable, sum, id.var = c("date", "year", "month"))

ce qui vous donnera le même résultat.

41
Jaap

Il est intéressant de noter que la méthode data.frame de la base R aggregate de __ n'est pas présentée ici, above l'interface de formule est utilisée, donc pour être complet:

aggregate(
  x = df1[c("x1", "x2")],
  by = df1[c("year", "month")],
  FUN = sum, na.rm = TRUE
)

Utilisation plus générique de la méthode d'agrégat data.frame:

Depuis que nous fournissons un

  • data.frame comme x et 
  • un list (data.frame est aussi un list) en tant que by, cela est très utile si nous devons l’utiliser de manière dynamique, par exemple. en utilisant d'autres colonnes à agréger et à agréger par est très simple
  • également avec des fonctions d'agrégation sur mesure 

Par exemple, comme ceci:

colsToAggregate <- c("x1")
aggregateBy <- c("year", "month")
dummyaggfun <- function(v, na.rm = TRUE) {
  c(sum = sum(v, na.rm = na.rm), mean = mean(v, na.rm = na.rm))
}

aggregate(df1[colsToAggregate], by = df1[aggregateBy], FUN = dummyaggfun)
2
Jozef

En retard pour le parti, mais récemment trouvé un autre moyen d'obtenir les statistiques récapitulatives.

library(psych) describe(data)

Sortie de sortie: Moyenne, min, max, écart type, n, erreur type, kurtosis, asymétrie, médiane et étendue pour chaque variable 

0
britt