1

我遇到了这个问题,我一生都无法弄清楚如何解决它。

示例前的快速总结:

我有数百个数据集,我希望每天从中创建报告。为了有效地做到这一点,我用doParallel. 在 RStudio 中,该过程运行良好,但是当我尝试通过 Windows 上的任务计划程序使该过程自动化时,我似乎无法让它工作。

RStudio 中的流程是:

我调用一个脚本来获取我所有其他脚本的来源,每个单独的脚本都有一个执行适当包导入的标题部分,例如它看起来像:

get_files <- function(){
  get_files.create_path() -> path
  for(file in path){
   if(!(file.info(paste0(path, file))[['isdir']])){
    source(paste0(path, file))
   }
  }
}

get_files.create_path <- function(){
   return(<path to directory>)
}

#self call
get_files()

这将是简单的“Source on saved”,并将我需要的所有内容都带入.GlobalEnv.

从那里,我可以简单地键入:parallel_report()它调用一个脚本,该脚本获取另一个脚本,该脚本包含报告生成的并行化。前一阵子直接调用并行化有一个问题(我想知道这是否相关?)所以我不得不使doParallel脚本成为一个非功能外壳脚本,因此无法使用get_files将启动的脚本引入每次我把所有东西都带进来时生成报告。因此,我必须将它包含在它自己的脚本中,并将它保存在其他地方以便在必要时调用。该parallel_report()功能将只是:

parallel_report <- function(){
  source(<path to script>)
}

然后,获取的脚本是真正的并行化脚本,看起来像:

doParallel::registerDoParallel(cl = (parallel::detectCores() - 1))
foreach(name = report.list$names,
        .packages = c('tidyverse', 'knitr', 'lubridate', 'stringr', 'rmarkdown'),
        .export = c('generate_report'),
        .errorhandling = 'remove') %dopar% {
  tryCatch(expr = {
    generate_report(name)
  }, error = function(e){
    error_handler(error = e, caller = paste0("generate report for ", name,  " from parallel"), line = 28)
  })
}
doParallel::stopImplicitCluster()

generate_report函数只是一个 .Rmd 和render()调用者:

generate_report <- function(<arguments>){
 #stuff
 generate_report.render(<arguments>)
 #stuff 
}  

generate_report.render <- function(<arguments>){
   rmarkdown::render(
    paste0(data.information@location, 'report_generator.Rmd'),
    params = list(
      name = name,
      date = date,
      thoughts = thoughts, 
      auto = auto),
    output_file = paste0(str_to_upper(stock), '_report_', str_remove_all(date, '-'))
  )
}

回顾一下,在 RStudio 中,我只需执行以下操作:

1 - 源代码保存脚本带来的一切

2 型parallel_report

2.a - 这直接doParallization调用generate_report

2.b -generate_report调用一个.Rmd文件,该文件包含所需的函数调用和生成报告的其他内容

该过程开始并顺利完成。

为了通过任务计划程序使情况自动化,我制作了一个任务计划程序可以调用的脚本,命名为automatic_caller

source(<path to the get_files script>) # this brings in all the scripts and data into the global, just 
# as if it were being done manually
tryCatch(
  expr = {
    parallel_report()
  }, error = function(e){
     error_handler(error = e, caller = "parallel_report from automatic_callng", line = 39)
})

error_handler函数只是一个用于在整个过程中记录错误的内部脚本。

因此,在任务计划的任务上,我先Rscript.exe调用了然后再调用automatic_caller除了报告生成之外,该函数中的所有内容都可以automatic_caller正常工作。该过程几乎自动完成,我得到的唯一输出是一个错误:

"pandoc version 1.12.3 or higher is required and was not found (see the help page ?rmarkdown::pandoc_available)."

但是rmarkdown在 的.export调用范围内,doParallel 并且在显式使用它的脚本中,实际上generate_report是通过 直接调用的rmarkdown::render()

所以 - 我完全不知所措。

想法和建议将不胜感激。

4

1 回答 1

1

因此 pandoc 显然是一个可执行文件,可以帮助将文件从一个扩展名转换为另一个扩展名。RStudio 带有自己的 pandoc 可执行文件,因此当从 RStudio 运行脚本时,它知道何时需要 pandoc。

在命令提示符下,系统不知道查看 RStudio 内部,因此只需将 pandoc 作为独立可执行文件下载即可为系统提供正确的指针。

下载pandoc,一切正常。

于 2021-08-09T02:41:01.373 回答