Aggregate en R

Manipulación de datos con R Transformación de datos
Ejemplos de uso de la función aggregate en R

En R, puedes usar la función aggregate para calcular resúmenes estadísticos para subconjuntos de datos. Esta función es muy similar a la función tapply pero en este caso también puedes pasar una fórmula o un objeto de serie temporal como entrada y además la salida es un data frame. En este tutorial aprenderás cómo usar la función aggregate en R con varios ejemplos, para agregar filas en base a un factor.

La función aggregate() en R

La sintaxis de la función aggregate dependerá de los datos de entrada. Hay tres tipos de entrada posibles: un data frame, una fórmula y un objeto de clase serie temporal. Los argumentos y su descripción se resumen para cada método en el siguiente bloque:

# Data frame
aggregate(x,               # Objeto de R
          by,              # Lista de variables (elementos que forman los grupos)
          FUN,             # Función a ser aplicada para crear el resumen estadístico
          ...,             # Argumentos adicionales a ser pasados a FUN
          simplify = TRUE, # Simplificar el resultado lo máximo posible (TRUE) o no (FALSE)
          drop = TRUE)     # Deshechar las combinaciones no usadas de grupos (TRUE) o no (FALSE).

# Formula
aggregate(formula,             # Fórmula de entrada
          data,                # Lista o data frame donde se encuentran las variables
          FUN,                 # Función a ser aplicada para crear el resumen estadístico
          ...,                 # Argumentos adicionales a ser pasados a FUN
          subset,              # Observaciones a ser usadas (opcional)
          na.action = na.omit) # Cómo tratar valores NA

# Serie de tiempo
aggregate(x,                   # Serie temporal
          nfrequency = 1,      # Observaciones por unidad de tiempo (submúltiplo de x)
          FUN = sum,           # Función a ser aplicada para crear el resumen estadístico
          ndeltat = 1,         # Fracción entre dos observaciones consecutivas
          ts.eps = getOption("ts.eps"), # Tolerancia para determinar si 'nfrequency' es un submúltiplo de la frecuencia de x
          ...)                 # Argumentos adicionales a ser pasados a FUN

Recuerda escribir help(aggregate) o ?aggregate para obtener detalles adicionales.

En las siguientes secciones mostraremos ejemplos y casos de uso, como agregar la media, realizar recuentos, o calcular cuantiles por grupos, entre otros ejemplos. Usar aggregate en R es muy simple y cabe mencionar que puedes aplicar cualquier función que quieras, incluso una función personalizada.

Agregar la media

Considera, por ejemplo, el siguiente conjunto de datos, que contiene el peso y el tipo de alimentación de una muestra de pollos:

df <- chickwts
head(df)
   weight     feed
1    179    horsebean
2    160    horsebean
3    136    horsebean
4    227    horsebean
5    217    horsebean
6    168    horsebean

Para utilizar la función aggregate para calcular la media por grupos en R, deberás especificar la variable numérica en el primer argumento, la categórica (como una lista) en el segundo y la función que se aplicará (en este caso mean) en el tercero. Una alternativa es especificar una fórmula de la forma: numérica ~ categórica.

group_mean <- aggregate(df$weight, list(df$feed), mean)
group_mean <- aggregate(weight ~ feed, data = df, mean) # Equivalente
group_mean
    Group.1      x
1    casein   323.5833
2 horsebean   160.2000
3   linseed   218.7500
4  meatmeal   276.9091
5   soybean   246.4286
6 sunflower   328.9167

Ten en cuenta que, cuando se utiliza una fórmula, la variable de grupo se convierte por defecto en clase factor. En consecuencia, también podrías usar una variable numérica que represente grupos.

Sin embargo, es posible que hayas notado que los nombres de las columnas del data frame resultante no representan las variables. Para modificar los nombres de las columnas de la salida, puedes usar la función colnames de la siguiente manera:

colnames(group_mean) <- c("Grupo", "Media")
group_mean
      Grupo     Media
1    casein   323.5833
2 horsebean   160.2000
3   linseed   218.7500
4  meatmeal   276.9091
5   soybean   246.4286
6 sunflower   328.9167

Contar los elementos de una variable categórica

A veces puede ser útil saber la cantidad de elementos de cada grupo de una variable categórica. Aunque podrías usar la función table, si quieres que la salida sea un data frame, puedes obtener el recuento aplicando la función length.

aggregate(chickwts$feed, by = list(chickwts$feed), FUN = length)
aggregate(feed ~ feed, data = chickwts, FUN = length) # Equivalente
    Group.1   x
1    casein  12
2 horsebean  10
3   linseed  12
4  meatmeal  11
5   soybean  14
6 sunflower  12

Agregar los cuantiles

En esta sección, vamos a usar un objeto de serie temporal de la clase xts como ejemplo, aunque podrías usar un data frame para aplicar la función. Considera el siguiente objeto de muestra, que representa los rendimientos mensuales de un fondo de inversión:

set.seed(1)

Fechas <- seq(dmy("01/01/2014"), dmy("01/01/2015"), by = "day")
Rendimiento <- rnorm(length(Fechas))

# install.packages("xts")
library(xts)
tserie <- xts(Rendimiento, Fechas)

head(tserie)
                 [, 1]
2014-01-01  -0.6264538
2014-01-02   0.1836433
2014-01-03  -0.8356286
2014-01-04   1.5952808
2014-01-05   0.3295078
2014-01-06  -0.8204684

En este escenario, puedes estar interesado en calcular los cuantiles por fecha (agregando los datos diarios a mensuales o semanales, por ejemplo). En este escenario, puedes calcular los cuantiles 5% y 95% para los retornos de cada mes escribiendo:

dat <- aggregate(tserie ~ month(index(tserie)), FUN = quantile,
                 probs = c(0.05, 0.95))
colnames(dat)[1] <- "Mes"
dat
    Mes     V1.5%      V2.95%
1    1   -1.7041221   1.2301178
2    2   -0.9388331   1.7888182
3    3   -1.3886001   1.5261942
4    4   -1.0834517   1.5697239
5    5   -1.6527890   1.0883061
6    6   -1.4064641   2.1472166
7    7   -1.3117488   1.6377309
8    8   -1.8666917   1.1298708
9    9   -1.8513285   1.4615978
10  10   -1.0359233   1.7162873
11  11   -1.4453582   1.3389949
12  12   -2.0918996   1.5258865

Recuerda que puedes agregar argumentos adicionales de la función que está aplicando separándolos con comas después del argumento FUN.

Agregar datos en R usando múltiples columnas

Por último, es importante destacar que es posible agregar más de una variable. Para este propósito existen tres opciones: agregar más de una variable categórica, agregar múltiples variables numéricas o ambas a la vez.

Por un lado, vamos a crear una nueva variable categórica llamada cat_var.

set.seed(1)

cat_var <- sample(c("A", "B", "C"), nrow(df), replace = TRUE)
df_2 <- cbind(df, cat_var)
head(df_2)
    weight    feed      cat_var
1    179    horsebean       A
2    160    horsebean       C
3    136    horsebean       A
4    227    horsebean       B
5    217    horsebean       A
6    168    horsebean       C

Ahora, puedes usar la función aggregate para resumir el data frame en base a las dos variables, especificando las variables adicionales dentro de la lista de variables categóricas, o especificando una fórmula sumando las variables. En este caso vamos a aplicar la función sum.

aggregate(df_2$weight, by = list(df_2$feed, df_2$cat_var), FUN = sum)

# Equivalente a:
aggregate(weight ~ feed + cat_var, data = df_2, FUN = sum)
       feed   cat_var  weight
1     casein      A     1005
2  horsebean      A      532
3    linseed      A     1079
4   meatmeal      A      242
5    soybean      A     1738
6  sunflower      A      882
7     casein      B     1131
8  horsebean      B      494
9    linseed      B      780
10  meatmeal      B     2244
11   soybean      B     1355
12 sunflower      B     2109
13    casein      C     1747
14 horsebean      C      576
15   linseed      C      766
16  meatmeal      C      560
17   soybean      C      357
18 sunflower      C      956

Al aplicar la función aggregate para varias variables categóricas se realizan todas las posibles combinaciones entre ellas y se crea el resumen correspondiente a cada una.

Por otro lado, vamos a crear una nueva variable numérica llamada num_var.

set.seed(1)

num_var <- rnorm(nrow(df))

df_3 <- cbind(num_var, df)

head(df_3)
     num_var   weight      feed
1 -0.6264538    179    horsebean
2  0.1836433    160    horsebean
3 -0.8356286    136    horsebean
4  1.5952808    227    horsebean
5  0.3295078    217    horsebean
6 -0.8204684    168    horsebean

En este escenario, cuando trabajes con dos o más variables numéricas, puedes utilizar la función cbind para concatenarlas:

aggregate(cbind(df_3$num_var, df_3$weight), list(df_3$feed), mean)
    Group.1       V1       V2
1    casein   0.4043795  323.5833
2 horsebean   0.1322028  160.2000
3   linseed   0.3491303  218.7500
4  meatmeal   0.2125804  276.9091
5   soybean  -0.2314387  246.4286
6 sunflower   0.1651836  328.9167

De esta forma, se crea el resumen numérico para las variables numéricas en base al factor.

También podrías aplicar la función con múltiples variables numéricas y categóricas. En tal situación habría tantos resúmenes como variables numéricas y tantos grupos como posibles combinaciones.