Ваш тестовый пример недостаточно сложен, чтобы раскрыть некоторые скрывающиеся крокодилы в R, относящиеся к объектам класса == factor, опциям по умолчанию для data.frame () и использованию таких функций, как apply и ifelse.Я мог бы извиниться за длину ответа, но на самом деле это всего лишь небольшое подмножество того, что вы можете прочитать в The Inferno .Допустим, вы создали data.frame, dfrm:
dfrm <-data.frame(textConnection("A B 2 12
L M 3 0
P Q 5 6", header=FALSE)
ВНИМАНИЕ: я немного изменил ваш первый случай.Теперь запустите первое предложенное решение: вы получите
apply(dfrm, 1, function(x){ifelse(x[3] > x[4], x[1], x[2])})
[1] "A" "L" "P"
Очевидно, что 2 НЕ больше 12, так что же случилось?Функция apply работает с матрицами и преобразует data.frame в матрицу перед выполнением функции и проверяет «2»> «12», что равно TRUE.Таким образом, крокодил # 1 является поведением по умолчанию apply ().
Ошибки или предупреждения также являются результатом того, что может показаться на первый и второй взгляд совершенно разумным кодом R:
vector <- dfrm$V2;
vector[V3 > V4] <- V1[V3 > V4]
(Во всяком случае, для меня это не было особенно информативным сообщением об ошибке ... кое-что о NA ... и это было связано с тем, что я пытался присвоить значение факторному объекту, для которого не было существующего уровня.) Это второй крокодил: класс по умолчанию для символьных значений, данных функции data.frame, это «фактор», а не «символ».
Третий крокодил - это поведение ifelse:
with(dfrm, ifelse(V3 > V4, V1, V2) )
[1] 1 2 3
WTF?Функция ifelse автоматически преобразует факторы в V1 и V2 в их внутренние числовые представления, и это происходит потому, что функция принудительно возвращает возвращаемые значения на основе типа условных аргументов.Не так, как я бы разработал такую функцию, но эти вещи были разработаны десятилетия назад, поэтому их изменение почти невозможно.Итак, пара «правильных» или, по крайней мере, более безопасных способов выполнения работы, которую вы просили: Метод 1:
with(dfrm, ifelse(V3 > V4, as.character(V1), as.character(V2) ) )
[1] "B" "L" "Q"
Метод 2:
vector <- as.character(dfrm$V2)
vector[which(dfrm$V3 > dfrm$V4)] <- as.character(dfrm$V1[which(dfrm$V3 > dfrm$V4)])
vector
[1] "B" "L" "Q"