在R包中使用future实现异步时无法找到自定义函数的解决方案求助
解决future无法识别开发中R包内函数的问题
问题背景
开发R包testpkg时,尝试用future实现异步运行,遇到报错:Error: there is no package called ‘testpkg’。已知可通过给future环境逐个赋值函数解决,但我的场景包含大量依赖自定义函数的对象,逐个赋值过于繁琐,需要能让future识别包内所有函数的简便方法。
测试包结构
testpkg/ ├── DESCRIPTION ├── NAMESPACE ├── R │ └── do_stuff.R ├── man │ └── do_stuff.Rd └── testpkg.Rproj
核心函数代码(do_stuff.R)
#' A function that clearly does stuff #' @export do_stuff <- function() { Sys.sleep(1) "Done" }
测试代码
devtools::load_all() library(future) plan(multisession) val %<-% do_stuff() val
解决方案
方法1:用devtools::load_all的export_all参数加载包
devtools::load_all(export_all = TRUE)会将包内所有对象(包括未导出的)加载到当前环境,让future子进程能直接访问:
devtools::load_all(export_all = TRUE) library(future) plan(multisession) val %<-% do_stuff() val
方法2:显式指定future的全局环境为包命名空间
将future的全局变量设置为包的命名空间环境,子进程会直接从包命名空间查找函数:
devtools::load_all() library(future) # 方式一:传递包名到全局变量 plan(multisession, globals = list(.packageName = "testpkg")) # 方式二:直接传入包命名空间 plan(multisession, globals = asNamespace("testpkg")) val %<-% do_stuff() val
方法3:调用函数时显式添加包名前缀
在异步调用中用包名::函数名的方式,直接从命名空间引用函数,无需子进程加载整个包:
devtools::load_all() library(future) plan(multisession) val %<-% testpkg::do_stuff() val
方法4:全局设置future的包依赖
通过futureOptions全局配置,将包的命名空间加入全局变量池,所有future任务都能自动访问:
devtools::load_all() library(future) futureOptions(globals = list("testpkg" = asNamespace("testpkg"))) plan(multisession) val %<-% do_stuff() val
内容的提问来源于stack exchange,提问作者Will Hipson
相关产品推荐
相关产品推荐

