从互斥的虚拟变量创建分类变量

时间:2013-04-21 19:31:55

标签: r categorical-data dummy-variable

我的问题是关于以前回答的有关combining multiple dummy variables into a single categorical variable的问题的详细说明。

在前面提到的问题中,分类变量是从非互斥的虚拟变量创建的。对于我的情况,我的虚拟变量是相互排斥的,因为它们代表了2X2个主体间因子设计中的交叉实验条件(也有一个我在这里没有解决的内部主题组件),所以我不认为{{1做我需要做的事情。

例如,我的数据可能如下所示:

interaction

我现在想制作结合ACROSS不同类型条件的分类变量。例如,具有条件A和B的值的人可能使用一个分类变量编码,并且具有条件C和D的值的人。

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

现在,我正在使用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

实际上,我每次都会将6-8列合并,所以更优雅的解决方案会有很多帮助。

3 个答案:

答案 0 :(得分:5)

  

更新(2019):请使用dplyr::coalesce(),它的工作原理基本相同。

我的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')

答案 1 :(得分: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)

答案 2 :(得分: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"))))