2013-04-21 103 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"))))