使用%dofuture%执行system2时遭遇文件未找到警告的技术求助
问题描述
尝试使用%dofuture%功能时出现文件找不到警告,其余执行方式均正常:
- 加载
foreach、doParallel、doFuture包后,设置plan(multisession, workers=availableCores()) - 指定下载目录为工作路径后,直接运行
system2、通过%do%、%dopar%调用Example1.bat都能正常执行 - 但使用
%dofuture%时,出现警告:In system2(paste0("Example", i, ".bat")) : '"Example1.bat"' not found
复现代码:
library(foreach) library(doParallel) library(doFuture) plan(multisession, workers=availableCores()) # 请在下载文件夹创建名为Example1.bat的文件,内容如下: # @ECHO OFF # ECHO Such a useful reproducible code... Folder.Path <- "C:/Users/Insert.Name.Here/Downloads/" setwd(Folder.Path) system2("Example1.bat") # 正常运行 foreach(i=1)%do%{system2(paste0("Example",i,".bat"))} # 正常运行 foreach(i=1)%dopar%{system2(paste0("Example",i,".bat"))} # 正常运行 foreach(i=1)%dofuture%{system2(paste0("Example",i,".bat"))} # 出现警告
问题原因
doFuture使用的multisession类型workers是独立启动的子进程,这些子进程不会继承主进程通过setwd()设置的工作目录,而是使用R默认的启动目录(如用户文档目录或R安装目录)。而%do%是在主进程内串行执行,%dopar%(搭配doParallel)会默认传递主进程的工作目录给子进程,所以这两种方式能找到bat文件,%dofuture%的子进程却找不到。
解决办法
三种可行方案任选其一即可:
1. 使用bat文件的绝对路径
不依赖当前工作目录,直接传入bat文件的完整路径:
foreach(i=1)%dofuture%{ bat_path <- file.path(Folder.Path, paste0("Example", i, ".bat")) system2(bat_path) }
2. 在%dofuture%代码块内显式设置工作目录
在子进程执行命令前,手动切换到目标目录:
foreach(i=1)%dofuture%{ setwd(Folder.Path) system2(paste0("Example",i,".bat")) }
3. 配置future让子进程继承主进程的工作目录
通过future.options参数,让multisession workers继承主进程的工作目录:
plan(multisession, workers=availableCores(), future.options = list(wd = getwd())) # 之后执行%dofuture%代码即可正常运行 foreach(i=1)%dofuture%{system2(paste0("Example",i,".bat"))}
内容的提问来源于stack exchange,提问作者Maize Blue
相关产品推荐
相关产品推荐

