代码之家  ›  专栏  ›  技术社区  ›  Jacob Nelson

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

  •  1
  • Jacob Nelson  · 技术社区  · 7 年前

    我有R代码,有时返回 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-repeat表达式?

    1 回复  |  直到 7 年前
        1
  •  2
  •   G. Grothendieck    7 年前

    (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 即使没有功能也可以工作:

    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