TL; 博士
使用 knit()
的(可能不需要的)副作用是什么?/knit2pdf()
而不是 RStudio 中的“编译 PDF”1 按钮?
动机knitr
的大多数用户似乎在 RStudio 中编写他们的文档并使用“编译 PDF”/“编织 HTML”按钮编译文档。这在大多数情况下都能顺利运行,但每隔一段时间就会出现使用编译按钮无法实现的特殊要求。在这些情况下,解决方案通常是拨打 knit()
/knit2pdf()
/rmarkdown::render()
(或类似的功能)直接。
一些例子:
使用
knit2pdf()
而不是“编译 PDF”按钮通常为此类问题提供简单的解决方案。但是,这是有代价的:“编译 PDF”处理文档 in a separate process and environment 有根本区别。而knit2pdf()
而 friend 不会。这有一些影响,问题是并非所有这些影响都是显而易见的。以
knit()
为例使用来自全局环境的对象(而“编译 PDF”没有)作为示例。在上面的第二个示例中,这可能是显而易见的和所需的行为,但是当 knit()
时,这是一个意想不到的结果。用于克服示例 1 和 3 中的问题。此外,还有更细微的区别:
问题及其目标
每当我读/写使用建议时
knit2pdf()
而不是“编译PDF”,我认为“正确,但用户应该理解后果......”。因此,这里的问题是:
What are the (possibly unwanted) side-effects of using
knit()
/knit2pdf()
instead of the "Compile PDF" button in RStudio?
如果这个问题有一个全面的(社区维基?)答案,它可以在 future 的答案中链接起来,建议使用
knit2pdf()
.相关问题
与此相关的问题有几十个。然而,他们要么只提出(或多或少)重现 RStudio 按钮行为的代码,要么解释“基本”发生的情况而没有提及可能的陷阱。其他看起来非常相似的问题,但结果却是它的(非常)特例。一些例子:
Sys.sleep(30)
也不是 the "Compile PDF" log很有见地(两个提示都指向同一件事)。 关于答案
我认为这个问题提出了许多应该作为答案一部分的问题。但是,可能还有更多我不知道的方面,这就是我不愿意自我回答这个问题的原因(尽管如果没有人回答,我可能会尝试)。
或许,一个答案应该包括三个要点:
knit()
使用来自调用环境的对象(默认值: envir = parent.frame()
)以及对可再现性的影响。我试图解决阻止问题knit()
使用文档外部的对象 this answer (第二个要点)。 我不确定对这个问题的正确看法。我认为,“当我点击‘编译 PDF’+ 含义时会发生什么”以及“当我使用
knit()
+ 含义时会发生什么”都是解决这个问题的好方法。1 这同样适用于编写 RMD 文档时的“Knit HTML”按钮。
最佳答案
首先,如果将范围限制在“编译 PDF”按钮,我认为这个问题更容易回答,因为“编织 HTML”按钮是另一回事。 “编译 PDF”仅适用于 Rnw 文档(R + LaTeX,或认为 Sweave)。
我将按照您建议的三点回答您的问题:
cd path/to/your-Rnw-directory
Rscript -e "library(knitr); knit('your.Rnw')"
pdflatex your.tex
请注意 针织 始终附有包裹,并且
pdflatex
可能是其他 LaTeX 引擎(取决于您对 Sweave 文档的 RStudio 配置,例如 xelatex
)。如果你想在你当前的 R session 中复制它,你可以在 R 中重写脚本:owd = setwd("path/to/your-Rnw-directory")
system2("Rscript", c("-e", shQuote("library(knitr); knit('your.Rnw')"))
system2("pdflatex", "your.tex")
setwd(owd)
这不像
knitr::knit('path/to/your.Rnw')
那么简单,在这种情况下,工作目录不会自动更改,并且所有内容都在当前 R session 中执行(默认在 globalenv()
中)。 envir
复制knitr::knit()
的论据在当前的 R session 中。特别是,您不能使用 knitr::knit(envir = new.env())
因为虽然 new.env()
是一个新环境,它有一个默认的父环境parent.frame()
,通常是 globalenv()
;您不能使用 knitr::knit(envir = emptyenv())
,或者,因为它“太干净了”,即使在 R 中,您也会遇到对象问题。底座 包裹。复制“编译 PDF”按钮功能的唯一可靠方法是我在 1 中所说的:system2("Rscript", c("-e", shQuote("library(knitr); knit('your.Rnw')"))
,在这种情况下 knit()
使用 globalenv()
一个新的 R session 。 repos
做了什么选项。如果未设置,它可能会在幕后自动设置此选项。我认为这是一个相对较小的问题。您可以在您的 .Rprofile
中设置它,我认为 RStudio 应该尊重您的 CRAN 镜像设置。 用户一直在问,为什么在当前的 R session 中没有编译 Rnw 文档(或 R Markdown 文档)。对我们来说,它基本上归结为以下哪个后果更令人惊讶或更不受欢迎:
总结一下,我认为:
BTW,我觉得我上面说的也适用于Knit或Knit HTML按钮,但底层功能是
rmarkdown::render()
而不是 knitr::knit()
.
关于r - 区别 : "Compile PDF" button in RStudio vs. knit() 和 knit2pdf(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34591487/