Вот один из способов решения проблемы, и все это в базе R.
Давайте начнем с функции, которая возвращает желаемое значение, но перед этим выдаст два предупреждения:
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