R语言嵌套调用函数时如何让警告正确显示原函数名
问题根源
purrr::map()运行时会把传入的目标函数包装成内部通用函数.f执行,R生成警告时默认抓取最近一层的调用名称,就会显示成.f(.x[[i]], ...),识别不到实际被调用的square_x。
解决方法
方法1:修改底层函数的warning配置(最稳妥,不受外层调用影响)
直接在square_x的warning()调用里指定call参数,强制警告标注来源为当前函数,不管外层用什么高阶函数包装,都不会出现来源丢失的问题。
如果要完全匹配你预期的In square_x : x < 0输出格式,代码改法如下:
square_x <- function(x) { if(x < 0) { warning("x < 0", call. = quote(square_x)) } x^2 } use_square_x_on_vector <- function(vector) { map(vector, square_x) } # 测试运行 use_square_x_on_vector(-1:1)
运行后警告输出完全符合要求:
Warning message: In square_x : x < 0
如果不需要严格匹配格式,也可以把call参数设为sys.call(),会自动带上当前函数的入参信息,同样会明确显示来源是square_x。
方法2:调整map传参写法(无需修改底层函数)
如果不想改动square_x的原有代码,可以在map里写显式的匿名函数调用,避免函数被purrr包装成内部.f:
use_square_x_on_vector <- function(vector) { map(vector, function(x) square_x(x)) }
这种写法的缺点是稳定性差,如果外层再套其他高阶函数,还是可能出现警告来源丢失的问题。
方法3:开启完整调用栈打印(不推荐)
如果不想修改任何业务代码,可以运行前执行options(keep.source = TRUE, warn = 1)配合调用链跟踪,会打印完整的警告调用链路,但输出信息冗余,日常调试之外不建议使用。
内容的提问来源于stack exchange,提问作者latorious
相关产品推荐
相关产品推荐

