¿Cómo pivotar/no dividir(lanzar/fundir) el marco de datos?
pivot-table reshape (3)
Esta pregunta ya tiene una respuesta aquí:
- Reformando data.frame de formato ancho a largo 5 respuestas
¿Cómo puedo ''separar'' una tabla? ¿Cuál es el término técnico adecuado para esto?
ACTUALIZACIÓN: El término se llama derretir.
Tengo un marco de datos para países y datos para cada año.
Country 2001 2002 2003
Nigeria 1 2 3
UK 2 NA 1
Y quiero tener algo como
Country Year Value
Nigeria 2001 1
Nigeria 2002 2
Nigeria 2003 3
UK 2001 2
UK 2002 NA
UK 2003 1
El enfoque de reshape
base R para este problema es bastante feo, particularmente porque los nombres no están en una forma que a la reshape
le guste. Sería algo como lo siguiente, donde la primera línea de setNames
modifica los nombres de las columnas en algo que la reshape
puede usar.
reshape(
setNames(mydf, c("Country", paste0("val.", c(2001, 2002, 2003)))),
direction = "long", idvar = "Country", varying = 2:ncol(mydf),
sep = ".", new.row.names = seq_len(prod(dim(mydf[-1]))))
Una mejor alternativa en la base R es usar la stack
, como esta:
cbind(mydf[1], stack(mydf[-1]))
# Country values ind
# 1 Nigeria 1 2001
# 2 UK 2 2001
# 3 Nigeria 2 2002
# 4 UK NA 2002
# 5 Nigeria 3 2003
# 6 UK 1 2003
También hay nuevas herramientas para remodelar los datos disponibles, como el paquete "tidyr", que nos permite reunirnos. Por supuesto, el método tidyr:::gather_.data.frame
simplemente llama a reshape2::melt
, por lo que esta parte de mi respuesta no necesariamente agrega mucho, excepto la introducción de la sintaxis más nueva que puede encontrar en el Hadleyverse.
library(tidyr)
gather(mydf, year, value, `2001`:`2003`) ## Note the backticks
# Country year value
# 1 Nigeria 2001 1
# 2 UK 2001 2
# 3 Nigeria 2002 2
# 4 UK 2002 NA
# 5 Nigeria 2003 3
# 6 UK 2003 1
Las tres opciones aquí necesitarían reordenación de filas si desea el orden de fila que mostró en su pregunta.
Una cuarta opción sería usar merged.stack
de mi paquete "splitstackshape". Al igual que la reshape
la base R, deberá modificar los nombres de las columnas a algo que incluya un indicador de "variable" y "tiempo".
library(splitstackshape)
merged.stack(
setNames(mydf, c("Country", paste0("V.", 2001:2003))),
var.stubs = "V", sep = ".")
# Country .time_1 V
# 1: Nigeria 2001 1
# 2: Nigeria 2002 2
# 3: Nigeria 2003 3
# 4: UK 2001 2
# 5: UK 2002 NA
# 6: UK 2003 1
Data de muestra
mydf <- structure(list(Country = c("Nigeria", "UK"), `2001` = 1:2, `2002` = c(2L,
NA), `2003` = c(3L, 1L)), .Names = c("Country", "2001", "2002",
"2003"), row.names = 1:2, class = "data.frame")
Puede utilizar el comando de melt
del paquete de reshape
. Consulte aquí: http://www.statmethods.net/management/reshape.html
Probablemente algo como melt(myframe, id=c(''Country''))
Todavía no puedo creer que le gané a Andrie con una respuesta. :)
> library(reshape)
> my.df <- read.table(text = "Country 2001 2002 2003
+ Nigeria 1 2 3
+ UK 2 NA 1", header = TRUE)
> my.result <- melt(my.df, id = c("Country"))
> my.result[order(my.result$Country),]
Country variable value
1 Nigeria X2001 1
3 Nigeria X2002 2
5 Nigeria X2003 3
2 UK X2001 2
4 UK X2002 NA
6 UK X2003 1