在 R 中使用 tryCatch 抑制警告

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

我想做什么

编写一个

tryCatch
来处理错误值但忽略警告。举个例子

foo <- function(x) {
  if (x == 1) {
    warning('Warning')
  } else if (x == 0) {
    stop('Error')
  }
  return(1)
}

bar <- function(x){
  tryCatch(
    expr    = foo(x),
    error   = identity,
    warning = function(w) invokeRestart("muffleWarning")
  )
}

因此,如果您传递 0,

foo
会发出警告,如果您传递 1,则会出现错误。
bar
的目的是,如果您传递 0,则会出现错误,但它会抑制
bar
生成的警告,如果你传递一个 1。
invokeRestart("muffleWarning")
命令来自
suppressWarnings
的定义。它在我这里的建筑中不起作用,我不知道为什么。 (讽刺的是,它会生成一个错误,因此尝试成功地将我不想要的警告升级为我无法解释的错误。)

我不想使用愚蠢的答案(TM),为什么

bar
的这个定义将会起作用

bar <- function(x){
  tryCatch(
    expr    = foo(x),
    error   = SomeFunctionThatDoesNotMatter,
    warning = function(w){suppressWarnings(foo(x))}
  )
}

bar
完全符合我的要求,但它以一种可能很糟糕的方式实现。想象一下,我有
expr = foo(x)
,而不是我这里的
expr = lapply(X=1:50, ...)
,并且
FUN
需要一个小时才能运行。如果
X[50]
生成唯一的警告,那么我的运行时间就会翻倍,从 50 小时增加到 100 小时(恶心)。

问题

  1. 为什么
    invokeRestart("muffleWarning")
    在我上面的示例中不起作用?
  2. 使用
    tryCatch
    时,应该为
    warning
    分配什么函数,以便让代码继续运行并抑制生成的警告?

感谢您的阅读!

r try-catch suppress-warnings
2个回答
2
投票

我遵循 nrussell 的直觉后遇到了这个问题。解决办法就是更换通用的

tryCatch({
  some_fn()
}, warning = function(w) {
  print(paste('warning:', w))
}, error = function(e) {
  print(paste('error:', e))
})

tryCatch({
  some_fn()
}, error = function(e) {
  print(paste('error:', e))
})

这种格式/语法对我有用。您可以轻松地将其包含在您需要的函数中


0
投票

以下内容应该可以解决您的问题。事实上,这个解决方案更通用,并且希望能够让 R 中的错误处理更加清晰。

考虑以下问题:您想要计算 expr fun()。 fun() 是一个内置函数,因此您无法控制它。令人讨厌的是 fun() 返回一个警告,理想情况下您希望抑制该警告。

下面的代码片段可能无法按预期工作:

tryCatch(fun(),
         warnings = function(w){},
         error = function(e){print("Error message")})

问题是警告或错误没有显示。当警告在内置函数 fun() 中显示为 finally 语句时,可能会发生这种情况。

不幸的是,try语句中的静默选项也不会抑制警告...所以运行下面的代码时仍然会弹出警告

expr = try(fun(), silent = T)
if(inherits(expr, "try-error")){print("Error Message")}

以下(聪明?)替代方案也不起作用

expr = suppressWarnings(try(fun()))
if(inherits(expr, "try-error")){print("Error Message")}

现在的问题是 expr 属于 NULL 类,不再是尝试错误

最后,以下内容确实规避了上述所有问题,同时为程序员留下了高度的灵活性(以向环境分配中间对象为代价)

  suppressWarnings(b <<- try(fun(), silent = T))
  if(inherits(b, "try-error")){print("Error Message")}
  } else{print("No error message")}

最后一个表达式应该可以解决您的问题,并避免根据需要重新运行代码

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