11.1 Resúmenes de datos por bloques

Comenzaremos por cargando el paquete (y tendrás que instalarlo si no lo has hecho ya) y leer unos datos de ejemplo:

library(plyr)
paro <- read.table("data/paro.csv", header = T, sep = "\t")

La función fundamental del paquete plyr es ddply que, típicamente, se invoca así:

res <- ddply(paro, .(Gender, Periodo, Situation), summarize, total = sum(value))

La tabla resultante contiene el número de españoles (en miles) por sexo, periodo y situación laboral agregando los valores correspondientes a todas las provincias.

Los elementos que componen la expresión anterior son:

  • ddply: es una función que transforma una tabla en otra tabla; de hecho, ddply siempre opera sobre tablas y siempre devuelve tablas.
  • paro: la tabla sobre la que opera.
  • .(Gender, Periodo, Situation): variales de la tabla de entrada cuyos niveles definen los trozos sobre los que se opera individualmente. La tabla de entrada se parte en tantas subtablas como combinaciones distintas de valores de Gender, Periodo y Situation existan.
  • summarize: una función que opera sobre tablas y devuelve tablas; veremos después ejemplos de otras funciones que pueden usarse en su lugar.
  • total = ...: argumentos de la función anterior. Igual que ocurría con tapply, los argumentos que siguen a la función anterior se aplican a ddply sino sobre aquella.

La función ddply encuentra las subtablas que definen los niveles distintos de las variables indicadas en el segundo argumento y se las pasa una a una a la función que indica el tercer argumento. Esta función opera sobre cada uno de los trozos por separado y, finalmente, ddply apila los resultados en una única tabla final.

ddply es otro ejemplo de una función de orden superior. Anteriormente habíamos introducido tapply, que es similar pero mucho menos potente: tapply opera solo sobre vectores, pero ddply admite tablas como argumentos.

La función summarize es muy simple: aplicada sobre una tabla, devuelve otra con una única fila que contiene los resúmenes (medias, etc.) que se le pasan como argumentos adicionales. Por ejemplo,

summarize(iris, media.pl = mean(Petal.Length), media.pw = mean(Petal.Width))
##   media.pl media.pw
## 1    3.758 1.199333

devuelve las longitudes y anchuras medias de los pétalos de iris. Por sí sola, tal y como ilustra el ejemplo anterior, summarize no es una función particularmente útil. Pero en combinación con ddply sirve para implementar lo equivalente a los group by de SQL. Si quisiéramos realizar esta operación por especies, podríamos envolver la expresión anterior en una llamada a ddply así:

ddply(iris, .(Species), summarize, media.pl = mean(Petal.Length), media.pw = mean(Petal.Width))
##      Species media.pl media.pw
## 1     setosa    1.462    0.246
## 2 versicolor    4.260    1.326
## 3  virginica    5.552    2.026

Usa summarize para calcular la media y la mediana de la temperatura en airquality.

Dispón airquality en formato largo y extrae la media y la mediana de cada variable por mes.

La función summarize no es, por supuesto, la única que admite ddply; le vale cualquier función que reciba una tabla y devuelva otra. Por ejemplo,

foo <- function(x) lm(Temp ~ Solar.R, data = x)$coefficients
ddply(airquality, .(Month), foo)
##   Month (Intercept)    Solar.R
## 1     5    61.08143 0.02651712
## 2     6    73.64522 0.02868418
## 3     7    80.18086 0.01719467
## 4     8    77.68639 0.03528288
## 5     9    74.72485 0.01299114

crea una regresión lineal que modela la temperatura en función de la irradiación solar para cada mes y devuelve los coeficientes de dichos modelos en una tabla. Dentro de la expresión anterior hemos creado una función, foo, que toma unos datos, construye una regresión lineal con ellos y devuelve los coeficientes del modelo; ddply permite aplicar esa función a los subconjuntos de airquality correspondientes a cada uno de los meses de los que contiene datos.

Usa ddply para crear la tabla que en SQL se construiría de la forma select Species, mean(Petal.Length) from iris group by Species.

Carga el conjunto de datos lmm_data.txt y calcula el valor medio de las variables numéricas del fichero por colegio y clase.

Repite el ejercicio anterior pero disponiendo previamente los datos en formato largo (usa la función melt del paquete reshape2).

Obtén las tres filas de iris correspondientes a las observaciones de con la mayor longitud del pétalo dentro de cada especie. Pista: puedes crear una función que ordene una tabla por una columna y luego seleccione su primera fila.