【问题标题】:If observe warning, skip iteration in for loop [R]如果观察到警告,则在 for 循环 [R] 中跳过迭代
【发布时间】:2021-04-26 03:40:03
【问题描述】:

我有一些循环计算一个值。有时该计算会触发警告。如何检查是否触发了警告,然后跳过该迭代?我正在使用 R。

在 cmets 的帮助下,我找到了 tryCatch() 并且能够将我的 for 循环修改如下并正常工作:

for (i in seq(1,100,1)){
    x<-sample(1:length(df$values), 1)
    input<-copy_df[x:x+5,]
    val<-tryCatch(myfunc(input$colA), warning=function(w) w)
    if (is(val,warning){ 
        next
    }
    print(paste0(i))
}

val 的输出应该是长度为 5 的列。

【问题讨论】:

  • 查看?Control 帮助页面。 for 循环有一个 next 关键字来移动到下一次迭代。但一般来说,如果您包含一个简单的reproducible example,其中包含可用于测试和验证可能解决方案的示例输入和所需输出,则更容易为您提供帮助。
  • 查看其他副本以了解如何检查警告:stackoverflow.com/questions/3903157/…
  • 很难检测到警告发生的位置,因为每次迭代循环时我都会通过随机观察。因此,很难调试和创建可重现的示例。我要求的功能与 myfunc() 无关,但更多处理 warnings()。
  • 只需将tryCatch 包裹在任何可能产生警告的地方。

标签: r for-loop try-catch


【解决方案1】:

这是一个使用随机生成警告的测试函数的完整示例

set.seed(101)
foo <- function() {
  x <- runif(1)
  if(x<.9) warning("low x")
  x
}
for(i in 1:20) {
  didwarn <- tryCatch({x <- foo(); FALSE}, warning = function(w) return(TRUE))
  if(didwarn) {
    next
  }
  print(paste("high x", x))
}

您将任何可能触发警告的代码包装在 try catch 中。在这里,我们让每个块根据是否抛出错误返回 TRUE 或 FALSE。没有下一个更简单的方法是

for(i in 1:20) {
  tryCatch({
      x <- foo(); 
      print(paste("high x", x))
    }, 
    warning = function(w) {
      # do nothing
    })
}

当警告发生时,tryCatch 表达式中的任何其他内容都不会运行

【讨论】:

    猜你喜欢
    • 2021-11-15
    • 1970-01-01
    • 2019-05-17
    • 1970-01-01
    • 2015-08-20
    • 1970-01-01
    • 2021-08-23
    相关资源
    最近更新 更多