在 R 中使用 tryCatch 抑制警告

Ada*_*dam 8 r try-catch suppress-warnings

我想做什么

编写一个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")
  )
}
Run Code Online (Sandbox Code Playgroud)

因此foo,如果您传递 0 会警告您,如果您传递 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))}
  )
}
Run Code Online (Sandbox Code Playgroud)

bar完全按照我的意愿去做,但它以一种潜在的可怕方式做到了。想象一下,而不是expr = foo(x)像我在这里那样,我拥有expr = lapply(X=1:50, ...)并且FUN需要一个小时才能运行。如果X[50]生成唯一的警告,那么我的运行时间从 50 小时增加到 100 小时(糟糕)。

问题

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

谢谢阅读!

Bjo*_*fan 2

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

tryCatch({
  some_fn()
}, warning = function(w) {
  print(paste('warning:', w))
}, error = function(e) {
  print(paste('error:', e))
})
Run Code Online (Sandbox Code Playgroud)

tryCatch({
  some_fn()
}, error = function(e) {
  print(paste('error:', e))
})
Run Code Online (Sandbox Code Playgroud)

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