2013-04-21 142 views
8

我的問題涉及對關於combining multiple dummy variables into a single categorical variable的以前回答的問題的闡述。從互斥虛擬變量創建分類變量

在之前提出的問題中,分類變量是從不相互排斥的虛擬變量創建的。對於我的情況,我的虛擬變量是相互排斥的,因爲它們代表了交叉實驗條件下2X2的主體間因素設計(也有一個主題內部組件,我不在這裏討論),所以我不認爲interaction做什麼我需要去做。

例如,我的數據可能是這樣的:

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 

我想現在作出這樣的組合在不同類型的條件分類變量。例如,人們誰了條件A和B值可能與一個分類變量,人們誰了狀態C和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 

值現在,我這樣做是使用ifelse()語句進行編碼,這簡直是​​一團糟(並不總是有效)。請幫忙!可能有一些超級明顯的「更簡單的方法」。

編輯:是

的種,我使用ifelse的命令如下:

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

在現實中,我每一次跨越相結合6-8列,所以一個更優雅的解決方案會幫助很多。

回答

4

R package有一個方便的功能,允許在選擇載體列表每個元素的第一個非NA值:

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

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

(我不知道,如果這個工程如果conditionAconditionB是因素。如果需要,使用as.numeric(as.character(...))之前將它們轉換爲數字。)

否則,你可以給interaction一試,用得到的因子水平的再編碼組合 - 但對我來說,它看起來像你更感興趣的第一個解決方案:

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

謝謝!良好的發現......當我編寫樣本數據時,最後兩行中有一個錯字。 – roody 2013-04-21 20:22:27

+0

@roody:'conditionD'是否包含值,比如3?那麼應該發生什麼? – krlmlr 2013-04-21 20:23:27

+0

不,他們都是兩個層次因素變量 - 1和2只是Qualtrics分配給他們的值,但它總是一個非常愚蠢的選擇。 – roody 2013-04-21 20:26:19

1

好吧,我想你可以簡單地用ifelse做到這一點,是這樣的:

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

另一種方式可以是:

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

而第三種解決方案,當然更之實踐,如果你有更多的兩個條件:

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

喜@朱巴 - 我喜歡第三種解決方案的簡單性......但是如果R讀取它們作爲因子,我怎樣才能將所有相關列更改爲數字?命令'df [cols] < - as.numeric(as.matrix(df [cols])) '似乎不起作用(當cols是列號列表時)。 – roody 2013-04-21 20:20:24

1

我覺得這個功能給你什麼你需要(誠然,這是一個快速入侵)。

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

這裏是它與您提供的示例數據一起使用。

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