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 deGender
,Periodo
ySituation
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 contapply
, los argumentos que siguen a la función anterior se aplican addply
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.