8.2 La función dcast y datos en formato ancho

A partir del formato largo se puede pasar a distintos tipos de formatos no largos (o anchos) usando la función dcast. Por ejemplo, a partir de los datos

pob.aragon.2014.largo <- melt(pob.aragon.2014)
pob.aragon.2014.largo
##   Provincia variable  value
## 1    Huesca  Hombres 113840
## 2    Teruel  Hombres  71449
## 3  Zaragoza  Hombres 471675
## 4    Huesca  Mujeres 111069
## 5    Teruel  Mujeres  68916
## 6  Zaragoza  Mujeres 488436

se pueden poner las pronvicias en filas

dcast(pob.aragon.2014.largo, Provincia ~ variable)
##   Provincia Hombres Mujeres
## 1    Huesca  113840  111069
## 2    Teruel   71449   68916
## 3  Zaragoza  471675  488436

o en columnas:

dcast(pob.aragon.2014.largo, variable ~ Provincia)
##   variable Huesca Teruel Zaragoza
## 1  Hombres 113840  71449   471675
## 2  Mujeres 111069  68916   488436

En su versión más simple, dcast necesita:

  • la tabla sobre la que operar
  • qué columnas disponer en filas (generalmente varias, separadas por +, delante de ~)
  • qué columnas disponer en columnas (generalmente una, detrás de ~)

La función dcast utiliza una serie de reglas simples para determinar cuál es la columna de la que extraer los datos que incluir en la tabla resultante. Pero, a veces, como en el ejemplo que sigue, se equivoca. Por ejemplo, vamos a intentar medir el incremento en las horas de sueño (extra) producidas por el tratamiento (o group) 2 sobre el 1 en el conjunto de datos sleep. Este conjunto de datos se refiere a individuos (ID) que fueron sometidos a dos tratamientos distintos. Podemos hacer

dcast(sleep, ID ~ group)
## Using ID as value column: use value.var to override.
##    ID  1  2
## 1   1  1  1
## 2   2  2  2
## 3   3  3  3
## 4   4  4  4
## 5   5  5  5
## 6   6  6  6
## 7   7  7  7
## 8   8  8  8
## 9   9  9  9
## 10 10 10 10

para intentar colocar los dos valores correspondientes a cada individuo en la misma fila para poder restarlos después. Sin embargo, el efecto no es el deseado y el warning de R es muy informativo sobre el problema: que dcast ha elegido como variable de valor ID en lugar de extra. Además, indica cómo forzar una alternativa a la que usa por defecto, i.e., usando value.var:

dcast(sleep, ID ~ group, value.var = "extra")
##    ID    1    2
## 1   1  0.7  1.9
## 2   2 -1.6  0.8
## 3   3 -0.2  1.1
## 4   4 -1.2  0.1
## 5   5 -0.1 -0.1
## 6   6  3.4  4.4
## 7   7  3.7  5.5
## 8   8  0.8  1.6
## 9   9  0.0  4.6
## 10 10  2.0  3.4

Ahora es posible añadir la columna adicional de interés haciendo

tmp <- dcast(sleep, ID ~ group, value.var = "extra")
tmp$diff <- tmp[, "2"] - tmp[, "1"]
head(tmp, 3)
##   ID    1   2 diff
## 1  1  0.7 1.9  1.2
## 2  2 -1.6 0.8  2.4
## 3  3 -0.2 1.1  1.3

as.data.frame(Titanic) es una tabla en formato largo que contiene información sobre los viajeros que sobrevivieron o perecieron el naufragio del Titanic. Calcula la proporción de viajeros que sobrevivieron por clase, sexo y grupo de edad. Nota: recuerda que para indicar varias filas, ya sea en filas o columnas (aunque lo segundo no se recomienda), los nombres de columna tienen que indicarse separados del signo +.

No obstante, al usar dcast pueden ocurrir situaciones como que ilustra el ejemplo siguiente. En primer lugar construimos una versión larga de iris:

iris.long <- melt(iris)
head(iris.long, 4)
##   Species     variable value
## 1  setosa Sepal.Length   5.1
## 2  setosa Sepal.Length   4.9
## 3  setosa Sepal.Length   4.7
## 4  setosa Sepal.Length   4.6

Hemos hecho la operación melt(iris) para crear un conjunto de datos de práctica. Sin embargo, en esta operación se pierde información: ya no sabemos a qué fila de la tabla original corresponden las de la versiòn arreglada. Por lo tanto, la reconstrucción de los datos originales es imposible.

Ahora, al hacer

dcast(iris.long, Species ~ variable)    
## Aggregation function missing: defaulting to length
##      Species Sepal.Length Sepal.Width Petal.Length Petal.Width
## 1     setosa           50          50           50          50
## 2 versicolor           50          50           50          50
## 3  virginica           50          50           50          50

obtenemos un resultado extraño (además de un warning). Se debe a que en cada posición de la tabla resultante hay más de un valor candidato; de hecho, 50 de ellos. La función dcast, por defecto, combina esos valores usando la función length. Sin embargo, es posible especificar otras:

dcast(iris.long, Species ~ variable, fun.aggregate = mean) 
##      Species Sepal.Length Sepal.Width Petal.Length Petal.Width
## 1     setosa        5.006       3.428        1.462       0.246
## 2 versicolor        5.936       2.770        4.260       1.326
## 3  virginica        6.588       2.974        5.552       2.026

La función dcast admite otras invocaciones equivalentes. Por ejemplo, como hemos visto más arriba, se puede especificar explícitamente la variable sobre la que opera la nueva función:

dcast(iris.long, Species ~ variable, fun.aggregate = mean, value.var = "value")  

No obstante, la opción más sucinta es

dcast(iris.long, Species ~ variable, mean)  

Calcula la media de cada variable meteorológica de airquality por mes.

Para los ejercicios siguientes vamos a utilizar una tabla descargada del INE que contiene información sobre la situación laboral de los ciudadanos de todas las provincias de España por periodo, provincia y sexo.

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

Los valores que aparecen en la tabla son valores absolutos: es el número de personas en miles.

Los datos están en formato largo, pero se pueden pivotar, p.e., así:

paro.alt <- dcast(paro, Gender + Provinces + Periodo ~ Situation)

Añade a paro.alt una columna adicional con la tasa de paro (desempleados entre población activa).

El ejercicio anterior demuestra cómo en ocasiones es conveniente crear un determinado tipo de formato ancho para operar sobre los datos más fácilmente. En concreto, para colocar en la misma fila valores sobre los que realizar operaciones; en nuestro caso, un cociente.

Identifica las provincias y periodos en los que la tasa de paro masculina supera a la femenina.

Si se utilizan todas las variables que forman parte de la clave de una tabla en la fórmula de dcast, en cada casilla de la tabla resultante aparece una única observación. Si se omite una o más, comienzan a aparecer valores repetidos y eso permite utilizar funciones de agregación para realizar operaciones similares a un group by de SQL.

Obtén totales para toda España (i.e., ignorando la provincia y el sexo) usando dcast.

No obstante, en una sección posterior veremos una manera alternativa, la recomendada, para realizar este tipo de agregaciones.