Используйте функцию sin() в сочетании с функцией rmarkdown::render() внутри цикла для обнаружения ошибок в запланированных отчетах .Rmd.

Предыстория: я создаю скрипт, который регистрирует консольный вывод файла уценки. Это необходимо для отслеживания ошибок в запланированных отчетах, которые запускаются часто. В конце концов - в случае возникновения ошибки при рендеринге - файл log.txt автоматически отправляется на мой почтовый ящик, чтобы получить информацию об ошибке, в т.ч. приложил файл log.txt.

Теперь к моему вопросу, который связан только с ведением журнала вывода консоли: в script.R я определяю команды, которые должны быть выполнены, и имя файла журнала для каждой из команд. Затем я запускаю цикл, который перебирает файлы .Rmd. Таким образом, каждый .Rmd визуализируется, а вывод консоли регистрируется с помощью функции sint(). Однако оказывается, что как только при рендеринге возникает ошибка, процесс стока не останавливается (несмотря на sink(NULL)) и цикл не продолжается с рендерингом и записью file2 .Рмд. Есть ли решение этой проблемы?

До сих пор я ожидал, что это будет проблема, связанная с окружающей средой. Но это не кажется критическим вопросом. Был бы признателен за помощь здесь.

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.Rmd и file2.Rmd — это файлы Markdown по умолчанию, которые вы получаете после создания нового файла .Rmd. Чтобы выдать ошибку, я вставил 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.


person Arut    schedule 10.08.2020    source источник


Ответы (1)


Как вы правильно заметили, диверсии должны быть прекращены (в правильном порядке). В вашем коде этого не происходит: 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)

  }
person Martin C. Arnold    schedule 10.08.2020