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

时间:2019-12-17 13:09:01

标签: r caching r-markdown knitr bookdown

我正在执行一些计算密集型操作,我想从中生成报告。我正在尝试使用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输入中获取了非常难看的报告。

有人能做到这一点吗?

2 个答案:

答案 0 :(得分:1)

默认情况下,缓存数据库的路径(由 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,而只缓存耗时的特定代码块。

答案 1 :(得分:0)

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

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上进行过的计算,而不必每次都重新运行所有计算。