Una Introducción a ReShape2

ReShape2 Es un paquete de R que facilita transformación de datos entre los formatos Ancho y Largo.

Por comodidad con la sintaxis del resto de comandos usaremos los nombres Wide & Long.

Y para los futuros ejemplos trabajaremos con el conjunto de datos (dataset) que tiene R integrado llamado airquality

Instalación del paquete ReShape2

Con tan solo escribir en nuestra consola lo siguiente empezaría la instalación install.packages(“reshape2”) Una vez instalado, cada vez que querramos usarlo tenemos que cargarlo en el script con:

library(“reshape2”)

¿Que hace que los datos estén en formato Wide o Long?

Los datos en formato Wide, tienen una columna para cada variable.

Por ejemplo, estos son datos en formato Wide:

##   Ozone Solar.R Wind Temp Month Day
## 1    41     190  7.4   67     5   1
## 2    36     118  8.0   72     5   2
## 3    12     149 12.6   74     5   3
## 4    18     313 11.5   62     5   4
## 5    NA      NA 14.3   56     5   5
## 6    28      NA 14.9   66     5   6

Y estos datos en formato Long:

##    variable value
## 1     Ozone    41
## 2     Ozone    36
## 3     Ozone    12
## 4     Ozone    18
## 5     Ozone    NA
## 6     Ozone    28
## 7   Solar.R   190
## 8   Solar.R   118
## 9   Solar.R   149
## 10  Solar.R   313
## 11  Solar.R    NA
## 12  Solar.R    NA

El formato de datos Long, tiene una columna para los posibles tipos de variables y otra columna para los valores de esas variables. El formato de datos Long no necesariamente tiene solo dos columnas, algunas veces nos hará falta otra columna dependiendo de lo que hagamos, en otras palabras, podemos tener diferentes “niveles” de formato largo.

En la mayoría de tipos analisis de datos se usará el formato de datos Long, pero el formato Wide suele ser más fácil para el almacenamiento de datos.

El paquete ReShape2

ReShape2 está basado en dos funciones clave: melt y cast:

melt Coge los datos en formato Wide y los funde convirtiendolos al formato Long.

cast Coge los datos en formato Long y los fusiona convirtiendolos al formato Wide.

Del formato de datos Wide al Long: Función “melt”

Para este ejemplo, cambiaremos los nombres de las columnas del conjunto de datos airquality y los pondremos en minúsculas para que se nos haga más fácil trabajar con ellos.

names(airquality) <- tolower(names(airquality))
head(airquality) ## el comando head, nos devuelve solo las primeras filas
##   ozone solar.r wind temp month day
## 1    41     190  7.4   67     5   1
## 2    36     118  8.0   72     5   2
## 3    12     149 12.6   74     5   3
## 4    18     313 11.5   62     5   4
## 5    NA      NA 14.3   56     5   5
## 6    28      NA 14.9   66     5   6

¿ Que pasa si corremos la función melt con todos los argumentos por defecto?

aql <- melt(airquality)
head(aql)
##   variable value
## 1    ozone    41
## 2    ozone    36
## 3    ozone    12
## 4    ozone    18
## 5    ozone    NA
## 6    ozone    28
tail(aql) ## el comando tail, nos devuelve solo las ultimas filas
##     variable value
## 913      day    25
## 914      day    26
## 915      day    27
## 916      day    28
## 917      day    29
## 918      day    30

Por defecto, melt asume que todas las columnas con vaores numericos son variables con valores, Mayormente es lo que querremos, pero tal vez aquí nos insteresaría conocer los valores de ozone, solar.r, wind y temp por cada month y day, entonces podríamos usar melt diciendole que queremos a mont y a day que sean “ID Variables”. las ID variables, son variables que identifican filas individuales de datos.

aql <- melt(airquality, id.vars = c("month", "day"))
head(aql)
##   month day variable value
## 1     5   1    ozone    41
## 2     5   2    ozone    36
## 3     5   3    ozone    12
## 4     5   4    ozone    18
## 5     5   5    ozone    NA
## 6     5   6    ozone    28

¿Qué pasa si queremos controlar tambien los nombres de las columnas de nuestros datos en formato Long?

melt nos permite establecerlos en un solo paso:

aql <- melt(airquality, id.vars = c("month", "day"),
  variable.name = "climate_variable",
  value.name = "climate_value")
head(aql)
##   month day climate_variable climate_value
## 1     5   1            ozone            41
## 2     5   2            ozone            36
## 3     5   3            ozone            12
## 4     5   4            ozone            18
## 5     5   5            ozone            NA
## 6     5   6            ozone            28

Del formato de datos Long al Wide: Función “cast”

Mientras que del formato Wide al Long es bastante sencillo, ir del formato Long al Wide, puede costarnos un poco más.

En reshape2 hay multiples funciones cast. Y ya que es más común trabajar con objetos data.frame, entonces usaremos la función dcast

Cojamos los datos que están en formato Long del dataset airquality y fusionemoslo en distintos formatos Wide, empecemos recuperando el mismo formato con el que empezamos y comparemoslas.

dcast Usa “Formulas” para describir la “forma” de los datos.

No vamos a entrar en la definición de fórmula, pero básicamente nos sirven para hacer una regresión lineal de unas variables a otra/s

Ejemplo: Si en el ejemplo usamos la formula month + day ~ variable, una manera sencilla de entenderlo, es que vamos a usar como medida a “variable” para obtener a las Variables ID “month y day”

Los argumentos en la izquierda son las variables ID y los de la derecha los de medida.

Lo que queremos es decirle a dcast que month y day son Variables ID (queremos una columna para cada una), y que variable describe las variables de medida. Ya que no hay otra columna, dcat se va a dar cuenta solo de que contiene los mismos valores. Tambien podriamos declararlo en el value.var (En algunos casos será necesario hacerlo)

aql <- melt(airquality, id.vars = c("month", "day"))
aqw <- dcast(aql, formula = month + day ~ variable)
head(aqw)
##   month day ozone solar.r wind temp
## 1     5   1    41     190  7.4   67
## 2     5   2    36     118  8.0   72
## 3     5   3    12     149 12.6   74
## 4     5   4    18     313 11.5   62
## 5     5   5    NA      NA 14.3   56
## 6     5   6    28      NA 14.9   66
head(airquality) #datos originales
##   ozone solar.r wind temp month day
## 1    41     190  7.4   67     5   1
## 2    36     118  8.0   72     5   2
## 3    12     149 12.6   74     5   3
## 4    18     313 11.5   62     5   4
## 5    NA      NA 14.3   56     5   5
## 6    28      NA 14.9   66     5   6

Aparte de que las columnas no están ordenadas de la misma forma, hemos recuperado nuestros datos originales.

Un “Error” confuso que podría pasarnos, es querer fusionar el dataset habiendo más de un valor por celda.

Para este ejemplo no incluiremos day como una variable ID en nuestra formula.

dcast(aql,month ~ variable)
##   month ozone solar.r wind temp
## 1     5    31      31   31   31
## 2     6    30      30   30   30
## 3     7    31      31   31   31
## 4     8    31      31   31   31
## 5     9    30      30   30   30

Vemos que nos aparece el mensaje

## Aggregation function missing: defaulting to length

Y echamos un vistazo a la salida, vemos que las celdas están rellenadas con el número de filas de dato por cada combinación de month-climate. Los números que estamos viendo son el número de días registrados en cada mes. Así que cada vez que fusionemos nuestros datos, habrán múltiples valores por celda, y es por ello que necesitaremos decirle a dcast como queremos agregar los datos.

Por ejemplo, tal vez querramos usar las medias de esos datos (mean) o la mediana (median) o la suma (suma).

probemos el último ejemplo, pero esta vez usaremos la media de los climate_values. Será necesario tambien indicar la opción na.rm=TRUE en los argumentos, para que la media se pueda hacer correctamente.

dcast(aql,month ~ variable, fun.aggregate = mean, na.rm = TRUE)
##   month    ozone  solar.r      wind     temp
## 1     5 23.61538 181.2963 11.622581 65.54839
## 2     6 29.44444 190.1667 10.266667 79.10000
## 3     7 59.11538 216.4839  8.941935 83.90323
## 4     8 59.96154 171.8571  8.793548 83.96774
## 5     9 31.44828 167.4333 10.180000 76.90000

Como hemos podido apreciar, a diferencia de la función melt, la función dcast permite hacer más transformaciones de datos.

Ayuda adicional

Leer la ayuda del paquete

help(package = "reshape2")

Página web de reshape2 (en inglés) ReShape2