Выбор 2 соответствующих столбцов в каждой строке фрейма данных

Прошу прощения, так как это кажется основным вопросом, но я искал лучшее решение, но не нашел его. У меня есть данные следующего типа.

myDATA<-data.frame(rbind(c("red","blue","green", "dog","hat","cat")
                     ,c("blue","green", "blue","dog","hat","cat")
                     ,c("green","blue","blue","dog","hat","cat")
                     ,c("green","red", "blue","dog","hat","cat")
                     )
               )
names(myDATA)<-c(paste("Color",1:3,sep=""),paste("Stim",1:3,sep=""))
myDATA$greenImage<-NA

Который дает:

мои данные

+-----------------------------------------------------+
|   Color1 Color2 Color3 Stim1 Stim2 Stim3 greenImage |
+-----------------------------------------------------+
| 1    red   blue  green   dog   hat   cat         NA |
| 2   blue  green   blue   dog   hat   cat         NA |
| 3  green   blue   blue   dog   hat   cat         NA |
| 4  green    red   blue   dog   hat   cat         NA |
+-----------------------------------------------------+

Столбцы Color соответствуют столбцам Stim по номерам, например, Stim1 отображается в Color1 и так далее. В каждой строке зеленым отображается один Stim. Я хочу найти этот Stim и сохранить его в новом столбце с именем greenImage.

Из ряда сообщений я понял, что apply() может быть здесь полезен, но мне не удалось заставить его работать. Мое довольно неэлегантное решение было петлей формы ниже,

for (i in 1:nrow(myDATA)) {
  x <- match("green", unlist(myDATA[i,paste("Color", 1:3, sep="")]))
  myDATA[i,"greenImage"] <- as.character(myDATA[i, paste("Stim", x, sep="")])
}

В результате чего:

myDATA
+-----------------------------------------------------+
|   Color1 Color2 Color3 Stim1 Stim2 Stim3 greenImage |
+-----------------------------------------------------+
| 1    red   blue  green   dog   hat   cat        cat |
| 2   blue  green   blue   dog   hat   cat        hat |
| 3  green   blue   blue   dog   hat   cat        dog |
| 4  green    red   blue   dog   hat   cat        dog |
+-----------------------------------------------------+

Однако фактический набор данных содержит более 10000 строк, поэтому мое решение очень неэффективно. Может ли кто-нибудь предложить более эффективный альтернативный подход?

Заранее спасибо!


person Marcus Morrisey    schedule 25.04.2013    source источник


Ответы (1)


Просто используйте ifelse для векторизации ваших сравнений:

for (i in 1:3) {
  myDATA$greenImage = ifelse (myDATA[,i] == "green",
                              as.character(myDATA[,i+3]),
                              myDATA$greenImage)
}

Обратите внимание, что as.character необходим, чтобы получить строку из ваших factor. Этого можно избежать, если вы используете stringsAsFactors = FALSE при создании своего data.frame.

person eddi    schedule 25.04.2013
comment
Большое спасибо за быстрый ответ. Это было прямо и эффективно. Очень признателен. - person Marcus Morrisey; 26.04.2013