2013-06-19 11 views
5

Ho un frame dati mytable con risultati per due misurazioni, A e B, portati a un gruppo di persone.R: come calcolare le differenze in base ai livelli di un fattore?

person measure outcome 
1  A  3.6 
2  A  2.3 
3  A  4.2 
1  B  3.9 
2  B  3.2 
3  B  2.7 

voglio calcolare per ogni persona la differenza tra i punteggi per A e B. Cioè, voglio ottenere:

person outcome_diff 
1  -0.3 
2  -0.9 
3  1.5 

ho cercato una risposta, ma ho trovato solo alcuni riguardo a trasformazioni all'interno dei livelli di un fattore, non attraverso di loro.

finalmente sono riuscita a lavorare fuori facendo:

mytable$outcome[mytable$measure=="B"] <- -1*mytable$outcome[mytable$measure=="B"] 
outtable <- aggregate(outcome ~ person, data=mytable, FUN=sum) 

Anche se funziona, mi chiedo come farlo senza rovinare la tabella originale. Inoltre, questa soluzione è abbastanza specifica per calcolare una differenza. Quale potrebbe essere un modo più generale per ottenere la stessa cosa?

risposta

5

userei plyr:

ddply(mytable, "person", summarize, 
     outcome_diff = outcome[measure == "A"] - 
        outcome[measure == "B"]) 
# person outcome_diff 
# 1  1   -0.3 
# 2  2   -0.9 
# 3  3   1.5 

Partendo dal presupposto di avere sempre esattamente due misure A e B e in questo ordine, si potrebbe anche solo fare ddply(mytable, "person", summarize, outcome_diff = -diff(outcome)).

+0

grazie! Daremo un'occhiata a 'plyr'. Per quanto riguarda l'alternativa 'diff', non sono sicuro di averlo capito: dato che' outcome' ha lunghezza 6, 'diff (risultato)' dovrebbe avere lunghezza 5. Quindi per ottenere il risultato 'result_diff' si dovrebbe adicalmente seleziona gli elementi dispari di 'diff (risultato)', giusto? – DvD

3

In base che si potrebbe fare questo:

ans <- sapply(split(myTable, myTable$person), function(x) { 
    diff(x[order(x$measure), 3]) 
}) 

data.frame(person = names(ans), outcome_dif = ans) 

## person outcome_dif 
## 1  1   0.3 
## 2  2   0.9 
## 3  3  -1.5 
3

Una soluzione data.table:

library(data.table) 
DT <- as.data.table(dat) 
DT[ , list(outcome_diff = outcome[measure == "A"] - 
       outcome[measure == "B"]),person] 
# person outcome_diff 
# 1:  1   -0.3 
# 2:  2   -0.9 
# 3:  3   1.5 
Problemi correlati