r - 区别 : "Compile PDF" button in RStudio vs. knit() 和 knit2pdf()

标签 r rstudio knitr

TL; 博士
使用 knit() 的(可能不需要的)副作用是什么?/knit2pdf()而不是 RStudio 中的“编译 PDF”1 按钮?
动机knitr的大多数用户似乎在 RStudio 中编写他们的文档并使用“编译 PDF”/“编织 HTML”按钮编译文档。这在大多数情况下都能顺利运行,但每隔一段时间就会出现使用编译按钮无法实现的特殊要求。在这些情况下,解决方案通常是拨打 knit()/knit2pdf()/rmarkdown::render() (或类似的功能)直接。
一些例子:

  • How to knit/Sweave to a different file name?
  • Is there a way to knitr markdown straight out of your workspace using RStudio?
  • Insert date in filename while knitting document using RStudio Knit button

  • 使用 knit2pdf()而不是“编译 PDF”按钮通常为此类问题提供简单的解决方案。但是,这是有代价的:“编译 PDF”处理文档 in a separate process and environment 有根本区别。而knit2pdf()而 friend 不会。
    这有一些影响,问题是并非所有这些影响都是显而易见的。以 knit() 为例使用来自全局环境的对象(而“编译 PDF”没有)作为示例。在上面的第二个示例中,这可能是显而易见的和所需的行为,但是当 knit() 时,这是一个意想不到的结果。用于克服示例 1 和 3 中的问题。
    此外,还有更细微的区别:
  • working directory可能没有按预期设置。
  • Packages need to be loaded .
  • 一些通常由 RStudio 设置的选项可能有 unexpected values .

  • 问题及其目标
    每当我读/写使用建议时 knit2pdf()而不是“编译PDF”,我认为“正确,但用户应该理解后果......”。
    因此,这里的问题是:

    What are the (possibly unwanted) side-effects of using knit()/knit2pdf() instead of the "Compile PDF" button in RStudio?


    如果这个问题有一个全面的(社区维基?)答案,它可以在 future 的答案中链接起来,建议使用 knit2pdf() .
    相关问题
    与此相关的问题有几十个。然而,他们要么只提出(或多或少)重现 RStudio 按钮行为的代码,要么解释“基本”发生的情况而没有提及可能的陷阱。其他看起来非常相似的问题,但结果却是它的(非常)特例。一些例子:
  • Knit2html not replicating functionality of Knit HTML button in R Studio : 缓存问题。
  • HTML outputs are different between using knitr in Rstudio & knit2html in command line : Markdown 版本。
  • How to convert R Markdown to HTML? I.e., What does “Knit HTML” do in Rstudio 0.96? :Yihui 的相当肤浅的回答(解释了“基本”发生的情况)以及如何重现 RStudio 按钮行为的一些选项。 suggested Sys.sleep(30)也不是 the "Compile PDF" log很有见地(两个提示都指向同一件事)。
  • What does “Knit HTML” do in Rstudio 0.98? :重现按钮的行为。

  • 关于答案
    我认为这个问题提出了许多应该作为答案一部分的问题。但是,可能还有更多我不知道的方面,这就是我不愿意自我回答这个问题的原因(尽管如果没有人回答,我可能会尝试)。
    或许,一个答案应该包括三个要点:
  • 新 session 与当前 session 问题(全局选项、工作目录、加载的包等)。
  • 第一点的结果:事实knit()使用来自调用环境的对象(默认值: envir = parent.frame() )以及对可再现性的影响。我试图解决阻止问题knit()使用文档外部的对象 this answer (第二个要点)。
  • RStudio secret 做的事情……
  • ...当开始一个交互式 session 时 ( example ) --> 点击“编译 PDF”时不可用
  • ...当点击“编译 PDF”时(除了工作目录设置为已处理文件的新 session 之外,还有什么特别的吗?)


  • 我不确定对这个问题的正确看法。我认为,“当我点击‘编译 PDF’+ 含义时会发生什么”以及“当我使用 knit()+ 含义时会发生什么”都是解决这个问题的好方法。

    1 这同样适用于编写 RMD 文档时的“Knit HTML”按钮。

    最佳答案

    首先,如果将范围限制在“编译 PDF”按钮,我认为这个问题更容易回答,因为“编织 HTML”按钮是另一回事。 “编译 PDF”仅适用于 Rnw 文档(R + LaTeX,或认为 Sweave)。

    我将按照您建议的三点回答您的问题:

  • 目前 RStudio 总是启动一个新的 R session 来编译 Rnw 文件,并首先将工作目录更改为 Rnw 文件的目录。你可以把这个过程想象成一个 shell 脚本,如下所示:
    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() 中)。
  • 因为 Rnw 文档总是在新的 R session 中编译,所以它不会使用当前 R session 中的任何对象。这很难仅通过 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 。
  • 我不完全确定 RStudio 为 repos 做了什么选项。如果未设置,它可能会在幕后自动设置此选项。我认为这是一个相对较小的问题。您可以在您的 .Rprofile 中设置它,我认为 RStudio 应该尊重您的 CRAN 镜像设置。

  • 用户一直在问,为什么在当前的 R session 中没有编译 Rnw 文档(或 R Markdown 文档)。对我们来说,它基本上归结为以下哪个后果更令人惊讶或更不受欢迎:
  • 如果我们在当前 R session 中编写文档,则不能保证您的结果可以在另一个 R session 中重现(例如,下次您打开 RStudio,或您的合作者在他们的计算机上打开 RStudio)。
  • 如果我们在新的 R session 中编织一个文档,用户可能会惊讶于找不到对象(并且当他们在 R 控制台中键入对象名称时,他们可以看到它们)。这可能令人惊讶,但它也是一个很好的早期提醒,您的文档下次可能无法使用。

  • 总结一下,我认为:
  • 在新的 R session 中编织更有利于再现性;
  • 在当前 R session 中编织有时更方便(例如,您尝试在当前 session 中使用不同的临时 R 对象进行编织)。有时您还必须在当前的 R session 中编织,尤其是当您以编程方式生成 PDF 报告时,例如,您使用 (for) 循环生成一系列报告。您无法仅通过“编译 PDF”按钮(该按钮主要仅用于单个 Rnw 文档)来实现此目的。

  • BTW,我觉得我上面说的也适用于Knit或Knit HTML按钮,但底层功能是rmarkdown::render()而不是 knitr::knit() .

    关于r - 区别 : "Compile PDF" button in RStudio vs. knit() 和 knit2pdf(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34591487/

    相关文章:

    r - SAS 转 R 代码 第一个和最后一个函数

    r - 显示未存储在 R shiny 应用程序内的 www 文件夹中的 PDF 文件

    R tm In mclapply(内容(x),FUN,...): all scheduled cores encountered errors in user code

    r - 在 Rmarkdown 中执行 Perl 6 代码

    r - “Knit HTML” 在 Rstudio 0.98 中做什么?

    r - knitr - 设置 block 选项*外部*文档?

    r - 使用桥接适配器在虚拟机上配置我的 Shiny 服务器时出现问题

    r - 在 R 中,给定 y = f(x),如何找到 y/x 的全局最大值?

    R Markdown 2 到 EPUB 如何?

    r - 我无法在 R Markdown 上编写 HTML。有人可以帮忙吗?