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
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
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
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
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