2012-03-15 87 views
99

Desde un marco de datos, ¿hay una manera fácil de agregar (es decir, sumar) múltiples variables simultáneamente?Agrupar/resumir múltiples variables por grupo (es decir, suma, media, etc.)

continuación se presentan algunos datos de ejemplo:

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) 

me gustaría agregar simultáneamente las x1 y x2 variables de la trama de datos df2 por año y mes. El siguiente código agrega la variable x1, ¿pero también es posible agregar simultáneamente la variable x2?

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

Cualquier sugerencia sería muy apreciada.

+0

@Jaap Esta pregunta no es una pregunta duplicada con el siguiente enlace. Es porque se trata de qué hacer con "dplyr". Por favor cancele la marca duplicada. r - ¿Resumiendo múltiples columnas con dplyr? - Desbordamiento de pila https://stackoverflow.com/questions/21644848/summarizing-multiple-columns-with-dplyr – Keiku

Respuesta

32

¿De dónde es la función de este año()?

También es posible usar el paquete reshape2 para esta tarea:

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 
+6

La función 'refundir' (también de' reshape2') integra las funciones 'melt' y' dcast' de una vez para tareas como esta: 'refundición (df1, año + mes ~ variable, suma, id.var = c ("fecha", "año", "mes")) ' – Jaap

151

Sí, en sus formula, puede cbind las variables numéricas para agregarse:

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 

Ver ?aggregate, el argumento formula y los ejemplos.

+2

¿Es posible que cbind use variables dinámicas? –

+9

Vale la pena señalar que cuando cualquiera de las variables que están en el cbind tiene una NA, la fila se eliminará para cada variable en el cbind. Este no es el comportamiento que esperaba. –

+0

¿Qué pasa si en lugar de x1 yx2 quiero utilizar todas las variables restantes (que no sean año, mes) –

39

Usando el paquete data.table, que es rápido (útil para grandes conjuntos de datos)

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 

Utilizando el paquete plyr

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

El uso de resumir() del paquete Hmisc (encabezados de columna son desordenados en mi ejemplo, aunque)

# 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)) 
25

Con el paquete dplyr, puede utilizar summarise_all, summarise_at o summarise_if funciones para agregar múltiples variables simultáneamente. Para el ejemplo de conjunto de datos se puede hacer esto de la siguiente manera:

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) 

El resultado de las dos últimas opciones:

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 

Nota: summarise_each está en desuso en favor de summarise_all, summarise_at y summarise_if.


Como se mencionó en my comment above, también se puede utilizar la función de la recastreshape2 Paquete:

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

el cual le dará el mismo resultado.

Cuestiones relacionadas