Почему операторы R if ifsese не возвращают векторы?

Я обнаружил, что R’s ifelse заявления очень удобны время от времени. Например:

ifelse(TRUE,1,2) # [1] 1 ifelse(FALSE,1,2) # [1] 2 

Но меня несколько смущает следующее поведение.

 ifelse(TRUE,c(1,2),c(3,4)) # [1] 1 ifelse(FALSE,c(1,2),c(3,4)) # [1] 3 то ifelse(TRUE,c(1,2),c(3,4)) # [1] 1 ifelse(FALSE,c(1,2),c(3,4)) # [1] 3 

Это выбор дизайна, который выше моего платного?

Документация для ifelse гласит:

ifelse возвращает значение с той же формой, что и test который заполняется элементами, выбранными из yes или no зависимости от того, является ли элемент test TRUE или FALSE .

Поскольку вы проходите тестовые значения длины 1, вы получаете результаты по длине 1. Если вы пройдете более длинные тестовые векторы, вы получите более длительные результаты:

 > ifelse(c(TRUE, FALSE), c(1, 2), c(3, 4)) [1] 1 4 

Поэтому ifelse предназначен для конкретной цели тестирования вектора логических чисел и возврата вектора той же длины, заполненного элементами, взятыми из (вектора) yes и no аргументов.

Это обычная путаница из-за имени функции, чтобы использовать это, когда на самом деле вы хотите просто создать нормальную if () {} else {} .

Уверен, вам нужна простая инструкция if вместо ifelse – в R, if это не просто структура streamа управления, она может вернуть значение:

 > if(TRUE) c(1,2) else c(3,4) [1] 1 2 > if(FALSE) c(1,2) else c(3,4) [1] 3 4 

да, я думаю, что ifelse () действительно предназначен для тех случаев, когда у вас большой длинный вектор тестов и вы хотите сопоставить каждый из двух вариантов. Например, я часто делаю цвета для plot () следующим образом:

 plot(x,y, col = ifelse(x>2, 'red', 'blue')) 

Если бы у вас был большой длинный вектор тестов, но были нужны пары для выходов, вы могли бы использовать sapply() или plyr llply() или что-то еще, возможно.

Обратите внимание, что вы можете обойти проблему, если назначить результат внутри ifelse :

 ifelse(TRUE, a <- c(1,2), a <- c(3,4)) a # [1] 1 2 ifelse(FALSE, a <- c(1,2), a <- c(3,4)) a # [1] 3 4 

Иногда пользователю просто требуется инструкция switch вместо ifelse . В таком случае:

 condition <- TRUE switch(2-condition, c(1, 2), c(3, 4)) #### [1] 1 2 

(что является еще одним вариантом синтаксиса ответа Кена Уильямса)

Вот такой подход, подобный предложенному Кэтом, но он может работать с существующими заранее назначенными векторами

Он основан на использовании get() следующим образом:

 a <- c(1,2) b <- c(3,4) get(ifelse(TRUE, "a", "b")) # [1] 1 2 
  • Что означает «Следующий объект замаскирован из« package: xxx »?
  • Сгенерировать фиктивную переменную
  • Найдите дополнение к кадру данных (антисоединение)
  • Ошибка в : объект типа «закрытие» не является подмножеством
  • Почему не рекомендуется использовать attach () в R, и что я должен использовать вместо этого?
  • dplyr - mutate: использовать имена динамических переменных
  • Понимание функции order ()
  • Создание нескольких графических элементов из R-функции
  • Вставка двух векторов с комбинациями всех элементов векторов
  • Вычислить среднее по группе
  • Оценить выражение, данное как строка
  • Давайте будем гением компьютера.