Почему операторы ifelse R не могут возвращать векторы?

StackOverflow https://stackoverflow.com/questions/1335830

  •  20-09-2019
  •  | 
  •  

Вопрос

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

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 состояния:

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

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

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

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

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

Другие советы

Бьюсь об заклад, вы хотите простого if утверждение вместо ifelse - в R, if это не просто структура потока управления, она может возвращать значение:

> 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:

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

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

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

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

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

Она основана на использовании get() вот так:

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

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

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

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

используйте `если`, например

> `if`(T,1:3,2:4)
[1] 1 2 3

В вашем случае, используя if_else От dplyr это было бы полезно: if_else является более строгим, чем ifelse, и выдает ошибку для вашего случая:

library(dplyr)
if_else(TRUE,c(1,2),c(3,4))
#> `true` must be length 1 (length of `condition`), not 2
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top