2012-02-18 11 views
5

Le funzioni di fusione/fusione nel pacchetto di risagoma sono grandi, ma non sono sicuro se c'è un modo semplice per applicarle quando le variabili misurate sono di tipi diversi. Ad esempio, ecco un frammento da dati in cui ogni MD fornisce il sesso e peso dei tre pazienti:Alternative alle statistiche :: risagoma

ID PT1 WT1 PT2 WT2 PT3 WT3 
1 "M" 170 "M" 175 "F" 145 
... 

dove l'obiettivo è quello di rimodellare in modo che ogni riga è un paziente:

ID PTNUM GENDER WEIGHT 
1 1  "M" 170 
1 2  "M" 175 
1 3  "F" 145 
... 

Uso del la funzione di risagoma nel pacchetto stats è una delle opzioni di cui sono a conoscenza, ma sto postando qui nella speranza che gli utenti di R più esperti di me pubblichino altri metodi, si spera migliori. Grazie molto!

-

@Vincent Zoonekynd:

mi è piaciuto il vostro esempio molto, quindi ho generalizzato a più variabili.

# Sample data 
n <- 5 
d <- data.frame(
    id = 1:n, 
    p1 = sample(c("M","F"),n,replace=TRUE), 
    q1 = sample(c("Alpha","Beta"),n,replace=TRUE), 
    w1 = round(runif(n,100,200)), 
    y1 = round(runif(n,100,200)), 
    p2 = sample(c("M","F"),n,replace=TRUE), 
    q2 = sample(c("Alpha","Beta"),n,replace=TRUE), 
    w2 = round(runif(n,100,200)), 
    y2 = round(runif(n,100,200)), 
    p3 = sample(c("M","F"),n,replace=TRUE), 
    q3 = sample(c("Alpha","Beta"),n,replace=TRUE), 
    w3 = round(runif(n,100,200)), 
    y3 = round(runif(n,100,200)) 
) 
# Reshape the data.frame, one variable at a time 
library(reshape) 
d1 <- melt(d, id.vars="id", measure.vars=c("p1","p2","p3","q1","q2","q3")) 
d2 <- melt(d, id.vars="id", measure.vars=c("w1","w2","w3","y1","y2","y3")) 
d1 = cbind(d1,colsplit(d1$variable,names=c("var","ptnum"))) 
d2 = cbind(d2,colsplit(d2$variable,names=c("var","ptnum"))) 
d1$variable = NULL 
d2$variable = NULL 
d1c = cast(d1,...~var) 
d2c = cast(d2,...~var) 
# Join the two data.frames 
d3 = merge(d1c, d2c, by=c("id","ptnum"), all=TRUE) 

-

pensieri finale: la mia motivazione per questa domanda è stato quello di conoscere alternative al pacchetto di rimodellare oltre alle statistiche :: funzione di rimodellare. Per il momento, ho raggiunto le seguenti conclusioni:

  • Stick alle statistiche :: rimodellare quando è possibile. Finché ti ricorderai di usare una lista piuttosto che un semplice vettore per l'argomento "variabile", rimarrai fuori dai guai. Per i set di dati più piccoli - poche migliaia di casi di pazienti con meno di 200 variabili in totale è ciò che stavo trattando stavolta - la bassa velocità di questa funzione vale la semplicità del codice.

  • Per utilizzare l'approccio cast/melt nel pacchetto di risagoma (o di rimodellazione 2) di Hadley Wickham, è necessario suddividere le variabili in due gruppi, uno costituito da variabili numeriche e un altro di variabili di carattere. Quando il tuo set di dati è abbastanza grande da trovare stats :: reshape insopportabile, immagino che il passaggio in più nel dividere le tue variabili in due set non sembrerà così male.

+3

Meglio in che senso? risagoma è pensato per le attività proprio come questo, quindi perché non usarlo? – Fojtasek

+0

Risagoma funziona bene fino a quando si ricorda di utilizzare la forma canonica dell'argomento variabile (una lista): [collegamento] (http://www.mail-archive.com/[email protected]/msg160715 .html) Con R, sono costantemente sorpreso dall'esistenza di alternative di cui non ero a conoscenza, quindi ho pensato che qualcuno avrebbe pubblicato altri approcci. Un esempio di definizione di "migliore" sarebbe la velocità: nella mia esperienza dichiaratamente soggettiva, il cast/melt sembra più veloce della rimodulazione incorporata. –

+0

Non me ne sono accorto, grazie. Ora ho cambiato la libreria da reshape2 a rimodellare.Puoi comunque usare reshape2 se lo desideri: dovrai aggiungere l'argomento pattern con un valore di "" alla chiamata colsplit(). –

risposta

3

È possibile elaborare separatamente per ciascuna variabile, e unire le conseguenti due data.frames.

# Sample data 
n <- 5 
d <- data.frame(
    id = 1:n, 
    pt1 = sample(c("M","F"),n,replace=TRUE), 
    wt1 = round(runif(n,100,200)), 
    pt2 = sample(c("M","F"),n,replace=TRUE), 
    wt2 = round(runif(n,100,200)), 
    pt3 = sample(c("M","F"),n,replace=TRUE), 
    wt3 = round(runif(n,100,200)) 
) 
# Reshape the data.frame, one variable at a time 
library(reshape2) 
d1 <- melt(d, 
    id.vars="id", measure.vars=c("pt1","pt2","pt3"), 
    variable.name="patient", value.name="gender" 
) 
d2 <- melt(d, 
    id.vars="id", measure.vars=c("wt1","wt2","wt3"), 
    variable.name="patient", value.name="weight" 
) 
d1$patient <- as.numeric(gsub("pt", "", d1$patient)) 
d2$patient <- as.numeric(gsub("wt", "", d1$patient)) 
# Join the two data.frames 
merge(d1, d2, by=c("id","patient"), all=TRUE) 
+0

Grazie, questo ha senso. Il codice è più lungo di quello richiesto per stats :: reshape, ma probabilmente vale l'efficienza ottenuta quando ci sono molte variabili, il che è spesso il mio caso. –

2

Penso che la funzione reshape nel pacchetto di statistiche sia la più semplice. Ecco un semplice esempio, fa ciò che vuoi?

> tmp 
    id val val2 cat 
1 1 1 14 a 
2 1 2 13 b 
3 2 3 12 b 
4 2 4 11 a 
> tmp2 <- tmp 
> tmp2$t <- ave(tmp2$val, tmp2$id, FUN=seq_along) 
> tmp2 
    id val val2 cat t 
1 1 1 14 a 1 
2 1 2 13 b 2 
3 2 3 12 b 1 
4 2 4 11 a 2 
> reshape(tmp2, idvar='id', timevar='t', direction='wide') 
    id val.1 val2.1 cat.1 val.2 val2.2 cat.2 
1 1  1  14  a  2  13  b 
3 2  3  12  b  4  11  a 

Speriamo che il vostro pazienti sesso non sta cambiando ogni appuntamento, ma ci potrebbero essere altre variabili categoriali che cambiano tra una visita e

+0

Avevo in mente più pazienti per MD, non lo stesso paziente misurato in più occasioni. Ma sono d'accordo che il codice con stats :: reshape è decisamente più compatto, purché si sia consapevoli dei potenziali trucchi: [vedi link] (http://www.mail-archive.com/[email protected] .org/msg160715.html) –

+0

Quindi nel mio esempio usare id come id del medico e i valori multipli rappresentano i pazienti. –