Создание категориальных переменных из взаимоисключающих фиктивных переменных
Мой вопрос касается разработки ранее отвеченного вопроса о объединении нескольких фиктивных переменных в одну категориальную переменную.
В ранее заданном вопросе категориальная переменная была создана из фиктивных переменных, которые НЕ были взаимоисключающими. Для моего случая мои фиктивные переменные являются взаимоисключающими, потому что они представляют пересеченные экспериментальные условия в факториальном дизайне 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 столбцов каждый раз, так что более элегантное решение очень поможет.
3 ответа
Пакет My 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')
Ну, я думаю, что вы можете сделать это просто с 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)
Я думаю, что эта функция дает вам то, что вам нужно (по общему признанию, это быстрый взлом).
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"))))