r pivot-table reshape reshape2

¿Cómo pivotar/no dividir(lanzar/fundir) el marco de datos?



pivot-table reshape (3)

Esta pregunta ya tiene una respuesta aquí:

¿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")



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