原因を正確に説明できるかどうかはわかりませんが、問題を切り分けて修正できます。基本的な問題は再帰です: retry(.FUN, max.attempts-1)
- 再帰呼び出しが呼び出すときsubstitute(.FUN)
、値が何であるかを把握するために呼び出しスタックのレベルを上げる必要があります.FUN
- promise の評価を再開する必要があります (関数引数の遅延実行) ) レベルアップ。
修正は、置換を 1 回だけ行うことです。
retry <- function(.FUN, max.attempts = 3, sleep.seconds = 0.5) {
expr <- substitute(.FUN)
retry_expr(expr, max.attempts, sleep.seconds)
}
retry_expr <- function(expr, max.attempts = 3, sleep.seconds = 0.5) {
x <- try(eval(expr))
if(inherits(x, "try-error") && max.attempts > 0) {
Sys.sleep(sleep.seconds)
return(retry_expr(expr, max.attempts - 1))
}
x
}
f <- function() {
x <- runif(1)
if (x < 0.5) stop("Error!") else x
}
retry(f())
柔軟に使える機能を作るために、代替品の使用は最小限にすることを強くお勧めします。私の経験では、通常、置換を行う 1 つの関数と、すべての作業を行う別の関数を用意するのが最善です。これにより、別の関数から呼び出されたときに関数を使用できるようになります。
g1 <- function(fun) {
message("Function starts")
x <- retry(fun)
message("Function ends")
x
}
g1(f())
# Function starts
# Error in eval(expr, envir, enclos) : object 'fun' not found
# Error in eval(expr, envir, enclos) : object 'fun' not found
# Error in eval(expr, envir, enclos) : object 'fun' not found
# Error in eval(expr, envir, enclos) : object 'fun' not found
# Function ends
g2 <- function(fun) {
message("Function starts")
expr <- substitute(fun)
x <- retry_expr(expr)
message("Function ends")
x
}
g2(f())
# Function starts
# Error in f() : Error!
# Function ends
# [1] 0.8079241