Функция не должна возвращать значение, если оно не существует в функции - PullRequest
0 голосов
/ 23 марта 2020

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

Что мне здесь не хватает? Что я делаю не так?

Пример:

xyz <- function(x = NULL, y = NULL)
{
  if (x+y > 10) {z <- x + y}

  return(z)
}

Если я сейчас запускаю test <- xyz(20, 30), я получаю правильный результат (test = 50). Если я запускаю test <- xyz(2, 3), я также правильно получаю ошибку:

Ошибка в xyz (2, 3): объект 'z' не найден

Однако теперь я Я создаю значение z в глобальной среде.

z <- 3.14

Когда я сейчас запускаю свою функцию test <- xyz(2, 3), в результате я получаю 3.14.

Я ожидал, что функция будет вернуть значение z только в том случае, если оно существует внутри функции. Как я могу это сделать?

Спасибо

Ответы [ 3 ]

3 голосов
/ 23 марта 2020

Почему бы просто не выдать информативную ошибку, основанную на условии, а не z?

xyz <- function(x = NULL, y = NULL)
{
    if ( x + y <= 10 ) {
        stop("The sum of x and y must be greater than 10.")
    }
    return(x + y)
}

xyz(20, 30)
# [1] 50
xyz(2, 3)
# Error in xyz(2, 3) : The sum of x and y must be greater than 10.
3 голосов
/ 23 марта 2020

Если к функции доступна свободная переменная (одна из которых упоминается, но не определена), она просматривает среду, в которой была определена функция, а затем родительскую среду и т. Д.

Использование get("z", inherits = FALSE) для поиска z только в текущей среде или проверки, существует ли exists("z", inherits = FALSE) только в текущей среде.

Другая возможность - всегда давать z значение:

z <- if (length(x) && length(y) && x + y > 10) x + y

В этом случае z будет иметь значение NULL, если условие ложно, потому что по умолчанию else leg равен NULL. Возвращение NULL невидимым было бы как можно ближе к тому, чтобы не возвращать значение.

xyz2 <- function(x = NULL, y = NULL) {
  z <- if (length(x) && length(y) && x + y > 10) x + y
  # other processing can go here
  if (is.null(z)) invisible(z) else z
}
xyz2(1, 2)
xyz2(5, 9)
## [1] 14
2 голосов
/ 23 марта 2020

Мне нравится идея Duckmayr, но вот как вы можете реализовать, все еще используя z:

xyz <- function(x = NULL, y = NULL) {
    z = x + y
    if (z <= 10 ) {
        stop("The sum of x and y must be greater than 10.")
    }
    return(z)
}
...