2013-04-21 3 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 

Я хотел бы теперь делаю категориальные переменные, которые комбинируют между различными типами условий. Например, люди, которые имели значения условия А и В может быть закодирован с одной категориальной переменной, и людей, которые имели значения условия С и 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() заявления, который довольно просто горячий беспорядок (и не всегда работает). Пожалуйста помоги! Вероятно, есть какой-то супер-очевидный «более простой способ».

EDIT:

Виды 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)) 

(я не уверен, если это работает, если 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') 
+0

Спасибо! Хорошая уловка ... опечатка в последних двух строках, когда я составлял образцы данных. – roody

+0

@roody: Может ли 'conditionD' когда-либо содержать значение, скажем, 3? Что тогда должно произойти? – krlmlr

+0

Нет, все они являются двухфакторными переменными фактора - 1 и 2 - это только значения, присвоенные им Qualtrics, но это всегда дихотомический выбор. – roody

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

Привет @ juba - Мне нравится простота третьего решения ... но как мне изменить все соответствующие столбцы на числовые, если R читает их как фактор? Команда 'df [cols] <- as.numeric (as.matrix (df [cols])) ', похоже, не работает (когда 'cols' - это список номеров столбцов). – roody

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