Knitr的缓存可以与指针对象一起使用吗?
我正在使用knitr
来制作使用Terra
软件包绘制地图的文档。这是我的最小.rmd文件:
```{r init, echo=FALSE}
library(knitr)
opts_chunk$set(cache=TRUE)
```
```{r maps}
library(terra)
r = rast(matrix(1:12,3,4))
plot(r)
```
```{r test2}
print(r)
plot(r)
```
第一次运行(通过rmarkDown :: Render(...)
),这起作用,创建test_cache
文件夹。第二次运行(没有更改)也可以正常运行。如果我对块2进行了较小的更改(例如添加注释)并运行我得到:
Quitting from lines 14-17 (cache.Rmd)
Error in .External(list(name = "CppMethod__invoke_notvoid", address = <pointer: (nil)>, :
NULL value passed as symbol address
我也从另一个RMD文件中获得了此内容,可能相关:
Quitting from lines 110-115 (work.Rmd)
Error in x@ptr$readStart() : external pointer is not valid
清除缓存或使用Cache = false
运行然后起作用,但是缓存的意义是什么。
我认为这是因为r
是某种参考类,它通过通过rcpp
分配的某些内存而存在,而Knitr仅在缓存参考,因此当它尝试读取缓存时版本,它获得了对内存的引用,该内存没有创建的对象,该对象与其中的参考有关。所以它失败了。
fwiw a terra
栅格对象看起来像这样:
> str(r)
Formal class 'SpatRaster' [package "terra"] with 1 slot
..@ ptr:Reference class 'Rcpp_SpatRaster' [package "terra"] with 20 fields
.. ..$ depth : num 0
.. ..$ extent :Reference class 'Rcpp_SpatExtent' [package "terra"] with 2 fields
是否
> r@ptr
C++ object <0x55ce6fdf2bd0> of class 'SpatRaster' <0x55ce5a6750b0>
有一种方法可以使Knitr Cache与这些对象一起使用?我知道我只能将它们排除在缓存中,但是我的90%的文档正在使用此类对象,这就是我要使用缓存来加快速度的原因。但是,每当我遇到此错误时,我都必须停止,清除缓存,重新开始,我不知道该时间是否值得加速我使用缓存。
r 4.1.1与
> packageVersion("knitr")
[1] ‘1.34’
> packageVersion("rmarkdown")
[1] ‘2.11’
I'm using knitr
to make a document that uses the terra
package to draw maps. Here's my minimal .Rmd file:
```{r init, echo=FALSE}
library(knitr)
opts_chunk$set(cache=TRUE)
```
```{r maps}
library(terra)
r = rast(matrix(1:12,3,4))
plot(r)
```
```{r test2}
print(r)
plot(r)
```
First run (via rmarkdown::render(...)
), this works, creates a test_cache
folder. Running a second time (with no changes) it also runs fine. If I make a minor change to chunk 2 (eg add a comment) and run I get:
Quitting from lines 14-17 (cache.Rmd)
Error in .External(list(name = "CppMethod__invoke_notvoid", address = <pointer: (nil)>, :
NULL value passed as symbol address
I've also had this from another Rmd file, probably related:
Quitting from lines 110-115 (work.Rmd)
Error in x@ptr$readStart() : external pointer is not valid
clearing the cache or running with cache=FALSE
then works, but then what's the point of the cache.
I think its because r
is some sort of reference class which exists via some memory allocated by Rcpp
, and knitr is only caching a reference, so when it tries to read the cached version it gets a reference to memory which doesn't have the object that was created to go with the reference there. So it fails.
FWIW a terra
raster object looks like this:
> str(r)
Formal class 'SpatRaster' [package "terra"] with 1 slot
..@ ptr:Reference class 'Rcpp_SpatRaster' [package "terra"] with 20 fields
.. ..$ depth : num 0
.. ..$ extent :Reference class 'Rcpp_SpatExtent' [package "terra"] with 2 fields
and
> r@ptr
C++ object <0x55ce6fdf2bd0> of class 'SpatRaster' <0x55ce5a6750b0>
Is there a way to make the knitr cache work with these objects? I know I could exclude just these from the cache but 90% of my document is working with these sorts of objects and that's the reason I want to use the cache to speed things up. But then every time I get this error I have to stop, clear the cache, start again, and I don't know if that time is worth the speedup I get with the cache.
R 4.1.1 with
> packageVersion("knitr")
[1] ‘1.34’
> packageVersion("rmarkdown")
[1] ‘2.11’
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
例如,Terra做了一些允许序列化的工作:
但是,似乎具有“保存”到RDATA文件的Knitr缓存;在这种情况下,将原始对象存储,在重新加载时,该对象是无效的。
我认为 May 可以通过一些巧妙的使用 hook function < /a>;但这将是如此涉及,以至于它将击败缓存的目的。
terra does some work to allow serialization, for example:
But it seems that knitr caches with "save" to an RData file; in that case, the raw object is stored, which won't be valid when reloaded.
I think it may be possible to work around this with some clever use of hook functions; but that would be so involved that it would defeat the purpose of caching.