R:foreach、%dopar% 和来源

R : foreach, %dopar%, and source

我正在接管专为 运行 其他脚本制作的脚本。用于执行此操作的代码如下:

cl <- makeCluster(detectCores() - 1)
registerDoParallel(cl, cores = detectCores() - 1)

dopar_output <- foreach(x=listExec, .errorhandling = "pass") %dopar% {
  source(x)
}

listExec 是一个具有各种脚本路径的向量。

我一直在尝试更新它以传递一个变量,其中包含脚本的名称,以便在每次脚本执行期间用于日志目的,如下所示:

dopar_output <- foreach(x=listExec, .errorhandling = "pass") %dopar% {
  Script <- basename(gsub(".R","",x))      
  source(x)
}

目标是在每个脚本 运行 时在环境中提供一个 "Script" 变量,以确保脚本的名称和日志中使用的名称相同。 但是,对于上面的代码,脚本变量写在列表 dopar_output 中,我不能使用它(或者至少我不知道如何使用)。

我愿意接受任何建议,我的第一次尝试是使用以下命令在每个脚本中声明脚本变量:

basename(sys.frame(1)$ofile)

但是,这在我的环境中似乎无法正常工作,因为: 该脚本 运行 由主脚本 运行 通过 Cron 作业在 Unix 服务器上完成。

您可以使用 system(...) 调用通过 commandArgs(...)

传递参数
# script1.R
val <- commandArgs(trailingOnly=TRUE)
writeLines(val, "out1.txt")

# script2.R
val <- commandArgs(trailingOnly=TRUE)
writeLines(val, "out2.txt")    

定义 arg

listExec <- c("script1.R", "script2.R")
dopar_output <- foreach(x=listExec, .errorhandling = "pass") %dopar% {
  arg <- basename(gsub(".R", "", x))
  system(paste("Rscript", x, arg))
}

out1out2

中输出
# out1.txt
# script1

# out2.txt
# script2

CPak 解决方案有效。仅作记录,我发现了另一种与 source 一起使用的方法: 在您想要获得 name/fullpath 的任何脚本中使用以下函数:

get.full.path.to.this.sourced.script = function() {    
  for(i in sys.nframe():1) {  # Go through all the call frames,
    # in *reverse* order.
    x = sys.frame(i)$ofile
    if(!is.null(x))               # if $ofile exists,
      return(normalizePath(x))  #  then return the full absolute path
  }
}