2012-01-25 28 views
5

Estoy luchando con la transformación de un conjunto de datos de panel de formato ancho a largo. El conjunto de datos se ve así:Reformar formato ancho de datos de panel a formato largo

ID | KP1_430a | KP1_430b | KP1_430c | KP2_430a | KP2_430b | KP2_430c | KP1_1500a | ... 
1  .... 
2  .... 

KP1; KP2 hasta KP7 describe las olas. a, b hasta f describe un artículo específico. (Por ejemplo, de izquierda a derecha, colocación del Partido a)

Me gustaría tener estos datos en formato largo. De esta manera:

ID | Party | Wave | 430 | 1500 
1  1  1  .. .. 
1  2  1  .. .. 
.  .  .   
1  1  2  .. .. 
.  .  .   
2  1  1  .. .. 

He intentado utilizar la función de remodelación. Pero tuve problemas para remodelarlo con el tiempo y sobre las partes simultáneamente.

Aquí hay un pequeño ejemplo de data.frame.

data <- data.frame(matrix(rnorm(10),2,10)) 
data[,1] <- 1:2 
names(data) <- c("ID","KP1_430a" , "KP1_430b" , "KP1_430c" , "KP2_430a" , "KP2_430b ", "KP2_430c ", "KP1_1500a" ,"KP1_1500b", "KP1_1500c") 

Y esto es lo lejos que conseguí.

data_long <- reshape(data,varying=list(names(data)[2:4],names(data)[5:7], names(data[8:10]), 
          v.names=c("KP1_430","KP2_430","KP1_1500"), 
          direction="long", timevar="Party") 

La pregunta sigue siendo: ¿cómo puedo obtener las variables variables en tiempo en formato largo también? ¿Y hay una forma más elegante de remodelar esta información? En el código anterior, tendría que ingresar los nombres (nombres (datos) [2: 4]) para cada onda y variable. Con este pequeño data.frame está bien, pero el Dataset es mucho más grande.

EDITAR: Cómo se puede hacer esta transformación a mano: De hecho, he hecho esto, lo que me deja con un archivo de código de una página.
Primero, enlazar KP1_430a y KP1_1500a con IDs, Tiempo = 1 y Partido = 1 columna sabio. Segundo, crea el mismo objeto para todas las partes [b-f], cambiando el índice de la parte respectivamente, y añádelo en fila. Realice los pasos uno y dos para el resto de las ondas [2-7], respectivamente, cambiando el partido y la var del tiempo, y añádalos en filas.

+0

Si desea columnas separadas para 430 y 1500 en el formato largo, entonces debe haber una cantidad igual de datos de esas condiciones en el ancho. De la forma en que lo tienes, tendrías muchas NA en la columna de 1500 ... ¿o lo querías de esa manera? – John

+0

Oh, esto probablemente sea un poco incompleto. Hay la misma cantidad de ondas (1-7) y elementos de fiesta (a-f) para estas dos variables. Entonces: KP [1-7] _430 [a-f], KP [1-7] _1500 [a-f]. – lstoetze

+0

Sin embargo, para algunas variables en el conjunto de datos, hay (a) solo datos para algunas ondas, p. Ej. KP [146] _1640 [a-f] o (b) no es específico de una parte, p. KP [1-7] _1490. – lstoetze

Respuesta

4

lo general, es más fácil para proceder en dos pasos: primero use melt para poner sus datos en un formato "alto" (a menos que ya sea el caso) y luego use dcast para convertir ti a un formato más amplio.

library(reshape2) 
library(stringr) 

# Tall format 
d <- melt(data, id.vars="ID") 

# Process the column containing wave and party 
d1 <- str_match_all( 
    as.character(d$variable), 
    "KP([0-9])_([0-9]+)([a-z])" 
) 
d1 <- do.call(rbind, d1) 
d1 <- d1[,-1] 
colnames(d1) <- c("wave", "number", "party") 
d1 <- as.data.frame(d1) 
d <- cbind(d, d1) 

# Convert to the desired format 
d <- dcast(d, ID + wave + party ~ number) 
+0

¡Eso funciona! Estupendo. Gracias. – lstoetze

0

Por el momento, sus datos Wave están en sus nombres de variables y debe extraerlos con algún procesamiento de cadenas. No tuve ningún problema con la fusión

mdat <- melt(data, id.vars="ID") 
mdat$wave=sub("KP", "", sub("_.+$", "", mdat$variable)) # remove the other stuff 
mdat 

Su descripción es demasiado vaga (hasta ahora) para mí averiguar la regla para derivar una variable "Parte", por lo que quizás puede editar usted pregunta para mostrar la forma en que podría ser hecho por un ser humano ... y luego podemos mostrarle a la computadora cómo hacerlo.

EDIT: Si la última letra minúscula en los nombres de las columnas originales es Parte como piensa Vicente, entonces se podría recortar los espacios finales en los nombres y el extracto:

mdat$var <- sub("\\s", "", (as.character(mdat$variable))) 
mdat$party=substr(mdat$var, nchar(mdat$var), nchar(mdat$var)) 
#-------------- 
> mdat 
    ID variable  value wave party  var 
1 1 KP1_430a 0.7220627 1  a KP1_430a 
2 2 KP1_430a 0.9585243 1  a KP1_430a 
3 1 KP1_430b -1.2954671 1  b KP1_430b 
4 2 KP1_430b 0.3393617 1  b KP1_430b 
5 1 KP1_430c -1.1477627 1  c KP1_430c 
6 2 KP1_430c -1.0909179 1  c KP1_430c 
<snipped output> 
Cuestiones relacionadas