2015-04-21 6 views
33

Sto provando a prendere le colonne che sono nel formato lungo e le spargo al formato largo come indicato sotto. Mi piacerebbe usare tidyr per risolvere questo problema con gli strumenti di manipolazione dei dati in cui sto investendo, ma per rendere questa risposta più generale, si prega di fornire altre soluzioni.Come posso diffondere misure ripetute di più variabili nel formato grande?

Ecco quello che ho:

library(dplyr); library(tidyr) 

set.seed(10) 
dat <- data_frame(
    Person = rep(c("greg", "sally", "sue"), each=2), 
    Time = rep(c("Pre", "Post"), 3), 
    Score1 = round(rnorm(6, mean = 80, sd=4), 0), 
    Score2 = round(jitter(Score1, 15), 0), 
    Score3 = 5 + (Score1 + Score2)/2 
) 

## Person Time Score1 Score2 Score3 
## 1 greg Pre  80  78 84.0 
## 2 greg Post  79  80 84.5 
## 3 sally Pre  75  74 79.5 
## 4 sally Post  78  78 83.0 
## 5 sue Pre  81  78 84.5 
## 6 sue Post  82  81 86.5 

desiderata di grande formato:

Person Pre.Score1 Pre.Score2 Pre.Score3 Post.Score1 Post.Score2 Post.Score3 
1 greg   80   78  84.0   79   80  84.5 
2 sally   75   74  79.5   78   78  83.0 
3 sue   81   78  84.5   82   81  86.5 

posso farlo facendo qualcosa di simile per ogni punteggio:

spread(dat %>% select(Person, Time, Score1), Time, Score1) %>% 
    rename(Score1_Pre = Pre, Score1_Post = Post) 

E quindi utilizzando _join ma sembra prolisso e come deve esserci un modo migliore.

domande correlate:
tidyr wide to long with two repeated measures
Is it possible to use spread on multiple columns in tidyr similar to dcast?

+2

Questo è più facile con la versione devel di 'data.table' es. 'dcast (setDT (dat), Person ~ Time, value.var = c ('Score1', 'Score2', 'Score3'))' – akrun

+0

@TylerRinker, penso che si riferisca alla seconda colonna del tuo risultato – BrodieG

risposta

42

Se si vuole attaccare con tidyr/dplyr

dat %>% 
    gather(temp, score, starts_with("Score")) %>% 
    unite(temp1, Time, temp, sep = ".") %>% 
    spread(temp1, score) 
+0

Questa è la * soluzione * tidyr che cercavo, che si dice che sia meno soddisfacente di entrambe le altre 2 risposte qui. Mi piacerebbe vedere la funzionalità di ** reshape2 ** in relazione a questo tipo di spostamento aggiunto a ** tidyr **. –

+5

@TylerRinker l'obiettivo di tidyr è di rendere i tuoi dati in ordine, quindi non dovresti aspettarti di fare il contrario per essere più semplice – hadley

+2

@amente Sì, posso vedere come gli strumenti dovrebbero soddisfare la filosofia del pacchetto. Spesso penso che ** tidyr ** abbia sostituito ** rimodella ** ma in realtà hanno diverse filosofie di base (i nomi dei pacchetti dicono tutto); ** tidyr ** è una sotto-filosofia di ** reshape2 **. Qualsiasi piano per un pacchetto ** untidyr ** :-) –

10

Uso reshape2:

library(reshape2) 
dcast(melt(dat), Person ~ Time + variable) 

produce:

Using Person, Time as id variables 
    Person Post_Score1 Post_Score2 Post_Score3 Pre_Score1 Pre_Score2 Pre_Score3 
1 greg   79   78  83.5   83   81  87.0 
2 sally   82   81  86.5   75   74  79.5 
3 sue   78   78  83.0   82   79  85.5 
+4

Probabilmente solo 'rifusione (dat, Persona ~ Tempo + variabile)' sarà sufficiente. –

+0

Grazie @DavidArenburg, non sapevo di quello – BrodieG

13

Utilizzando dcast dal pacchetto data.table.

library(data.table)#v1.9.5+ 
dcast(setDT(dat), Person~Time, value.var=paste0("Score", 1:3)) 

O reshape da baseR

reshape(as.data.frame(dat), idvar='Person', timevar='Time',direction='wide') 
+3

'value.var = paste0 (" Punteggio ", 1: 3)'? +1 per la base (ho ancora paura di 'reshape') – BrodieG

+0

@BrodieG Grazie, funziona, e anche il' names (dat) [3: 5] 'o potrebbe anche essere' grep'. – akrun

Problemi correlati