我需要将包含许多幻灯片和 Tikz 图的演示文稿编织在一起。Knitr 非常适合这个,但它需要很长时间,而且我无法同时编织两个报告。
我已经将问题归结为 tikzDictionary 文件的磁盘保存问题。有两个问题,但我怀疑它们是相关的,并且有相同的解决方案。
问题 1:tikzDictionary 会在硬盘上为每个幻灯片和图表重写。这会减慢报告生成速度。
问题 2:如果我在第一个报告准备好之前用 Rscript 编写第二个报告生成,则会出现错误,并且报告生成会崩溃:
Quitting from lines 10-11 (./Slide_template_example.Rnw)
Error in createLockFile(lockname) : cannot create lock file
Calls: knit2pdf ... dbExists -> dbExists -> dbList -> dbList -> createLockFile
我如何定义 tikzDictionary 以便不按幻灯片重写,并且不与另一个 R 会话冲突?
这是一个最小工作(崩溃)示例。在终端窗口中分别运行此示例:
Rscript Report_start.R "Report1"
Rscript Report_start.R "Report2"
R 文件:
## Report_start.R
args <- commandArgs(trailingOnly = TRUE)
report.name <- as.character(args[1])
library(knitr)
knit2pdf(input="Report_master_example.Rnw", compiler='xelatex', output=paste(report.name, ".tex", sep=""))
主 Rnw:
## Report_master_example.Rnw
\documentclass{beamer}
\usepackage{tikz}
\title{Beamer-example}
\author{Chris}
\begin{document}
<<data.prep, include=FALSE>>=
library(ggplot2)
library(tikzDevice)
options(tikzDefaultEngine='xetex')
plot.data <- data.frame(days=c(1,2,3,4,5,6,7,8,9), price=c(2,3,4,3,5,6,5,7,8))
@
\begin{frame}[plain]
\titlepage%
\end{frame}
<<run-all-orig, include=FALSE>>=
out = NULL
for (i in 1:100) {
out = c(out, knit_child('Slide_template_example.Rnw'))
}
@
\Sexpr{paste(out, collapse = '\n')}
\end{document}
幻灯片模板-Rnw:
## Slide_template_example.Rnw
<<, echo=FALSE >>=
opts_chunk$set(fig.path=paste("figure/", report.name, "-nr-", i, "-", sep=""))
@
\begin{frame}{Slide: \Sexpr{i}}
<<, echo=FALSE, dev='tikz', sanitize=TRUE, fig.width=6, fig.height=4, out.width='.40\\paperwidth', message=FALSE, warning=FALSE>>=
p <- ggplot(plot.data, aes(x=days, y=price))
p <- p + geom_line()
p
@
\end{frame}
希望有人会发现这个例子很有用。
答案1
对于这两个问题:
- 字典文件确实会针对每个单独的情节进行重写,并且无法避免。实际上文件哈希包,因此它不会像你想象的那么慢。你也可以打开缓存以避免重复计算。
您可以为不同的报告指定不同的字典文件路径,例如之后
options(tikzDefaultEngine='xetex')
,还指定:options(tikzMetricsDictionary = paste(report.name, 'tikzDictionary', sep = '-'))
那么你的两份报告的字典文件就不会发生冲突。
答案2
我发现,至少在 Windows 7(64 位)下,操作系统中似乎存在竞争条件(可能是目录的某种缓存需要一段时间才能更新?),其中有时会删除锁定文件,但随后创建锁定文件的调用会失败,因为操作系统报告锁定文件仍然存在。这种情况在我使用的几个系统上间歇性地发生,但很频繁。
修改 filehash 以尝试几次等待几百毫秒的迭代,并在第一次尝试无法创建锁文件时重试,似乎可以解决这个问题。
请参阅 filehash git 上的问题和拉取请求:https://github.com/rdpeng/filehash/pull/6