提问人:Corvus 提问时间:3/9/2013 最后编辑:CommunityCorvus 更新时间:10/25/2017 访问量:1331
为什么 Data.Table ':=' 的 KNITR 缓存失败?
why does knitr caching fail for data.table `:=`?
问:
这在精神上与这个问题有关,但在机制上必须有所不同。
如果尝试缓存包含分配的块,则它的行为就像该块尚未运行一样,并且后面的块看不到 .knitr
data.table
:=
:=
知道这是为什么吗?检测对象是如何更新的,是什么让它感到困惑?knitr
data.table
看来您可以通过执行 来解决此问题。DT = DT[, LHS:=RHS]
示例:
```{r}
library(data.table)
```
Data.Table Markdown
========================================================
Suppose we make a `data.table` in **R Markdown**
```{r, cache=TRUE}
DT = data.table(a = rnorm(10))
```
Then add a column using `:=`
```{r, cache=TRUE}
DT[, c:=5]
```
Then we display that in a non-cached block
```{r, cache=FALSE}
DT
```
The first time you run this, the above will show a `c` column,
from the second time onwards it will not.
第二次运行时输出
答:
19赞
Josh O'Brien
3/9/2013
#1
投机:
这是似乎正在发生的事情。
KNITR 非常明智地在创建对象后立即缓存它们。然后,每当检测到它们已被更改时,它都会更新其缓存值。
但是,data.table 绕过了 R 的常规按值复制分配和替换机制,并使用运算符而不是 、 或 .因此,knitr 不会拾取被 更改的信号。:=
=
<<-
<-
DT
DT[, c:=5]
溶液:
只需将此块添加到代码中,只要您希望重新缓存当前值即可。它不会花费您任何内存或时间(因为除了引用之外,没有任何东西被复制),但它确实有效地向已更新的 knitr 发送(假)信号:DT
DT <- DT
DT
```{r, cache=TRUE, echo=FALSE}
DT <- DT
```
示例文档的工作版本:
通过运行文档的编辑版本来检查它是否有效:
```{r}
library(data.table)
```
Data.Table Markdown
========================================================
Suppose we make a `data.table` in **R Markdown**
```{r, cache=TRUE}
DT = data.table(a = rnorm(10))
```
Then add a column using `:=`
```{r, cache=TRUE}
DT[, c:=5]
```
```{r, cache=TRUE, echo=FALSE}
DT <- DT
```
Then we display that in a non-cached block
```{r, cache=FALSE}
DT
```
The first time you run this, the above will show a `c` column.
The second, third, and nth times, it will as well.
评论
0赞
Corvus
3/9/2013
谢谢你 - 任何猜测会涉及什么。是发出正确的信号,还是要注意?knitr
:=
data.table
knitr
:=
3赞
Yihui Xie
3/9/2013
@Corone在这种情况下,手动将对象名称分配给缓存听起来是个好主意;如果您提交功能请求,我可以考虑:github.com/yihui/knitr/issuesknitr
0赞
Matt Dowle
3/10/2013
@Yihui 嗨。如果有什么我可以改变的,请告诉我。data.table
0赞
Yihui Xie
3/10/2013
@MatthewDowle谢谢,但这可能很难;我想要的是并且也应该出现在环境中,但这显然与 的哲学相矛盾。我心中有一个可能的解决方案,我会更多地考虑它。x=data.table(a=1:5); ev=new.env(); eval(quote({x[, b:=5]}), envir=ev)
x
ev
data.table
2赞
Josh O'Brien
3/13/2013
@MatthewDowle -- 像这样的东西应该可以工作: .(在调用堆栈中搜索调用 to 可能比查找 更安全,因为在调用是“以编程方式”构造的情况下,它会更好地工作,如 或 等)"evaluate" %in% sapply(sys.calls(), function(X) deparse(X[[1]]))
evaluate
knit
knit
do.call(knit, ...)
sapply(..., knit)
11赞
Yihui Xie
4/8/2013
#2
正如乔什·奥布莱恩(Josh O'Brien)回答下的第四条评论所指出的,我添加了一个新的块选项来处理这种非常特殊的情况。在第二个缓存块中,我们可以指定 这样将保存 .cache.vars
cache.vars='DT'
knitr
DT
```{r}
library(data.table)
```
Data.Table Markdown
========================================================
Suppose we make a `data.table` in **R Markdown**
```{r, cache=TRUE}
DT = data.table(a = rnorm(10))
```
Then add a column using `:=`
```{r, cache=TRUE, cache.vars='DT'}
DT[, c:=5]
```
Then we display that in a non-cached block
```{r, cache=FALSE}
DT
```
无论您编译文档多少次,输出都是这样的:
评论
DT
DT
cache=FALSE
.Internal(inspect(DT))
knitr
knitr
data.table