¿Cómo reorganizar y resumir todos tus datos en R?

¿Cómo reorganizar y resumir todos tus datos en R?

sep´21 Rosana Ferrero 0 comentarios

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

¹ Todos los campos son obligatorios.
² Tu correo electrónico no será publicado.

Nadie ha publicado ningún comentario aún. ¡Se tu la primera persona!

Te llamamos

Introduce los siguientes datos y nos pondremos en contacto contigo para atender tus dudas sin compromiso.

Te llamamos

Muchas gracias por solicitar información.
Te contactaremos lo antes posible.

Diseño web: Albin Soft.