¿Cómo reorganizar y resumir todos tus datos en R?
A menudo los datos no presentan el formato o estructura que necesitamos para nuestros análisis. En estos casos suele ser necesario reorganizar la forma de tus datos para su análisis, reteniendo todos los datos existentes, o agregándolos y resumiéndolos.La estructura general de una base de datos tiene las observaciones en las filas y variables en las columnas. Para reorganizar y resumir tus datos debemos dividir los tipos de variables en dos grupos: de identificación y variables medidas.
- Las variables de identificación (id) identifican la unidad en la que se realizan las mediciones. Las variables de Id suelen ser discretas y, por lo general, dependen del diseño de la investigación.
- Las variables medidas (Y), que representan lo que se mide en esa unidad o caso.
De esta forma, podemos crear nuevos formatos especificando qué variables deben formar las columnas y las filas.
Por ejemplo, podríamos reorganizar el siguiente conjunto de datos que describe a John y Mary Smith,y tiene dos variables de id (sujeto y tiempo) para que cada fila represente una observación de una variable.
> smiths subject time age weight height 1 John Smith 1 33 90 1.87 2 Mary Smith 1 NA NA 1.54
Podemos remodelar los datos para obtener una nueva variable de identificación llamada ‘variable’ y una nueva variable con las medidas llamada ‘valor’ donde se guarden las medidas tomadas para cada observación. Este sería el formato que buscamos:
subject time variable value John Smith 1 age 33.00 John Smith 1 weight 90.00 John Smith 1 height 1.87 Mary Smith 1 height 1.54
Ahora tenemos los datos en una forma en la que solo hay variables de id y una única columna de valor. A esta operación se llama fusión (melting).
¿Qué significa formato largo (long) y formato ancho (wide)?
Los datos en formato ancho tienen una columna para cada variable, mientras que en el formato largo cada fila es una combinación única de variable de identificación.
El formato largo es el más conveniente para filtrar y realizar algunos tipos de agregaciones, mientras que el formato ancho es típico de datos realizados en el tiempo.
Formato ancho: una columna para cada variable.
Formato largo: cada fila es una combinación única de variable de identificación.
Funciones en R
En R, hay una serie de funciones generales que pueden agregar datos, por ejemplo, tapply, by y aggregate, y una función específica para remodelar datos, reshape.Cada una de estas funciones tiende a funcionar bien con uno o dos escenarios específicos, y cada uno requiere argumentos de entrada ligeramente diferentes.Las funciones melt y cast del paquete reshape superan estos problemas con un marco conceptual general y son sencillas de manejar; fíjate en la siguiente figura para comprender las transformaciones que realizaremos.
Función melt
La función de fusión (“melt») nos permite pasar de un formato ancho a uno largo.Necesitamos indicar qué variables se miden y cuáles son de identificación.Los argumentos de la función son:
- data: Conjunto de datos para fundir
- id.vars: Variables de identificación (Id). Si está en blanco, usará todas las variables que no sean measure.vars. Puede ser un valor entero (posición variable) o cadena (nombre de la variable)
- measure.vars: Variables medidas Si está en blanco, usará todas las variables que no sean id.vars. Puede ser un valor entero (posición variable) o cadena (nombre de la variable)
- variable_name: Nombre de la variable que almacenará los nombres de las variables originales
- na.rm: ¿Deben eliminarse los valores de NA del conjunto de datos?
Esta función es «inteligente» y asume que cualquier variable de tipo factor o carácter es una variable “id” si no lo especificas tú explícitamente.Continuando con nuestro ejemplo, tenemos:
De wide a long
Recordemos los datos que tenemos:
> smiths subject time age weight height 1 John Smith 1 33 90 1.87 2 Mary Smith 1 NA NA 1.54
Por defecto la función melt genera el siguiente conjunto de datos en formato largo:
> long<- melt(smiths) Using subject as id variables > long subject variable value 1 John Smith time 1.00 2 Mary Smith time 1.00 3 John Smith age 33.00 4 Mary Smith age NA 5 John Smith weight 90.00 6 Mary Smith weight NA 7 John Smith height 1.87 8 Mary Smith height 1.54
Si queremos que la variable «time» se incluya como variable de identificación, junto al sujeto («subject») debemos especificar lo siguiente:
> long<- melt(smiths, id=c("subject","time")) > long subject time variable value 1 John Smith 1 age 33.00 2 Mary Smith 1 age NA 3 John Smith 1 weight 90.00 4 Mary Smith 1 weight NA 5 John Smith 1 height 1.87 6 Mary Smith 1 height 1.54
También podemos especificar que no considere los valores ausentes (NA).
> melt(smiths, id=c("subject","time"), na.rm=T) subject time variable value 1 John Smith 1 age 33.00 2 John Smith 1 weight 90.00 3 John Smith 1 height 1.87 4 Mary Smith 1 height 1.54
Función cast
La función de moldear (“cast») nos permite pasar de un formato largo a uno ancho.Los argumentos son:
- data: el conjunto de datos para utilizar.
- formula: si fuera necesario, con la fórmula de conversión describimos la forma del formato de salida (si omite este argumento, devolverá el marco de datos en la forma clásica con las variables medidas en las columnas y todas las demás variables de identificación en las filas).
- fun.aggregate (opcional): función de agregación para usar, si es necesario
- margins (opcional): ¿qué valores marginales se deben calcular?. Vector de nombres de variables (puede incluir «grand\ _col» y «grand\ _row») a calcular los márgenes, o TRUE para calcular todos los márgenes.
Otras opciones son:
- add.missing: ¿completar las combinaciones faltantes?
- value: nombre de la columna de valores
- subset: vector lógico del conjunto de datos del subconjunto antes de remodelar
- df: argumento utilizado internamente
- fill: valor con el que rellenar los valores perdidos.
Para especificar la fórmula ten en cuenta la forma básica columna_var1+columna_var2 ~ fila_var1 + fila_var2. Es decir, puedes especificar qué variable quieres que vaya en las columnas y cuáles en filas. Estas variables deben provenir del formato WIDE o de alguna de las siguientes opciones:
- “. ~ x” o “ x ~ .” Si quieres obtener una única fila o columna, respectivamente.
- “…” para representar todas las variables restantes.
Continuando con nuestro ejemplo:
De long a wide
Para volver a la organización original de los datos.
> cast(long) subject time age weight height 1 John Smith 1 33 90 1.87 2 Mary Smith 1 NA NA 1.54
Otra opción es ingresar las órdenes mediante fórmulas:
> cast(long, ... ~ time) subject variable 1 1 John Smith age 33.00 2 John Smith weight 90.00 3 John Smith height 1.87 4 Mary Smith height 1.54
Más ejemplos
Ejemplo 1. Datos de calidad de aire en el tiempo
Veamos el siguiente conjunto de datos con las mediciones diarias de la calidad del aire en Nueva York, de mayo a septiembre de 1973.
> head(airquality) 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
Queremos pasar al formato largo, por ejemplo para poder graficarlo con las funciones ggplot.
De wide a long
Mantenemos la información del mes y día como identificación de la observación y las demás variables las unificamos en una nueva columna.
> long<-melt(airquality, id=c("Month", "Day")) > head(long) 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
De long a wide
Por defecto (si no especificamos otra fórmula) se colocan las variables en columnas y datos en filas, volviendo a la distribución original.
> wide<-cast(long) > head(wide) 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
Si queremos realizar un resumen. En la fórmula ponemos la estructura de los datos que queremos obtener, en este caso queremos calcular la media de cada variable por mes:
> cast(long, Month ~ variable, mean) Month Ozone Solar.R Wind Temp 1 5 NA NA 11.622581 65.54839 2 6 NA 190.1667 10.266667 79.10000 3 7 NA 216.4839 8.941935 83.90323 4 8 NA NA 8.793548 83.96774 5 9 NA 167.4333 10.180000 76.90000
Ejemplo 2. Datos de pesos de pollos según la dieta
578 filas y 4 columnas de un experimento sobre el efecto de la dieta sobre el crecimiento temprano de los pollos.
> head(ChickWeight) Grouped Data: weight ~ Time | Chick weight Time Chick Diet 1 42 0 1 1 2 51 2 1 1 3 59 4 1 1 4 64 6 1 1 5 76 8 1 1 6 93 10 1 1
De wide a long
La información de identificación del experimento viene dada por las variables de las columnas 2 a 4, así que serán las que especifiquemos como «id”. Las demás variables respuesta se colocarán en una única columna y sus valores en otra. El resultado es prácticamente el mismo que teníamos al principio pero nos permitirá utilizar la función cast luego para realizar resúmenes por grupo.
> long<- melt(ChickWeight, id=2:4, na.rm=TRUE) > head(long) Time Chick Diet variable value 1 0 1 1 weight 42 2 2 1 1 weight 51 3 4 1 1 weight 59 4 6 1 1 weight 64 5 8 1 1 weight 76 6 10 1 1 weight 93
De long a wide
Media del peso de los pollos por dieta y tiempo.
> head(cast(long, Diet + Time ~ variable, mean)) Diet Time weight 1 1 0 41.40000 2 1 2 47.25000 3 1 4 56.47368 4 1 6 66.78947 5 1 8 79.68421 6 1 10 93.05263
Media del peso de los pollos por tiempo.
> head(cast(long, Time ~ variable, mean)) Time weight 1 0 41.06000 2 2 49.22000 3 4 59.95918 4 6 74.30612 5 8 91.24490 6 10 107.83673
Ejemplo 3. Datos de bares por meses
Un camarero registró información sobre cada consejo que recibió durante un período de unos meses trabajando en un restaurante. Recolectó varias variables:propina en dólares, factura en dólares, sexo del pagador de facturas, si había fumadores en la fiesta, día de la semana, hora del día, tamaño de la fiesta.En total, registró 244 consejos. Los datos se informaron en una colección de estudios de casos para estadísticas comerciales (Bryant y Smith 1995).
> head(tips) total_bill tip sex smoker day time size 1 16.99 1.01 Female No Sun Dinner 2 2 10.34 1.66 Male No Sun Dinner 3 3 21.01 3.50 Male No Sun Dinner 3 4 23.68 3.31 Male No Sun Dinner 2 5 24.59 3.61 Female No Sun Dinner 4 6 25.29 4.71 Male No Sun Dinner 4
De wide a long
La información de identificación del cada evento viene dada por las variables de las columnas «day» y «time», así que serán las que especifiquemos como «id”. Las demás variables respuesta se colocarán en una única columna y sus valores en otra.
> long<-melt(tips, id=c("day","time"))
Using sex, smoker, day, time as id variables > head(long) day time variable value 1 Sun Dinner total_bill 16.99 2 Sun Dinner total_bill 10.34 3 Sun Dinner total_bill 21.01 4 Sun Dinner total_bill 23.68 5 Sun Dinner total_bill 24.59 6 Sun Dinner total_bill 25.29
De long a wide
> wide<-cast(long) Aggregation requires fun.aggregate: length used as default > head(wide) Aggregation requires fun.aggregate: length used as default day time total_bill tip sex smoker size 1 Fri Dinner 12 12 12 12 12 2 Fri Lunch 7 7 7 7 7 3 Sat Dinner 87 87 87 87 87 4 Sun Dinner 76 76 76 76 76 5 Thur Dinner 1 1 1 1 1 6 Thur Lunch 61 61 61 61 61
Si queremos realizar un resumen.
En la fórmula ponemos la estructura de los datos que queremos obtener, en este caso queremos realizar una tabla de sexo por tipo de fumador (No & Yes), donde calcular la media para cada variable. Utilizamos el operador “|” para crear una lista por variable:
> cast(wide, sex ~ smoker | variable, mean) Using sex, smoker, day, time as id variables $total_bill sex No Yes 1 Female 18.10519 17.97788 2 Male 19.79124 22.28450 $tip sex No Yes 1 Female 2.773519 2.931515 2 Male 3.113402 3.051167 $size sex No Yes 1 Female 2.592593 2.242424 2 Male 2.711340 2.500000
Si buscamos el resultado solo para la variable “total_bill»:
> cast(wide, sex ~ smoker, mean, subset=variable=="total_bill") Using sex, smoker, day, time as id variables sex No Yes 1 Female 18.10519 17.97788 2 Male 19.79124 22.28450
Ejemplo 4. Datos sensoriales de un experimento de papas fritas
Estos datos provienen de un experimento sensorial que investiga el efecto de diferentes aceites para freír sobre el sabor de las papas fritas a lo largo del tiempo. Hay tres tipos diferentes de aceites para freír (tratamiento), cada uno en dos freidoras diferentes (rep), probados por 12 personas (sujeto) en 10 días diferentes (tiempo). Los atributos sensoriales registrados, en orden de conveniencia, son sabores a base de patata, manteca, hierba, rancio y sabor extraño.
> head(french_fries)
time treatment subject rep potato buttery grassy rancid painty 61 1 1 3 1 2.9 0.0 0.0 0.0 5.5 25 1 1 3 2 14.0 0.0 0.0 1.1 0.0 62 1 1 10 1 11.0 6.4 0.0 0.0 0.0 26 1 1 10 2 9.9 5.9 2.9 2.2 0.0 63 1 1 15 1 1.2 0.1 0.0 1.1 5.1 27 1 1 15 2 8.8 3.0 3.6 1.5 2.3
De wide a long
La información de identificación del experimento viene dada por las variables de las columnas 1 a 4, así que serán las que especifiquemos como "id”. Las demás variables respuesta se colocarán en una única columna y sus valores en otra.
> long <- melt(french_fries, id=1:4, na.rm=TRUE) > head(long) time treatment subject rep variable value 1 1 1 3 1 potato 2.9 2 1 1 3 2 potato 14.0 3 1 1 10 1 potato 11.0 4 1 1 10 2 potato 9.9 5 1 1 15 1 potato 1.2 6 1 1 15 2 potato 8.8
De long a wide
Para volver a la organización original de los datos.
> wide<-cast(long) > head(wide) time treatment subject rep potato buttery grassy rancid painty 1 1 1 3 1 2.9 0.0 0.0 0.0 5.5 2 1 1 3 2 14.0 0.0 0.0 1.1 0.0 3 1 1 10 1 11.0 6.4 0.0 0.0 0.0 4 1 1 10 2 9.9 5.9 2.9 2.2 0.0 5 1 1 15 1 1.2 0.1 0.0 1.1 5.1 6 1 1 15 2 8.8 3.0 3.6 1.5 2.3
Si queremos realizar un resumen.
Calcular la media para cada variable:
> cast(long, variable ~ ., mean) variable (all) 1 potato 6.9525180 2 buttery 1.8236994 3 grassy 0.6641727 4 rancid 3.8522302 5 painty 2.5217579
Si queremos saber cuántas observaciones tenemos por tratamiento y réplica:
> cast(long, treatment ~ rep, length) treatment 1 2 1 1 579 580 2 2 578 579 3 3 575 580
> cast(long, treatment + rep ~ ., length) treatment rep (all) 1 1 1 579 2 1 2 580 3 2 1 578 4 2 2 579 5 3 1 575 6 3 2 580
Si queremos obtener la media de cada variable por tratamiento:
> cast(long, treatment ~ variable, mean) treatment potato buttery grassy rancid painty 1 1 6.887931 1.780087 0.6491379 4.065517 2.583621 2 2 7.001724 1.973913 0.6629310 3.624569 2.455844 3 3 6.967965 1.717749 0.6805195 3.866667 2.525541
Referencias
- Wickham, Hadley (2007) Reshaping Data with the reshape Package. Journal of Statistical Software. 21(12).
- Puedes encontrar más ejemplos si pides ayuda en R: ?melt y ?cast
- También tienes más información aquí http://had.co.nz/reshape/
0 comentarios
Nadie ha publicado ningún comentario aún. ¡Se tu la primera persona!