使用furrr库时options(warn=2)与tryCatch()导致结果不一致的问题
问题
为什么以下代码直接调用和用furrr多会话调用会得到不同结果?
代码定义:
library(furrr) fu <- function(x){ options(warn = 2) b <- x tryCatch({b <- as.numeric('b')}, error = function(e){}) options(warn = 0) return(data.frame(b)) }
- 直接调用:
fu(1:10),返回结果为1 2 3 4 5 6 7 8 9 10 - 多会话调用:
返回结果为plan(multisession, workers = 5) future_map_dfr(.x = 1:10, .f = fu) plan(sequential)NA NA NA NA NA NA NA NA NA NA
注意:请勿使用RStudio 2025.05.0+496版本测试,该版本存在options(warn=2)相关已知bug。预期结果中b应为1到10。
原因与修复
问题根源
函数内全局修改options(warn=2)的操作,在多会话环境中干扰了future框架的变量传递机制:
- 直接调用时,
as.numeric('b')触发的是错误,tryCatch能正常捕获,b保留初始值x,最后options(warn=0)也能正常恢复设置。 - 多会话模式下,每个worker是独立的R进程,函数内修改全局
options后,恢复warn=0的操作可能未在worker进程中正确生效,导致后续变量序列化/反序列化过程中出现的警告被强制转为错误,最终使得b的值被覆盖为NA。
修复方案
避免在函数内全局修改options,如果需要将警告转为错误,针对特定代码块局部处理即可:
方案1:局部处理警告转错误
library(furrr) fu <- function(x){ b <- x # 仅在目标代码块内将警告转为错误 withCallingHandlers( expr = tryCatch({b <- as.numeric('b')}, error = function(e){}), warning = function(w) stop(w) ) return(data.frame(b)) }
方案2:移除不必要的options设置
实际上as.numeric('b')本身就是错误,不需要通过warn=2来处理,直接保留tryCatch即可:
library(furrr) fu <- function(x){ b <- x tryCatch({b <- as.numeric('b')}, error = function(e){}) return(data.frame(b)) }
两种方案都能保证直接调用和多会话调用得到相同的预期结果。
内容的提问来源于stack exchange,提问作者S.T.
相关产品推荐
相关产品推荐

