Использование Apply, чтобы избежать «условие имеет длину> 1 и будет использоваться только первый элемент»? - PullRequest
1 голос
/ 26 февраля 2020

Я пытаюсь определить кусочную функцию, и она отлично работает для одиночных входов, но когда я пытаюсь использовать векторный ввод, я получаю «условие имеет длину> 1, и только первый элемент будет б "ошибка, потому что он передает скаляр в вектор, насколько я могу судить.

ex <- function(x){
  if (x < -1) {
    y <- (-2 * x) -2
    return(y)
  }
  else if (-1 <= x & x <= 1) {
    y <- 0
    return(y)
  }
  else if (1 < x){
    y <- (x * x) - 1
    return(y)
  }
}

Может кто-нибудь помочь мне использовать функцию применения, чтобы решить эту проблему? Я бы хотел избежать использования ifelse.

Ответы [ 2 ]

4 голосов
/ 26 февраля 2020

Просто для демонстрации Vectorize здесь, что является еще одним способом векторизации ваших функций, то есть

ex_vec <- Vectorize(ex)

ex_vec(c(10, 12))
#[1]  99 143
1 голос
/ 26 февраля 2020

Как вы уже знаете, ваша функция написана только для скалярных входов, а не для векторов. Итак,

ex(10)
ex(12)

работает. Но

ex(c(10, 12))

нет. (На самом деле это дает ожидаемый результат с предупреждением в этом случае)


Без изменения функции одним из способов является использование sapply

sapply(c(10, 12), ex)

Или вы можете измените функцию и используйте ifelse, который будет работать для векторов

ex1 <- function(x){
   ifelse(x < -1,(-2 * x) -2,
     ifelse(-1 <= x & x <= 1, 0,
       ifelse(1 < x,(x * x) - 1,NA)))
}

ex1(c(10, 12))

или с dplyr::case_when

ex2 <- function(x){
   dplyr::case_when(x < -1 ~ (-2 * x) -2,
                   -1 <= x & x <= 1 ~ 0,
                    1 < x ~ (x * x) - 1)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...