【问题标题】:tryCatch within for loopfor 循环中的 tryCatch
【发布时间】:2020-03-23 20:50:33
【问题描述】:

我是 R 新手,我已经检查了大多数在线链接,但我无法解决问题。 这是我正在做的蒙特卡罗模拟的可重现示例:

rm(list = ls())
x=c(-2,3,-1,4,'A')
y=rep(0,5)

for(i in 1:5){
  tryCatch(
    expr = {
      y[i]=log(x[i])
    },
    error = function(e){
      message('Caught an error!',i)
      return(NA)
    },
    warning = function(w){
      message('Caught an warning!',i)
      return(NA)
    }
  ) 

}

请问如何修复代码,以便在 for 循环结束时,R 将 y 的值返回为

y= NA,log(3),NA,log(4),NA
i=1,3,5

以及出现错误或警告的 i 的值。 也就是说,错误和警告被替换为 NA 并返回成功的评估,并且还返回出现错误或警告的 i 的值。

谢谢

【问题讨论】:

    标签: r for-loop error-handling try-catch warnings


    【解决方案1】:

    NA 初始化y,然后运行for 循环。另外,由于x 是一个向量,并且向量只能包含一个类,所以x 中的所有数字都转换为字符,因为x 中有非数字元素,因此您需要在获取log 之前将它们转换为数字。

    x=c(-2,3,-1,4,'A')
    y=rep(NA,5)
    
    for(i in 1:5){
      tryCatch(
        expr = {
          y[i]= log(as.numeric(x[i]))
        },
      error = function(e){
          message('Caught an error!',i)
       },
      warning = function(w){
          message('Caught a warning! ',i)
        }
      ) 
    }
    #Caught a warning! 1
    #Caught a warning! 3
    #Caught a warning! 5
    
    y
    #[1]       NA 1.098612       NA 1.386294       NA
    

    然后使用is.nawhich 来获取发生错误或警告的索引。

    which(is.na(y))
    #[1] 1 3 5
    

    当然,你也可以不使用for 循环来实现这一点

    y <- log(as.numeric(x))
    which(is.na(y))
    #[1] 1 3 5
    

    return基于错误或警告的不同值,我们可以把它做成一个函数

    run_fun <- function(x) {
       tryCatch(
         expr = {
          return(log(as.numeric(x)))
         },
         error = function(e){
           message('Caught an error!',i)
           return(100)
          },
          warning = function(w){
            message('Caught a warning! ',i)
            return(200)
           }
          ) 
     }
    

    然后在for循环中调用它。

    for (i in seq_along(x)) {
       y[i] <- run_fun(x[i])
    }
    
    y
    #[1] 200.0000   1.0986 200.0000   1.3863 200.0000
    

    【讨论】:

    • 感谢您的帮助。请问有两个问题:1.如果出现错误或警告,是否有指定的方式来返回特定的数字选择?比如说,返回 100 表示错误,返回 200 表示警告? 2、为什么要用as.numeric(),因为我想替换tryCatch的expr部分下的一堆优化代码?
    • @dms 1) 是的,您可以将其更改为函数并返回您想要的任何值。请参阅我更新答案的最后一部分。 2)如果你检查class(x)你会看到它是类字符,你不能取log的字符值,因此你需要用as.numeric将它转换成数字。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-20
    • 2019-04-15
    • 2017-06-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多