2013-04-21 17 views
8

La mia domanda riguarda un'elaborazione su una domanda precedentemente fornita a proposito di combining multiple dummy variables into a single categorical variable.Creazione di variabili categoriali da variabili dummy mutuamente esclusive

Nella domanda precedente, la variabile categoriale è stata creata da variabili dummy che NON si escludevano a vicenda. Per il mio caso, le mie variabili dummy si escludono a vicenda perché rappresentano condizioni sperimentali incrociate in un design fattoriale 2x2 tra soggetti (che ha anche una componente soggettiva all'interno di cui non mi sto riferendo qui), quindi non penso che lo interaction faccia cosa Devo fare.

Per esempio, i miei dati potrebbero apparire così:

id conditionA conditionB conditionC  conditionD 
1 NA   1    NA    NA 
2 1    NA   NA    NA 
3 NA   NA   1    NA 
4 NA   NA   NA    1 
5 NA   2    NA    NA 
6 2    NA   NA    NA 
7 NA   NA   2    NA 
8 NA   NA   NA    2 

Mi piacerebbe fare ora variabili categoriali che combinano tra i diversi tipi di condizioni. Ad esempio, le persone che avevano valori di condizione A e B possono essere codificati con una sola variabile categoriale, e le persone che avevano valori di condizione C e D.

id conditionA conditionB conditionC  conditionD factor1 factor2 
1 NA   1    NA    NA   1   NA 
2 1    NA   NA    NA   1   NA 
3 NA   NA   1    NA   NA   1 
4 NA   NA   NA    1   NA   1 
5 NA   2    NA    NA   2   NA 
6 2    NA   NA    NA   2   NA 
7 NA   NA   2    NA   NA   2 
8 NA   NA   NA    2   NA   2 

In questo momento, sto facendo questo utilizzando ifelse() dichiarazioni, che è semplicemente un pasticcio caldo (e non sempre funziona). Per favore aiuto! Probabilmente c'è un "modo più semplice" super-ovvio.

EDIT:

I tipi di ifelse comandi che sto usando sono i seguenti:

attach(df) 
df$factor<-ifelse(conditionA==1 | conditionB==1, 1, NA) 
df$factor<-ifelse(conditionA==2 | conditionB==2, 2, df$factor) 

In realtà, io sto combinando tra 6-8 colonne di volta in volta, in modo da una soluzione più elegante aiuterebbe molto

risposta

4

mio R package ha una funzione convenienza che permette di scegliere il primo valore non NA per ogni elemento in un elenco di vettori:

#library(devtools) 
#install_github('kimisc', 'muelleki') 
library(kimisc) 

df$factor1 <- with(df, coalesce.na(conditionA, conditionB)) 

(non sono sicuro se questo funziona se conditionA e conditionB sono fattori. Converti in numeri prima di utilizzare as.numeric(as.character(...)) se necessario.)

In caso contrario, si potrebbe dare interaction una prova, combinata con ricodifica dei livelli del fattore risultante - ma a me sembra che siete più interessati nella prima soluzione:

df$conditionAB <- with(df, interaction(coalesce.na(conditionA, 0), 
             coalesce.na(conditionB, 0))) 
levels(df$conditionAB) <- c('A', 'B') 
+0

Grazie! Buona cattura ... un refuso nelle ultime 2 righe quando stavo inventando dati di esempio. – roody

+0

@roody: Può 'condizioneD' mai contenere il valore, ad esempio, 3? Cosa dovrebbe succedere allora? – krlmlr

+0

No, sono tutte due variabili fattore di livello - 1 e 2 sono solo i valori assegnati loro da Qualtrics, ma è sempre una scelta dictomous. – roody

1

Beh, penso che si può fare semplicemente con ifelse, qualcosa di simile a:

factor1 <- ifelse(is.na(conditionA), conditionB, conditionA) 

Un altro modo potrebbe essere:

factor1 <- conditionA 
factor1[is.na(factor1)] <- conditionB 

E una terza soluzione, sicuramente più pratico se si dispone di più di due colonne condizioni:

factor1 <- apply(df[,c("conditionA","conditionB")], 1, sum, na.rm=TRUE) 
+0

Hi @ juba - Mi piace la semplicità della terza soluzione ... ma come faccio a cambiare tutte le colonne rilevanti in numerico se R le legge come fattore? Il comando 'df [cols] <- as.numeric (as.matrix (df [cols])) ' non sembra funzionare (quando 'cols' è una lista di numeri di colonna). – roody

1

Penso che questa funzione ti dia quello che hai bisogno (certamente, questo è un trucco veloce).

to_indicator <- function(x, grp) 
{ 
    apply(tbl, 1, 
      function (x) 
      { 
       idx <- which(!is.na(x)) 
       nm <- names(idx) 
       if (nm %in% grp) 
       x[idx] 
       else 
       NA 
      }) 
} 

E qui viene utilizzato con i dati di esempio forniti.

tbl <- read.table(header=TRUE, text=" 
conditionA conditionB conditionC  conditionD 
NA   1    NA    NA 
1    NA   NA    NA 
NA   NA   1    NA 
NA   NA   NA    1 
NA   2    NA    NA 
2    NA   NA    NA 
NA   NA   2    NA 
NA   NA   NA    2") 
tbl <- data.frame(tbl) 

(tbl <- cbind(tbl, 
       factor1=to_indicator(tbl, c("conditionA", "conditionB")), 
       factor2=to_indicator(tbl, c("conditionC", "conditionD")))) 
Problemi correlati