R:foreach,%dopar%和来源

时间:2018-04-18 14:21:36

标签: r cron doparallel parallel-foreach

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

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列表中,我无法使用它(或者至少我不知道如何)。

我对任何建议持开放态度,我的第一次尝试是使用以下命令在每个脚本中声明Script变量:

basename(sys.frame(1)$ofile)

但是,在我的环境中似乎没有正常工作,因为: 该脚本由一个主脚本运行,该脚本本身通过Unix服务器上的Cron作业运行。

2 个答案:

答案 0 :(得分:0)

您可以使用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

答案 1 :(得分:0)

CPak解决方案有效。只是为了记录,我找到了另一种适用于源的方法: 在任何想要获取名称/完整路径的脚本中使用以下函数:

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
  }
}