如何让rlang::warn()生成的警告实现即时输出?
如何让rlang::warn()即时输出警告
当在函数中使用rlang包的rlang::warn()生成警告时,警告会延迟到函数返回结果后才显示,示例如下:
delayed_warning <- function() { rlang::warn("A warning") Sys.sleep(10) "A return value" } delayed_warning() #> Warning: A warning #> [1] "A return value"
(示例创建于2023-09-18,使用reprex v2.0.2)
在需要提前告知用户函数可能耗时较长的场景下,即时输出警告十分有用。base R的warning()可通过设置immediate.=TRUE实现即时输出,那么rlang::warn()有没有办法实现同样的效果?
解决方案
有两种常用方法可以实现rlang::warn()的即时警告输出:
方法一:给警告条件添加immediate属性
手动构造警告条件并赋予immediate = TRUE属性,再通过rlang::warn()抛出:
delayed_warning_immediate <- function() { # 构造带即时属性的警告条件 warn_cond <- rlang::condition( message = "A warning", class = c("warning", "rlang_warning"), immediate = TRUE ) rlang::warn(warn_cond) Sys.sleep(10) "A return value" } delayed_warning_immediate()
执行这个函数时,警告会在Sys.sleep(10)执行前立刻显示,不会等到函数返回结果。
方法二:结合base::warning()的即时参数
利用rlang::with_abort()让base R的警告兼容rlang的错误处理体系,同时启用即时输出:
delayed_warning_immediate2 <- function() { rlang::with_abort({ base::warning("A warning", immediate.=TRUE) }) Sys.sleep(10) "A return value" } delayed_warning_immediate2()
这种方式既保留了rlang的错误处理逻辑,又实现了警告的即时输出。
本质上,rlang的警告最终会调用base R的警告处理机制,只要给警告条件添加immediate属性,就能触发即时输出的行为。
内容的提问来源于stack exchange,提问作者Matt Ashby
相关产品推荐
相关产品推荐

