Почему я получаю "Предупреждающие NaNs Произведено" с ifelse? - PullRequest
0 голосов
/ 20 декабря 2018

У меня есть довольно простая кусочная функция, которая принимает векторный аргумент omega:

btilde <- function(omega) {
        if(min(omega)<=0) stop("ALL ELEMENTS OF OMEGA MUST BE POSITIVE")
        ifelse( 0 < omega & omega <=  1, 0.233*omega^2,
        ifelse( 1 < omega & omega <=  3, 0.005*omega^4 - 0.06906*omega^3 + 0.3167*omega^2 - 0.02326*omega,
        ifelse( 3 < omega & omega <= 40, 0.705*sqrt(omega)*log(omega),
        ifelse(40 < omega,               sqrt(3*omega*log(omega) - log(8*pi) - 2/log(omega) - 170),
        NA))))
    }

Я получаю «Предупреждение о создании NaN», если omega=c(1,41), но не если omega=1 или omega=41.

> btilde(1)
[1] 0.233
> btilde(41)
[1] 16.8228
> btilde(c(1,41))
[1]  0.2330 16.8228
Warning message:
In sqrt(3 * omega * log(omega) - log(8 * pi) - 2/log(omega) - 170) :
  NaNs produced

Если условие "> 40" применяется к "omega = 1", тогда да, я бы получил NaN, но это не так, как работает ifelse(), верно?Может ли кто-нибудь помочь мне понять, что происходит?Спасибо!

Ответы [ 2 ]

0 голосов
/ 20 декабря 2018

Я бы порекомендовал вам сосредоточиться на одном элементе вашего алгоритма, а затем map вашей функции в списке.Это еще одна версия вашего метода без предупреждений:

library(purrr)

btilde <- function(omega) {
  if (omega <= 0) stop("ALL ELEMENTS OF OMEGA MUST BE POSITIVE")
  if (omega <= 1) return (0.233*omega^2)
  if (omega <= 3) return (0.005*omega^4 - 0.06906*omega^3 + 0.3167*omega^2 - 0.02326*omega)
  if (omega <= 40) return(0.705*sqrt(omega)*log(omega))
  return(sqrt(3*omega*log(omega) - log(8*pi) - 2/log(omega) - 170))
}

Следующий вывод:

> map_dbl(c(1,41), ~ btilde(.x))
[1]  0.2330 16.8228
0 голосов
/ 20 декабря 2018

На странице справки ifelse

«да» будет оцениваться тогда и только тогда, когда какой-либо элемент «теста» имеет значение «истина», и аналогично «нет».

Таким образом, выражение вычисляется, даже если отдельный элемент равен FALSE, если любой другой элемент равен TRUE.Рассмотрим простой пример

x = c(0, -1) 
ifelse(x == 0, sqrt(x), x)

[1]  0 -1
Warning message:
In sqrt(x) : NaNs produced

, который выдает предупреждение, подобное вашему коду.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...