带参数渲染时如何缓存中间结果?

How to cache intermediate results when rendering with parameters?

使用 RMarkdown,我尝试为参数的不同值呈现参数化报告。 Rmd 文件使用缓存。

如果我在 RStudio 中使用编织按钮进行编织,缓存将按预期工作:首先构建缓存,然后在每次连续编织时使用,即使我更改了 YAML 中的参数值 header。

但是当使用我的参数值循环并使用 rmarkdown::render() 时,每次迭代都会重建缓存。

test.Rmd 文件

---
title: "Untitled"
author: "Author"
params:
  id: 0
date: "23/10/2019"
output: html_document
---

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

## Test `r params$id`

```{r cars, cache=TRUE}
## open and work on large file (simulate)
test <- mtcars
Sys.sleep(10)
```

渲染脚本:render.R

library(rmarkdown)
library(tidyverse)

1:5 %>% 
  walk(function(x) render("test.Rmd",
                          params = list(id = x),
                          output_file = paste0("file", x, ".html")))

脚本需要 5 * 10 秒到 运行 而不是大约 10 秒。

我做错了什么?如何使用缓存?

与参数无关,可以用下面最小化的reprex(test.Rmd)表示,去掉参数(和不相关的tidyverse) :

---
title: "Untitled"
---

```{r, cache=TRUE}
Sys.sleep(10)
```

然后运行

for (i in 1:5) rmarkdown::render(
  "test.Rmd", output_file = paste0("file", i, ".html")
)

问题来自output_file,每次迭代都会发生变化。对于 R Markdown 文档,输出文件名决定 knitr 块选项 fig.path。例如,当output_file = "file1.html"时,fig.path设置为file1_files/html/

当代码块的任何块选项更改时,knitr 将使其缓存失效。在您的情况下,fig.path 每次都使缓存无效。为避免这种情况,您必须稳定此选项,例如

---
title: "Untitled"
---

```{r, cache=TRUE, fig.path='test_files/html/'}
Sys.sleep(2)
```