9

我的问题是关于先前回答的关于将多个虚拟变量组合成单个分类变量的问题的详细说明。

在之前提出的问题中,分类变量是由不互斥的虚拟变量创建的。就我而言,我的虚拟变量是互斥的,因为它们代表 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

3 回答 3

6

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

我的R 包有一个方便的功能,允许为NA向量列表中的每个元素选择第一个非值:

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

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

(我不确定这是否有效,如果conditionA并且conditionB是因素。as.numeric(as.character(...))如有必要,在使用之前将它们转换为数字。)

否则,您可以interaction试一试,并结合对结果因子水平的重新编码——但在我看来,您似乎对第一个解决方案更感兴趣:

df$conditionAB <- with(df, interaction(coalesce.na(conditionA, 0), 
                                       coalesce.na(conditionB, 0)))
levels(df$conditionAB) <- c('A', 'B')
于 2013-04-21T20:19:48.427 回答
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)
于 2013-04-21T20:01:54.763 回答
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"))))
于 2013-04-21T20:02:54.077 回答