根据它们在警告列表中的位置或基于 R 中的正则表达式来抑制警告

Suppress warning based on their position in warning list or based on a regular expression in R

我使用的一个函数可以 return 警告:第一个警告总是发生,我不关心它。以下警告通常很有趣,因为它们实际上是在警告确实出了问题。

这是我不关心的由我的函数发出的常见警告 return 的示例:

Warning message:
Using alpha for a discrete variable is not advised.

这里现在是一个常见警告的例子 + 我实际上想在它恰好被 returned 时看到的相关警告:

Warning messages:
1: Using alpha for a discrete variable is not advised. 
2: Removed 2 rows containing missing values (geom_point).

我的问题是如何根据第一个警告 (Using alpha for a discrete variable is not advised.) 在警告列表中的位置或使用正则表达式...或任何其他想法来抑制第一个警告 (Using alpha for a discrete variable is not advised.),而不使用其他包比默认 R 的(基础、数据集、图形、统计...)?

到目前为止,我找到的解决方案是使用包 pkgcond v0.1.0,它有自己的 suppress_warnings() 函数。但我真的想避免加载额外的包。

提前感谢您的帮助!

这是一种处理问题的方法,它全部在 base R 中。

让我们从一个returns我们想要的值但在这样做之前会抛出两个警告的函数开始:

make_warnings <- function()
{
  warning("This is a warning that can be ignored")
  warning("This is a warning that shouldn't be ignored")
  return(0)
}

当然,如果我们运行这个,我们会得到警告:

make_warnings()
#> [1] 0
#> Warning messages:
#> 1: In make_warnings() : This is a warning that can be ignored
#> 2: In make_warnings() : This is a warning that shouldn't be ignored

如果我们 运行 suppressWarnings 中的函数,我们只会丢失所有警告,这不是我们想要的。但是我们可以使用 withCallingHandlers,它提供了一个 warning 参数,允许我们指定一个函数,该函数接受生成的每个警告并以编程方式对其进行任何我们喜欢的操作。

我们需要做的就是设置一个函数,使用带 grepl 的正则表达式检查每个警告的内容,如果它与我们的正则表达式匹配,则禁止该警告。

请注意,对于 withCallingHandlers 中捕获的 每个 警告,此函数将被调用一次。我们甚至不需要指定未捕获的警告会发生什么,因为如果它们没有在我们的函数中被特别抑制,它们仍然会向控制台生成警告:

warning_handler <- function(w)
{
  condition <- conditionMessage(w)
  if(grepl("can be ignored", condition)) invokeRestart("muffleWarning")
}

所以现在我们可以 运行 我们的警告生成函数,只是让我们不关心的警告静音。

withCallingHandlers(make_warnings(), warning = warning_handler)
#> [1] 0
#> Warning message:
#> In make_warnings() : This is a warning that shouldn't be ignored

所以你可以看到我们已经抑制了我们不想看到的警告,但保留了重要的警告。

如果你想让它更灵活,你可以将 withCallingHandlers 和你的处理函数包装成一个以正则表达式作为第一个参数的函数:

with_warning_handler <- function(reg, ...)
{
  withCallingHandlers(..., warning = function(w)
    {
        condition <- conditionMessage(w)
        if(grepl(reg, condition)) invokeRestart("muffleWarning")
  })
}

所以现在你可以这样做:

with_warning_handler("can be ignored", make_warnings())
#> [1] 0
#> Warning message:
#> In make_warnings() : This is a warning that shouldn't be ignored

所以,看一个真实的例子,看看我们用这行代码得到的两个警告:

a <- 1:3; a[] <- as.numeric(c("A", "1"))
#> Warning messages:
#> 1: NAs introduced by coercion 
#> 2: In a[] <- as.numeric(c("A", "1")) :
#>   number of items to replace is not a multiple of replacement length

但如果我们不担心强制转换,我们可以这样做:

with_warning_handler("coercion", {a <- 1:3; a[] <- as.numeric(c("A", "1"))})
#> Warning message:
#> In a[] <- as.numeric(c("A", "1")) :
#>   number of items to replace is not a multiple of replacement length