可以使用with()对环境进行knitr缓存更改吗?

时间:2017-11-29 17:57:34

标签: r knitr

看来,对environment with()对象所做的更改不会被缓存:

```{r}
foo <- new.env()
```

```{r, cache=TRUE}
with(foo, bar <- 42)
```

```{r}
foo$bar
```

这将在第一次运行时打印42,然后在NULL打印。

我不确定这是不是一个错误(可以说with()是一个被称为副作用的函数)但是我正在试验收集所有分析结果的想法environment的{​​{1}},如果这可以很好地与knitr的缓存一起使用会很棒。

1 个答案:

答案 0 :(得分:1)

您没有缓存第一个代码块,这意味着每次编译此文档时,都会执行第一个代码块。这意味着每次你获得一个全新的环境。

然后你缓存了第二个代码块。关于 knitr 的缓存最重要的事情是,第二次编译文档时不会评估缓存的块(除非您对代码块进行了更改)。由于未评估此代码块,因此未在bar环境中分配foo

简而言之:

  1. foo始终是一个新环境;

  2. 第二次编译文档时,不会创建
  3. bar

  4. 这解释了barNULL的原因。要解决此问题,您必须缓存第一个代码块。但还有另一个警告:由于使用了with() knitr 将无法发现foo在第二个代码块中被修改,因此您必须告诉 knitr 对象foo应该被缓存(即保存)。完整的解决方案是:

    ```{r, cache=TRUE}
    foo <- new.env()
    ```
    
    ```{r, cache=TRUE, cache.vars='foo'}
    with(foo, bar <- 42)
    ```
    
    ```{r}
    foo$bar
    ```