knit 缓存:如果数据文件更改但不更新其他选项(例如“fig.xyz”),则更新

Ben*_*sen 5 r knitr r-markdown

假设我使用knitr,我有一个需要一段时间才能运行的块,我希望这个块在文件更改时更新,但如果我更改则不更新fig.path。后者建议我应该将cache 块选项更改为 1 ,但随后我无法按照此处的建议使用校验和

这是一个 Markdown 文件的示例

---
title: "Example"
author: "Benjamin Christoffersen"
date: "September 2, 2018"
output: html_document
---

```{r setup, include=FALSE}
data_file <- "~/data.RDS"
knitr::opts_chunk$set(echo = TRUE, cache.extra = tools::md5sum(data_file))
```

```{r load_data}
dat <- readRDS(data_file)
```

```{r large_computation, cache = 1}
Sys.sleep(10)
Sys.time() # just to that result do not change
```

```{r make_some_plot}
hist(dat)
```
Run Code Online (Sandbox Code Playgroud)

运行set.seed(1): saveRDS(rnorm(100), "~/data.RDS")和编织产量

在此输入图像描述

然后跑步set.seed(2): saveRDS(rnorm(100), "~/data.RDS")和编织产量

在此输入图像描述

显示large_computation未更新,因为不应该更新,因为cache.extra不在knitr:::cache1.opts向量中。当然,我可以保存md5sum结果,检查以前存储的文件并在块cache.rebuild中使用或执行类似的操作large_computation,但如果有一个解决方案那就太好了knitr。我经常发现我更改了一些块选项(例如,dpifig.widthfig.height),因此使用cache = TRUE将不起作用。我想人们可以修改该包以便能够向knitr:::cache1.opts.

CL.*_*CL. 2

如果我正确理解这个问题,问题是如果设置为cache.extra则不会考虑到。事实上,这是设计使然cache1

\n\n

cache = 1期望的行为是,如果外部文件(或更一般:提供给 的某些值)发生更改,则使所有块(包括带有 的块)的缓存无效cache.extra

\n\n

正如问题中提到的,实现此目的的一种方法是使用chunk 选项cache.rebuild,但我不会手动跟踪外部文件中的更改,而是利用 knit 的内置缓存功能:

\n\n
```{r cachecontrol, cache = TRUE, cache.extra = tools::md5sum(data_file)}\nknitr::opts_chunk$set(cache.rebuild = TRUE)\n```\n
Run Code Online (Sandbox Code Playgroud)\n\n

将其添加为早期块,如果发生更改,所有后续块的缓存都会失效data_file。这个想法是缓存控制后续块 \xe2\x80\x93 缓存的块,但前提是外部文件未更改。

\n\n

当然,只有在cachecontrol评估块之前没有更改全局块选项的情况下,这才有效。

\n\n
\n\n

问题的完整示例:

\n\n

使用不同的种子运行set.seed(1); saveRDS(rnorm(100), "data.RDS")以生成不同的外部文件,然后编织:

\n\n
---\ntitle: "Invalidate all chunks condidional on external file (even if cache=1)"\noutput: html_document\n---\n\n```{r}\ndata_file <- "data.RDS"\n```\n\n```{r cachecontrol, include = FALSE, cache = TRUE, cache.extra = tools::md5sum(data_file)}\n# do NOT change global chunk options before this chunk\nknitr::opts_chunk$set(cache.rebuild = TRUE)\n```\n\n```{r setup, include = FALSE}\nknitr::opts_chunk$set(echo = TRUE, fig.width = 8)\n```\n\n\n```{r load_data}\ndat <- readRDS(data_file)\n```\n\n```{r large_computation, cache = 1}\nSys.sleep(10)\nSys.time() # just to show that result do not change unless external file changes\n```\n\n```{r make_some_plot}\nhist(dat)\n```\n
Run Code Online (Sandbox Code Playgroud)\n