2015-11-11

Convertir de formato largo a ancho usando una función de agregación en R

Title

Problema

Deseamos transformar un data frame de formato largo a ancho agrupando por la suma de los valores de una de las variables. Es decir pasar de esta tabla,

 V1 V3     V2
1  5 10    low
2  5  3    low
3  5  6 medium
4 45 10    low
5 45  3    low
6 77  1   high

A esta otra, donde mantenemos la columna V1, la columna V2 contiene los nombres de las nuevas columnas, y la columna V3 será la variable que almacenará los valores y que agregaremos sumando.

  V1 low medium high
1  5  13      6    0
2 45  13      0    0
3 77   0      0    1

  • Datos originales
  • V1 <- c(5,5,5,45,45,77)  
    V2 <- c("low", "low", "medium", "low", "low", "high")  
    V3 <- c(10,3,6,10,3,1)  
    df <- as.data.frame(cbind(V1,V3,V2))
    

    Soluciones

    Primero examinamos el data frame que nos dieron.

    str(df)
    'data.frame': 6 obs. of  3 variables:
     $ V1: Factor w/ 3 levels "45","5","77": 2 2 2 1 1 3
     $ V3: Factor w/ 4 levels "1","10","3","6": 2 3 4 2 3 1
     $ V2: Factor w/ 3 levels "high","low","medium": 2 2 3 2 2 1
    

    Las columnas V1 y V3 se han convertido en factores, cuando deberían ser númericas. Si utilizáramos cualquier código obtendríamos el error: Error: ‘sum’ not meaningful for factors. Para solucionarlo, empleamos el siguiente código:

    df <- cbind.data.frame(V1,V3,V2)
    str(df)
    'data.frame': 6 obs. of  3 variables:
     $ V1: num  5 5 5 45 45 77
     $ V3: num  10 3 6 10 3 1
     $ V2: Factor w/ 3 levels "high","low","medium": 2 2 3 2 2 1
    

  • reshape2
  • Empleamos dcast para crear un data frame, usando V3 como la variable valores, e indicamos como función de agregación la suma (sum).

    library(reshape2)
    dcast(df, V1  ~ V2, value.var="V3", fun = sum)
    
      V1 high low medium
    1  5    0  13      6
    2 45    0  13      0
    3 77    1   0      0
    

    Como se puede observar, ordenado las columnas alfabéticamente (high, low y medium) en lugar de respetar el orden de ocurrencia original: low, medium, high.

    dcast(df, V1  ~ factor(V2, levels = unique(V2)), value.var = "V3", sum)
    
    'data.frame': 6 obs. of  3 variables:
     $ V1: num  5 5 5 45 45 77
     $ V3: num  10 3 6 10 3 1
     $ V2: Factor w/ 3 levels "high","low","medium": 2 2 3 2 2 1
    

  • paquete base
  • Empleamos la función xtabs para crear una tabla de contingencia mediante el formato fórmula.

    xtabs(V3 ~ V1 + V2, df)
    
        V2
    V1   high low medium
      5     0  13      6
      45    0  13      0
      77    1   0      0
    

    xtabs(V3 ~ V1 + factor(V2, c("low", "medium", "high")), df)
    
       factor(V2, c("low", "medium", "high"))
    V1   low medium high
      5   13      6    0
      45  13      0    0
      77   0      0    1
    

  • dplyr y tidyr
  • Con dplyr con la función spread, el equivalente a dcast en reshape2.

    df$V2 <- factor(df$V2, levels = c("low", "medium", "high"))
    
    library(tidyr)# Función spread
    library(dplyr)
    
    df %>%
      group_by(V1, V2) %>%
      summarise(sum = sum(V3)) %>%
      spread(V2, sum, fill = 0)
    
    Source: local data frame [3 x 4]
    
         V1   low medium  high
      (dbl) (dbl)  (dbl) (dbl)
    1     5    13      6     0
    2    45    13      0     0
    3    77     0      0     1
    

    Entradas relacionadas

    Referencias

    No hay comentarios:

    Publicar un comentario

    Nube de datos