多次尝试一个表达式,直到在 R 中成功

问题描述 投票:0回答:2

我的 R 代码有时会返回

NA
,这会导致下游错误。 然而,它失败的唯一原因是随机数不好。使用不同的起点再次运行该表达式,它生成的结果不是
NA

我设置了一个

while
循环,在放弃之前多次尝试该表达式。这是一个例子:

attempts <- 0
x <- NA
while(is.na(x) & attempts < 100) {
     attempts <- attempts + 1
     rand <- runif(1)
     x <- ifelse(rand > 0.3, rand, NA)
}
if(attempts == 100) stop("My R code failed")
x

我不喜欢这太笨重了。

是否有函数、包或方法可以帮助简化这个 try-repeat-try-again 表达式?

r error-handling try-catch
2个回答
2
投票

1) 我们可以将其变成一个函数,如果找到一个则返回

x
,如果没有则停止。 我们还使用
for
代替
while
,使用
if
代替
ifelse

retry <- function() {
  for(i in 1:100) {
    rand <- runif(1)
    x <- if (rand > 0.3) rand else NA
    if (!is.na(x)) return(x)
  }
  stop("x is NA")
}

retry()

2) 或者如果您不想在函数中停止,则删除

stop
行,将其替换为返回 x 的行,然后使用它(尽管它确实涉及测试 x 的 NA 两次):

x <- retry()
if (is.na(x)) stop("x is NA")

3) 或另一种选择是将错误值传递给函数。 由于惰性评估,

bad
参数仅在实际上不好时才被评估:

retry2 <- function(bad) {
  for(i in 1:100) {
    rand <- runif(1)
    x <- if (rand > 0.3) rand else NA
    if (!is.na(x)) return(x)
  }
  bad
}

retry2(stop("x is NA"))

4) 如果您不介意使用

break
测试 x 的 NA 两次,即使没有函数也可以工作:

for(i in 1:100) {
  rand <- runif(1)
  x <- if (rand > 0.3) rand else NA
  if (!is.na(x)) break
}
if (is.na(x)) stop("x is NA")
x

0
投票

我使用

retry
包做了一些类似的事情,取得了一些成功,该包具有重复运行代码直到满足某些条件的功能。

https://cran.r-project.org/package=retry

我的情况与你的有点不同,因为我生成/发送电子邮件的代码会定期失败,所以我想重新运行它,直到返回条件不为 NULL。

retry::retry({
  # original code to compose an email,
  # add some attachments and then send 
},
until = \(val, condition) { is.null(condition) },
max_tries = 10)

我想如果你改变

until
函数,你可以测试返回值,例如

until = \(val, condition) { !is.na(val) }

© www.soinside.com 2019 - 2024. All rights reserved.