在循环中结合使用 sink() 和 rmarkdown::render() 来检测计划的 .Rmd 报告的错误

Use sink() in combination with rmarkdown::render() within loop to detect errors for scheduled .Rmd reports

背景:我正在创建一个脚本来记录降价文件的控制台输出。需要它来跟踪经常 运行 的定期报告中的错误。最后 - 如果渲染时出现错误 - log.txt 文件会自动发送到我的邮箱,以便获得有关错误的通知,包括。附上 log.txt 文件。

现在回答我的问题,它只与控制台输出的日志记录有关:在 script.R 中,我定义了必须执行的命令和日志文件名每个命令。然后我 运行 遍历 .Rmd 文件的循环。因此,每个 .Rmd 都被渲染,控制台输出在 sink() 的帮助下被记录下来。然而,事实证明,一旦渲染时发生错误,下沉过程就不会停止(尽管 sink(NULL))并且循环不会继续渲染和记录 file2.Rmd。这个问题有解决办法吗?

到目前为止,我认为这是一个与环境相关的问题。但这似乎不是关键问题。在此感谢您的帮助。

script.R

data <- data.frame(command = c("file1.Rmd", "file2.Rmd"),
                   log = c("file1Log.txt", "file2Log.txt"))

for (i in 1:nrow(data)) {
  command_i <- as.character(data[i, "command"])
  log_i <- as.character(data[i, "log"])
  
  renderMarkdown <- function() {
    
    con <- file(log_i,"w")
    sink(con, append=TRUE)
    sink(con, append=TRUE, type="message")
    
    rmarkdown::render(input = command_i,
                      output_format = "html_document",
                      output_file = sub(".Rmd", "", command_i),
                      output_dir = getwd())
    
    sink()
  }
  
  env <- new.env()
  assign("command", command_i, envir = env)
  assign("log", log_i, envir = env)
  
  sinkMarkdown <- function(renderMarkdown, env) {
    environment(renderMarkdown) <- env
    renderMarkdown()
  }
  
  sinkMarkdown(renderMarkdown, env)
}

file1.Rmdfile2.Rmd 是您在创建新 .Rmd 后获得的默认 Markdown 文件文件。为了抛出错误,我插入了 print(errorOnPurpose),它表示一个不存在的对象。

file1.Rmd(相当于file2.Rmd

---
title: "file1"
author: "user"
date: "10 8 2020"
output: html_document
---

#```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
#```

## R Markdown

This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see <http://rmarkdown.rstudio.com>.

When you click the **Knit** button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:

#```{r cars}
summary(cars)
print(errorOnPurpose)
#```

## Including Plots

You can also embed plots, for example:

#```{r pressure, echo=FALSE}
plot(pressure)
#```

Note that the `echo = FALSE` parameter was added to the code chunk to prevent printing of the R code that generated the plot.

如你所言,转移应该停止(以正确的顺序)。这不会在您的代码中发生:sink() 被调用一次并仅停止输出转移(您可以使用 sink.number(type = "message") 检查消息转移是否打开)。您还应该使用 close().

关闭连接

使用 try() 防止 .rmd 文件中的错误中断循环。

renderMarkdown <- function() {
    
    con <- file(log_i,"w")
    sink(con, append=TRUE)
    sink(con, append=TRUE, type="message")
    
    try(
    rmarkdown::render(input = command_i,
                      output_format = "html_document",
                      output_file = sub(".Rmd", "", command_i),
                      output_dir = getwd())
    )
    
    sink(type = "message")
    sink(type = "output")
    close(con)

  }