Остановите оценку функции, используя другую функцию в R
Я сделал тест с вложенным return
функция в R, но без успеха. Я пришел из Mathematica, где этот код работает хорошо. Вот игрушечный код:
fstop <- function(x){
if(x>0) return(return("Positive Number"))
}
f <- function(x){
fstop(x)
"Negative or Zero Number"
}
Если я оцениваю f(1)
, Я получил:
[1] "Negative or Zero Number"
Когда я ожидал всего лишь:
[1] "Positive Number"
Вопрос: есть некоторая нестандартная оценка, которую я могу сделать в fstop
так что я могу просто fstop
результат, без изменений f
функционировать?
PS: я знаю, что могу поставить if
прямо внутри f
, но в моем реальном случае структура не так проста, и эта структура сделает мой код проще.
2 ответа
Собираюсь высунуть мне шею и сказать...
Нет.
Возвращение функции не к вызывающей стороне, а к вызывающей ее вызывающей стороне будет означать изменение контекста выполнения. Вот как такие вещи, как return
и другие вещи потока управления реализованы в источнике. Увидеть:
https://github.com/wch/r-source/blob/trunk/src/main/context.c
Я не думаю, что код уровня R имеет доступ к контекстам выполнения, подобным этому. Может быть, вы могли бы написать некоторый код уровня C, который мог бы это сделать, но это не ясно. Вы всегда можете написать do_return_return
функция в стиле do_return
в eval.c
и создать собственную версию R... Это не стоит.
Таким образом, ответ, скорее всего, "нет".
Я думаю, что Spacedman прав, но если вы хотите оценить свои выражения в обертке, то это возможно, используя tryCatch
механизм вырваться из стека оценки.
Во-первых, нам нужно определить специальный RETURN
функция:
RETURN <- function(x) {
cond <- simpleCondition("") # dummy message required
class(cond) <- c("specialReturn", class(cond))
attr(cond, "value") <- x
signalCondition(cond)
}
Затем мы переписываем ваши функции, чтобы использовать наши новые RETURN
:
f <- function(x) {
fstop(x)
"Negative or Zero"
}
fstop <- function(x) if(x > 0) RETURN("Positive Number") # Note `RETURN` not `return`
Наконец, нам нужна функция-обертка (здесь wsr означает "со специальным возвратом") для оценки наших выражений:
wsr <- function(x) {
tryCatch(
eval(substitute(x), envir=parent.frame()),
specialReturn=function(e) attr(e, "value")
) }
Затем:
wsr(f(-5))
# [1] "Negative or Zero"
wsr(f(5))
# [1] "Positive Number"
Очевидно, это немного глупо, но повседневное использование не сильно отличается от оценки выражений в with
или вызывающий код с source
, Один недостаток в том, что он всегда вернется на тот уровень, который вы называете wsr
от.