说,我有一个外部R脚本external.R
:
df.rand <- data.frame(rnorm(n = 100), rnorm(n = 100))
然后是main.Rmd
:
\documentclass{article}
\begin{document}
<<setup, include = FALSE>>=
library(knitr)
library(ggplot2)
# global chunk options
opts_chunk$set(cache=TRUE, autodep=TRUE, concordance=TRUE, progress=TRUE, cache.extra = tools::md5sum("external.r"))
@
<<source, include=FALSE>>=
source("external.R")
@
<<plot>>=
ggplot(data = df.rand, mapping = aes(x = x, y = y)) + geom_point()
@
\end{document}
在外部脚本中使用它是有帮助的,因为实际上,这是一堆污染main.Rmd
的导入,数据清理和模拟任务。
main.Rmd
中的任何块都依赖于外部脚本中的更改。
为了解释此依赖关系,我添加了上述cache.extra = tools::md5sum("external.r")
。
这似乎没问题。
我正在寻找最佳实践。
external.R
中的任何更改都会触发完整的缓存失效,而不仅仅是使实际更改的对象无效。“ 没有副作用(某些library()
来电除外,但我可以将它们移至main.Rmd
)。
我总是担心我在某种程度上做错了。
答案 0 :(得分:2)
应该有比目前使用的自助缓存更好的方法。首先,您可以将external.R
拆分为块:
# ---- CreateRandomDFs----
df.rand1 <- data.frame(rnorm(n = 100), rnorm(n = 100))
df.rand2 <- data.frame(rnorm(n = 100), rnorm(n = 100))
# ---- CreateOtherObjects----
# stuff
在main.Rmd
中,添加(在未缓存的块中!)read_chunk(path = 'external.R')
。然后执行块:
<<CreateRandomDFs>>=
@
<<CreateOtherObjects>>=
@
如果autodep
不起作用,请将dependson
添加到您的块中。仅使用df.rand1
和df.rand2
的块获取dependson = "CreateRandomDFs"
;当还使用其他对象时,设置dependson = c("CreateRandomDFs", "CreateOtherObjects")
。
当特定对象发生变化时,您也可能使块缓存失效:cache.whatever = quote(df.rand1)
。
这样,您可以通过external.R
中的任何更改来避免使整个缓存失效。将文件中的代码拆分为块是至关重要的:如果使用太多的块,则必须列出许多依赖项;如果你使用太少的块,缓存会更多/太频繁地失效。