2013-04-21 12 views
8

Meine Frage betrifft eine Ausarbeitung auf eine zuvor beantwortete Frage über combining multiple dummy variables into a single categorical variable.Erstellen von kategorischen Variablen aus sich gegenseitig ausschließenden Dummy-Variablen

In der zuvor gestellten Frage wurde die kategoriale Variable aus Dummy-Variablen erstellt, die sich NICHT gegenseitig ausschlossen. Für meinen Fall schließen sich meine Dummy-Variablen gegenseitig aus, weil sie gekreuzte experimentelle Bedingungen in einem 2X2 zwischen Subjekten faktoriellen Design darstellen (das hat auch eine Subjektkomponente, die ich hier nicht anspreche), also glaube ich nicht, was interaction tut Ich muss ... machen.

Zum Beispiel könnte meine Daten wie folgt aussehen:

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 

Ich mag würde jetzt kategorischen Variablen machen, die über verschiedene Arten von Bedingungen kombinieren. Zum Beispiel Menschen, die Werte für die Bedingung A und B hatten vielleicht mit einer kategorialen Variablen, und den Menschen codiert werden, die Werte für die Bedingung C und 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 

nun Recht hatte, mache ich diese ifelse()-Anweisungen, was einfach ein heißes Durcheinander ist (und nicht immer funktioniert). Bitte helfen Sie! Es gibt wahrscheinlich einen sehr offensichtlichen "leichteren Weg".

EDIT:

Die Arten von ifelse Befehle, die ich verwende sind wie folgt:

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

In Wirklichkeit bin ich über 6-8 Spalten jedes Mal kombiniert, so eine elegantere Lösung würde viel helfen.

Antwort

4

Mein R package hat eine Komfortfunktion, die den ersten nicht NA Wert für jedes Element in einer Liste von Vektoren auswählen kann:

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

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

(Ich bin nicht sicher, ob dies funktioniert, wenn conditionA und conditionB sind Faktoren.Wandeln Sie sie in Zahlen um, bevor Sie as.numeric(as.character(...)) verwenden, falls erforderlich.)

Andernfalls könnten Sie interaction einen Versuch, kombiniert mit Umkodierung des Pegels des resultierenden Faktors geben - aber für mich sieht es aus wie Sie in der ersten Lösung mehr interessiert sind:

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

Danke! Guter Fang ... ein Tippfehler in den letzten 2 Zeilen, als ich Probendaten erfasste. – roody

+0

@rody: Kann 'conditionD' jemals den Wert enthalten, sagen wir 3? Was soll dann passieren? – krlmlr

+0

Nein, sie sind alle zwei Level-Faktor-Variablen - 1 und 2 sind nur die Werte, die ihnen von Qualtrics zugewiesen werden, aber es ist immer eine dichte Wahl. – roody

1

Nun, ich glaube, Sie es mit ifelse einfach tun können, so etwas wie:

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

Ein anderer Weg sein könnte:

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

Und eine dritte Lösung, sicherlich mehr pratical wenn Sie mehr als zwei Spalten Bedingungen:

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

Hallo @ juba - Ich mag die Einfachheit der dritten Lösung ... aber wie ändere ich alle relevanten Spalten auf numerisch, wenn R sie als Faktor einliest? Der Befehl 'df [cols] <- as.numeric (as.matrix (df [cols])) ' scheint nicht zu funktionieren (wenn 'cols' eine Liste von Spaltennummern ist). – roody

1

Ich denke, diese Funktion gibt Ihnen was Du brauchst (zugegeben, das ist ein schneller Hack).

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 
      }) 
} 

Und hier ist es mit den von Ihnen bereitgestellten Beispieldaten verwendet.

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"))))