2012-03-13 13 views
14

So che il lungo è stato chiesto troppe volte qui ma non riesco a capire come trasformare il seguente in formato lungo. Spara Ho anche chiesto uno dei larghi a lungo con 2 misure ripetute su SO. Sto diventando frustrato dalla mia incapacità di convertire i miei dati. Come posso trasformare questa (ordine variabile non importa):misure multiple da lungo a lungo ogni volta

 id trt work.T1 play.T1 talk.T1 total.T1 work.T2 play.T2 talk.T2 total.T2 
1 x1.1 cnt 0.34434350 0.7841665 0.1079332 0.88803151 0.64836951 0.87954320 0.7233519 0.5630988 
2 x1.2 tr 0.06132255 0.8426960 0.3338658 0.04685878 0.23478670 0.19711687 0.5164015 0.7617968 
3 x1.3 tr 0.36897981 0.1834721 0.3241316 0.76904051 0.07629721 0.06945971 0.4118995 0.7452974 
4 x1.4 tr 0.40759356 0.5285396 0.5654258 0.23022542 0.92309504 0.15733957 0.4132653 0.7078273 
5 x1.5 cnt 0.91433676 0.7029476 0.2031782 0.31518412 0.14721669 0.33345678 0.7620444 0.9868082 
6 x1.6 tr 0.88870525 0.9132728 0.2197045 0.28266959 0.82239037 0.18006177 0.2591765 0.4516309 
7 x1.7 cnt 0.98373218 0.2591739 0.6331153 0.71319565 0.41351839 0.14648269 0.7631898 0.1182174 
8 x1.8 tr 0.47719528 0.7926248 0.3525205 0.86213792 0.61252061 0.29057544 0.9824048 0.2386353 
9 x1.9 tr 0.69350823 0.6144696 0.8568732 0.10632352 0.06812050 0.93606889 0.6701190 0.4705228 
10 x1.10 cnt 0.42574646 0.7006205 0.9507216 0.55032776 0.90413220 0.10246047 0.5899279 0.3523231 

in questo:

 id trt time  work  play  talk  total 
1 x1.1 cnt 1 0.34434350 0.78416653 0.1079332 0.88803151 
2 x1.2 tr 1 0.06132255 0.84269599 0.3338658 0.04685878 
3 x1.3 tr 1 0.36897981 0.18347215 0.3241316 0.76904051 
4 x1.4 tr 1 0.40759356 0.52853960 0.5654258 0.23022542 
5 x1.5 cnt 1 0.91433676 0.70294755 0.2031782 0.31518412 
6 x1.6 tr 1 0.88870525 0.91327276 0.2197045 0.28266959 
7 x1.7 cnt 1 0.98373218 0.25917392 0.6331153 0.71319565 
8 x1.8 tr 1 0.47719528 0.79262477 0.3525205 0.86213792 
9 x1.9 tr 1 0.69350823 0.61446955 0.8568732 0.10632352 
10 x1.10 cnt 1 0.42574646 0.70062053 0.9507216 0.55032776 
11 x1.1 cnt 2 0.64836951 0.87954320 0.7233519 0.56309884 
12 x1.2 tr 2 0.23478670 0.19711687 0.5164015 0.76179680 
13 x1.3 tr 2 0.07629722 0.06945971 0.4118995 0.74529740 
14 x1.4 tr 2 0.92309504 0.15733957 0.4132653 0.70782726 
15 x1.5 cnt 2 0.14721669 0.33345678 0.7620444 0.98680824 
16 x1.6 tr 2 0.82239038 0.18006177 0.2591765 0.45163091 
17 x1.7 cnt 2 0.41351839 0.14648269 0.7631898 0.11821741 
18 x1.8 tr 2 0.61252061 0.29057544 0.9824048 0.23863532 
19 x1.9 tr 2 0.06812050 0.93606889 0.6701190 0.47052276 
20 x1.10 cnt 2 0.90413220 0.10246047 0.5899279 0.35232307 

Il set di dati

id <- paste('x', "1.", 1:10, sep="") 
set.seed(10) 
DF <- data.frame(id, trt=sample(c('cnt', 'tr'), 10, T), work.T1=runif(10), 
    play.T1=runif(10), talk.T1=runif(10), total.T1=runif(10), 
    work.T2=runif(10), play.T2=runif(10), talk.T2=runif(10), 
    total.T2=runif(10)) 

Grazie in anticipo!

MODIFICA: Si è verificato qualcosa di avvincente quando stavo usando set.seed (sicuramente un errore l'ho fatto). I dati effettivi sopra non sono i dati che otterrai se usi set.seed(10). Lascio l'errore per la precisione storica e in realtà non influisce sulle soluzioni fornite dalle persone.

+0

Domanda chiara, esempio riproducibile. +1 –

risposta

8

Questo è abbastanza vicino e cambiando i nomi delle colonne dovrebbe essere all'interno della vostra Skillset:

reshape(DF, 
     varying=c(work= c(3, 7), play= c(4,8), talk= c(5,9), total= c(6,10)), 
     direction="long") 

EDIT: Aggiunta di una versione che è quasi una soluzione esatta:

reshape(DF, varying=list(work= c(3, 7), play= c(4,8), talk= c(5,9), total= c(6,10)), 
     v.names=c("Work", "Play", "Talk", "Total"), 
      # that was needed after changed 'varying' arg to a list to allow 'times' 
     direction="long", 
     times=1:2,  # substitutes number for T1 and T2 
     timevar="times") # to name the time col 
+1

grazie mille! Ero vicino a questo, ma non capivo cosa stavo facendo. Molto semplice e ho imparato un po 'di più sulla risagoma in base (funzione potente ma a volte confusa –

+0

Sono completamente d'accordo sul fatto che possa essere fonte di confusione. Come Ben Bolker, usavo solo reshape :: melt. –

+0

è appena tornato qui (I Vorrei che SO ti dicesse se qualcuno modifica la loro risposta, solo un suggerimento di aggiungere un commento quando lo fai COSÌ informa i poster) e mi è piaciuta la tua risposta prima Mi piace molto adesso Le annotazioni sono fantastiche Grazie Grazie –

3

Stranamente ho don sembra che tu abbia gli stessi numeri di te (che dovrei usare entrambi, set.seed(10)?), ma per il resto questo sembra fare il trucco:

library(reshape) #this might work with reshape2 as well, I haven't tried ... 
DF2 <- melt(DF,id.vars=1:2) 
## split 'activity.time' label into two separate variables 
DF3 <- cbind(DF2, 
      colsplit(as.character(DF2$variable),"\\.", 
         names=c("activity","time"))) 
## rename time, reorder factors: 
DF4 <- transform(DF3, 
       time=as.numeric(gsub("^T","",time)), 
       activity=factor(activity, 
        levels=c("work","play","talk","total")), 
       id=factor(id,levels=paste("x1",1:10,sep="."))) 
## reshape back to wide 
DF5 <- cast(subset(DF4,select=-variable),id+trt+time~activity) 
## reorder 
DF6 <- with(DF5,DF5[order(time,id),]) 

È più complicato della risposta di @ DWin ma forse (?) Più generale.

+0

Grazie tu Ben, aggiungo sia la tua risposta sia quella di Dwin alle mie note R (ora più di 200 pagine). Entrambe le risposte sono state molto perspicaci a seconda della situazione +1 –

2

Se davvero non volevi la "T" nella variabile "tempo" nell'output, non potresti semplicemente fare quanto segue?

names(DF) = sub("T", "", names(DF)) 
reshape(DF, direction="long", varying=3:10) 

Oppure, senza cambiare names(DF), si può semplicemente impostare l'argomento sep= per includere "T":

reshape(DF, direction="long", varying=3:10, sep=".T") 

Sono un po 'confuso, però. Come Ben Bolker ha indicato a in his comment, il tuo "codice set di dati" non fornisce gli stessi numeri di quello che hai. Inoltre, l'output di DWin e mio corrisponde perfettamente, ma non corrisponde all'output "in questo" presente nella domanda originale.

Ho verificato ciò creando un frame di dati denominato "DWin" con i suoi risultati e un frame di dati denominato "mio" con i miei risultati e li ho confrontati utilizzando DWin == mine.

Puoi verificare che l'output che abbiamo ottenuto sia effettivamente quello che ti serviva?

+0

Sì, l'output che hai ottenuto e di DWin è corretto. set.seed Mi scuso Grande soluzione, codice molto piccolo –

0

Un altro modo di affrontare il problema che richiede pochissimo codice, ma sarebbe probabilmente più lento ,:

DF.1 <- DF[, 1:2] 
DF.2 <- DF[, 3:6] 
DF.3 <- DF[, 7:10] 

names(DF.2) <- names(DF.3) <- unlist(strsplit(names(DF.2), ".", fixed=T))[c(T,F)] 
time <- rep(1:2, each=nrow(DF.1)) 
data.frame(rbind(DF.1, DF.1), time, rbind(DF.2, DF.3)) 
4

Il modo più conciso è quello di utilizzare in combinazione con tidyr dplyr biblioteca.

library(tidyr) 
library(dplyr) 
result <- DF %>% 
    # transfer to 'long' format 
    gather(loc, value, work.T1:total.`enter code here`T2) %>% 
    # separate the column into location and time 
    separate(loc, into = c('loc', 'time'), '\\.') %>% 
    # transfer to 'short' format 
    spread(loc, value) %>% 
    mutate(time = as.numeric(substr(time, 2, 2))) %>% 
    arrange(time) 

tidyr è progettato specificamente per rendere i dati in ordine.

+0

Non lo definirei conciso rispetto ad altre soluzioni –

+1

Questo è superiore alle soluzioni che usa 'reshape' - più facile da leggere grazie al suo stile funzionale (l'operatore'%>% ') e anche più performante, penso, a causa delle parti chiave scritte in C++. – GregT

+1

cosa si suppone essere la parte 'inserisci codice qui? @ Yingsen Mao – vashts85

Problemi correlati