有没有办法生成 rmarkdown 文档的缓存版本,然后直接从缓存中生成多个输出?

Is there a way to generate a cached version of an rmarkdown document and then generate multiple outputs directly from the cache?

我正在执行一些计算密集型操作,我想从中生成报告。我正在试验 bookdown 或直接 rmarkdown。本质上,我想要一份 html_document 报告和一份 word_document 报告。

我的 .Rmd 文件如下所示:

---
title: "My analysis"
author: "me"
date: '2019-12-17'
output:
  bookdown::word_document2:
    highlight: tango
    df_print: kable
    reference_docx: Word_template.docx
    toc: yes
    toc_depth: 2
    fig_caption: yes
  bookdown::html_document2:
    theme: yeti
    highlight: tango
    df_print: paged
    toc: yes
    toc_depth: 2
    fig_caption: yes
    keep_md: yes
---
***

```{r child = 'index.Rmd', cache=TRUE}
```

```{r child = '01-Read_in_raw_data.Rmd', cache=TRUE}
```

```{r child = '02-Add_analysis.Rmd', cache=TRUE}
```

发生的情况是 html 和 word 文档被单独缓存,这是 a) 耗时,因为它们是 运行 两次,b) 由于一些导出的文件在缓存(它们是在第一次编织操作期间生成的,但在第二次和后续操作中已经存在并会产生错误)。

我试过只生成 .md 文件,但它没有改变问题 (a),我只是从 pandoc 的 .md 输入中得到非常难看的报告。

有人有更优雅的方法吗?

哦,我能感觉到你的痛苦。这是我的解决方案。我基本上不在降价文档中做昂贵的计算。相反,我在 R 文档中执行它们。然后我可以存储结果,当然也可以重新加载它们。很酷的是现在我可以使用工作区中的数据创建一个 markdown 文档,然后编织它。

library(rmarkdown)
library(knitr)

rmd_code <- function(){
    paste0(
        "---
title: \"My analysis\"
author: \"me\"
date: '2019-12-17'
output:
  bookdown::word_document2:
    highlight: tango
    df_print: kable
    reference_docx: Word_template.docx
    toc: yes
    toc_depth: 2
fig_caption: yes
  bookdown::html_document2:
    theme: yeti
    highlight: tango
    df_print: paged
    toc: yes
    toc_depth: 2
    fig_caption: yes
    keep_md: yes
---
***

```{r child = 'index.Rmd', cache=TRUE}
```

```{r child = '01-Read_in_raw_data.Rmd', cache=TRUE}
```

```{r child = '02-Add_analysis.Rmd', cache=TRUE}
```
"
    )
}

# write the Rmd code into a file
cat(rmd_code()
    , file = "bla.Rmd")

# knit this R-Markdown file now
render(input = "bla.Rmd"
       , output_file = "yourOutPutFile.html")

# and now delete the R-Markdown file again
file.remove("bla.Rmd")

这样就可以使用您已经在 Rmd 上完成的计算,而无需每次都重新运行所有计算。

默认情况下,缓存数据库的路径(由 knitr 生成)取决于 R Markdown 输出格式。这就是为什么必须为 HTML 和 Word 等不同输出格式重新生成缓存的原因。要对所有输出格式使用相同的缓存数据库副本,您可以手动指定一个不依赖于输出格式的路径,例如,

```{r, setup, include=FALSE}
knitr::opts_chunk$set(cache.path = 'a/fixed/directory/')
```

但是,请注意,每种输出格式使用自己的缓存路径肯定是有原因的:R 代码块的输出可能取决于输出格式。例如,对于 Word 输出,可能使用 Markdown 语法 ![](...) 写出一个图,但对于 HTML 输出可能会变成 <img src="..." />。如果您确定您的代码块没有任何副作用(例如,生成图表和表格),您可以安全地为缓存数据库使用固定路径。通常我不会建议你为整个文档(because caching is hard)打开cache = TRUE,而是只缓存特定的耗时代码块。