From ?options
, the description of warn
said
If 10 or fewer warnings were signalled, they will be printed, otherwise a message saying how many were signalled.
So if there are more than 10 warnings, they will be compressed into 1 message. For example:
f <- function() {
warning("warn 1")
warning("warn 2")
warning("warn 3")
warning("warn 4")
warning("warn 5")
warning("warn 6")
warning("warn 7")
warning("warn 8")
warning("warn 9")
warning("warn 10")
warning("warn 11")
return(1)
}
f()
[1] 1
There were 11 warnings (use warnings() to see them)
How can I reduce the limit of 10 to 1? I.e. Even if I have only one warning, I expect it to show
There were 1 warnings (use warnings() to see them)
Couldn't find an option to globally set this threshold to a custom value (might be a nice feature request you could discuss on r-devel). Instead, you could use a wrapper function to summarize warnings where needed. We'd need an environment since---for good reason---'last.warning'
is read-only.
W <- \(FUN) {
env <- new.env()
env$w_lst <- list() ## empty warning list to increment
res <- withCallingHandlers(FUN, warning=\(w) {
env$w_lst <- c(env$w_lst, list(w))
invokeRestart('muffleWarning')
})
n <- length(env$w_lst) ## count warnings
if (n > 0) {
more <- (n > 1L) + 1L
msg <- sprintf('There %s %s warning%s (use warnings2() to see %s)',
switch(more, 'was', 'were'),
n,
switch(more, '', 's'),
switch(more, 'it', 'them')
)
message('Warning: ', msg)
assign('last.warning', env$w_lst, envir=warn_env) ## assign warnings to env
}
res
}
## alternative warnings function
warnings2 <- \() {
if (exists("last.warning", envir=warn_env)) {
w_lst <- get("last.warning", envir=warn_env)
for (i in seq_along(w_lst)) {
message(sprintf('Warning %d: %s', i, conditionMessage(w_lst[[i]])))
}
} else {
base::warnings()
}
}
> warn_env <- new.env() ## create env for 'last.waning'
>
> W(f(0))
[1] 1
> W(f(1))
Warning: There was 1 warning (use warnings2() to see it)
[1] 1
> W(f(2))
Warning: There were 2 warnings (use warnings2() to see them)
[1] 1
> W(f(11))
Warning: There were 11 warnings (use warnings2() to see them)
[1] 1
>
> warnings2()
Warning 1: foo
Warning 2: foo
Warning 3: foo
Warning 4: foo
Warning 5: foo
Warning 6: foo
Warning 7: foo
Warning 8: foo
Warning 9: foo
Warning 10: foo
Warning 11: foo
Data:
f <- \(n) {
replicate(n, warning('foo'))
return(1)
}