如何从命令提示符调用并行脚本?
How to call a parallelized script from command prompt?
我 运行 遇到了这个问题,但我一直想不出如何解决它。
示例前的快速总结:
我有数百个数据集,我希望每天从中创建报告。为了有效地做到这一点,我用 doParallel
并行化了这个过程。在 RStudio 中,该过程运行良好,但是当我尝试通过 windows 上的任务计划程序使该过程自动进行时,我似乎无法让它工作。
RStudio 中的进程是:
我调用一个脚本来获取我所有其他脚本的源代码,每个单独的脚本都有一个 header 部分来执行适当的包导入,例如它看起来像:
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()
这将是简单的“保存时的来源”并将我需要的所有内容引入 .GlobalEnv
。
从那里,我可以简单地键入:parallel_report()
,它调用一个脚本,该脚本提供另一个脚本,该脚本包含报告生成的并行化。前一段时间直接调用并行化有一个问题(我想知道这是否相关?)所以我不得不将 doParallel
脚本设为 non-function 住房脚本,因此无法引入使用 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 - 这直接调用 generate_report
的 doParallization
2.b - generate_report
调用一个 .Rmd
文件,其中包含生成报告所需的函数调用和诸如此类的东西
过程开始并顺利完成。
为了通过Task Scheduler使情况自动进行,我制作了一个Task Scheduler可以调用的脚本,命名为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
函数只是一个 in-house 脚本,用于在整个过程中记录错误。
然后在任务计划的任务中,我调用了 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
在 doParallel
的 .export
调用中 和 它在明确使用它的脚本中,和在实际generate_report
中是直接通过rmarkdown::render()
调用的。
所以 - 我完全不知所措。
我们将不胜感激您的想法和建议。
所以 pandoc 显然是一个可执行文件,可以帮助将文件从一个扩展名转换为另一个扩展名。 RStudio 带有自己的 pandoc 可执行文件,因此当 运行 来自 RStudio 的脚本时,它知道在需要 pandoc 时指向何处。
在命令提示符下,系统不知道查看 RStudio 的内部,因此只需将 pandoc 作为独立的可执行文件下载即可为系统提供正确的指针。
已下载 pandoc,一切正常。
我 运行 遇到了这个问题,但我一直想不出如何解决它。
示例前的快速总结:
我有数百个数据集,我希望每天从中创建报告。为了有效地做到这一点,我用 doParallel
并行化了这个过程。在 RStudio 中,该过程运行良好,但是当我尝试通过 windows 上的任务计划程序使该过程自动进行时,我似乎无法让它工作。
RStudio 中的进程是:
我调用一个脚本来获取我所有其他脚本的源代码,每个单独的脚本都有一个 header 部分来执行适当的包导入,例如它看起来像:
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()
这将是简单的“保存时的来源”并将我需要的所有内容引入 .GlobalEnv
。
从那里,我可以简单地键入:parallel_report()
,它调用一个脚本,该脚本提供另一个脚本,该脚本包含报告生成的并行化。前一段时间直接调用并行化有一个问题(我想知道这是否相关?)所以我不得不将 doParallel
脚本设为 non-function 住房脚本,因此无法引入使用 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 - 这直接调用 generate_report
doParallization
2.b - generate_report
调用一个 .Rmd
文件,其中包含生成报告所需的函数调用和诸如此类的东西
过程开始并顺利完成。
为了通过Task Scheduler使情况自动进行,我制作了一个Task Scheduler可以调用的脚本,命名为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
函数只是一个 in-house 脚本,用于在整个过程中记录错误。
然后在任务计划的任务中,我调用了 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
在 doParallel
的 .export
调用中 和 它在明确使用它的脚本中,和在实际generate_report
中是直接通过rmarkdown::render()
调用的。
所以 - 我完全不知所措。
我们将不胜感激您的想法和建议。
所以 pandoc 显然是一个可执行文件,可以帮助将文件从一个扩展名转换为另一个扩展名。 RStudio 带有自己的 pandoc 可执行文件,因此当 运行 来自 RStudio 的脚本时,它知道在需要 pandoc 时指向何处。
在命令提示符下,系统不知道查看 RStudio 的内部,因此只需将 pandoc 作为独立的可执行文件下载即可为系统提供正确的指针。
已下载 pandoc,一切正常。