2012-01-25 17 views
5

Sono in difficoltà con la trasformazione di un set di dati del pannello dal formato ampio a quello lungo. Il set di dati è simile al seguente:Reshape Panel Data Wide Format to Long Format

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

KP1; KP2 fino a KP7 descrivono le onde. a, b fino a f descrivono un articolo specifico. (Posizionamento da sinistra a destra a destra del partito a)

Mi piacerebbe avere questi dati nel formato lungo. In questo modo:

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

Ho provato a utilizzare la funzione di risagoma. Ma ho avuto problemi a rimodellarlo nel tempo e sulle parti contemporaneamente.

Ecco un piccolo esempio di 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") 

E questo è quanto ho ottenuto.

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 domanda rimane: come posso ottenere il tempo variabili variabili anche nel formato lungo? E c'è un modo più elegante per rimodellare questi dati? Nel codice sopra dovrei inserire i nomi (nomi (dati) [2: 4]) per ogni onda e variabile. Con questo piccolo data.frame è Ok, ma il Dataset è molto più grande.

EDIT: Come questa trasformazione potrebbe essere eseguita a mano: in realtà ho fatto questo, che mi lascia con un file di codice lungo una pagina.
Innanzitutto, associare KP1_430a e KP1_1500a con ID, Tempo = 1 e Parte = 1 colonna. In secondo luogo crea lo stesso oggetto per tutte le parti [b-f], cambiando l'indice del partito rispettivamente, e aggiungilo alla riga. Fai un passo e due per il resto delle onde [2-7], cambiando rispettivamente party e time var, e aggiungili alla riga.

+0

Se si desidera colonne separate per 430 e 1500 nel formato lungo, ci dovrebbe essere una quantità uguale di dati da quelle condizioni nel campo. Il modo in cui lo hai, avresti molte NA nella colonna del 1500 ... o lo volevi in ​​quel modo? – John

+0

Oh, probabilmente è tutto un po 'approssimativo. C'è una quantità uguale di onde (1-7) e oggetti di partito (a-f) per queste due variabili. Quindi: KP [1-7] _430 [a-f], KP [1-7] _1500 [a-f]. – lstoetze

+0

Tuttavia, per alcune variabili nel set di dati c'è (a) solo dati per alcune onde - ad es. KP [146] _1640 [a-f] o (b) non specifici del gruppo - ad es. KP [1-7] _1490. – lstoetze

risposta

4

solito è più facile procedere in due passaggi: prima usare melt per inserire i dati in un formato "alto" (a meno che non sia già il caso) e quindi utilizzare dcast per convertire ti in un formato più ampio.

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

Questo funziona! Grande. Grazie. – lstoetze

0

Al momento i dati Wave sono nei nomi delle variabili e è necessario estrarli con l'elaborazione delle stringhe. Non ho avuto problemi con il fuso

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

La descrizione è troppo impreciso (finora) per me, per capire la regola per derivare una variabile "Party", quindi forse è possibile modificare si mette in discussione per mostrare come che potrebbe essere fatto da un essere umano .... e poi possiamo mostrare al computer come farlo.

EDIT: Se l'ultima lettera minuscola nei nomi delle colonne originali è partito come pensa Vincent, allora si potrebbe tagliare gli spazi finali in quei nomi ed estratto:

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>