如何让lapply循环中R函数的警告与消息按循环实时输出
R语言:实现lapply中警告的实时输出
你定义了如下test函数,循环到i=3时输出警告并终止循环,其余情况输出对应数值消息。单独调用时消息与警告可正常实时输出,但放入lapply批量调用时,所有警告会在最后批量输出,无法随每个循环实时显示。需实现警告与消息按每个lapply循环实时输出,达到指定效果。
原函数代码
test <- function(x) { for (i in 1:5) { if (i == 3) { warning("test") break() } if (i != 3) { message(i) } } }
现有输出对比
单独调用输出
test(1) 1 2 Warning message: test
当前lapply调用输出
lapply(1:2, test) 1 2 1 2 [[1]] NULL [[2]] NULL Warning messages: 1: In FUN(X[[i]], ...) : test 2: In FUN(X[[i]], ...) : test
期望输出
1 2 Warning messages: 1: In FUN(X[[i]], ...) : test 1 2 Warning messages: 1: In FUN(X[[i]], ...) : test [[1]] NULL [[2]] NULL
解决方法
R的lapply默认会捕获警告并统一延后输出,要实现实时输出,需主动干预警告的处理逻辑,有两种可行方案:
方案1:修改原函数,强制警告即时输出
在warning函数中添加immediate. = TRUE参数,强制警告即时输出,而非被lapply缓存。同时保留原逻辑:
test <- function(x) { for (i in 1:5) { if (i == 3) { warning("test", immediate. = TRUE) break() } if (i != 3) { message(i) } } }
调用lapply(1:2, test)即可得到期望的实时输出效果。
方案2:不修改原函数,在lapply中包装处理
如果不想改动原test函数,可在lapply的匿名函数中用withCallingHandlers捕获警告并即时打印,同时屏蔽后续的批量输出:
lapply(1:2, function(x) { withCallingHandlers( test(x), warning = function(w) { cat("Warning messages:\n1: In FUN(X[[i]], ...) : test\n") invokeRestart("muffleWarning") # 阻止警告被缓存到最后 } ) })
此方式同样能让每个循环的警告实时输出,与消息的顺序匹配。
内容的提问来源于stack exchange,提问作者deschen
相关产品推荐
相关产品推荐

