web-dev-qa-db-ja.com

相違点:RStudioの「PDFのコンパイル」ボタンとknit()およびknit2pdf()の違い

TL; DR

「PDFのコンパイル」の代わりにknit()/knit2pdf()を使用した場合の(望ましくない)副作用は何ですか1 RStudioのボタン?

動機

knitrのほとんどのユーザーは、RStudioでドキュメントを作成し、[PDFのコンパイル]/[HTMLのニット]ボタンを使用してドキュメントをコンパイルするようです。これはほとんどの場合スムーズに機能しますが、コンパイルボタンを使用して達成できない特別な要件がときどきあります。これらの場合、解決策は通常、knit()/knit2pdf()/rmarkdown::render()(または類似の関数)を直接呼び出すことです。

いくつかの例:

「PDFのコンパイル」ボタンの代わりにknit2pdf()を使用すると、通常、このような質問に対する簡単な解決策が提供されます。ただし、これには代償が伴います。「PDFのコンパイル」がドキュメントを処理するという根本的な違いがあります 別のプロセスと環境で に対して、knit2pdf()とその仲間は処理しません。

これには影響があり、問題はこれらの影響のすべてが明白ではないということです。knit()がグローバルからオブジェクトを使用するという事実を取ります例として環境(「PDFのコンパイル」にはありません)。これは明白であり、上記の2番目の例のような場合には望ましい動作ですが、knit()を使用すると、予期しない結果になります例1と3のような問題を克服する。

さらに、さらに微妙な違いがあります。

質問とその目標

「PDFのコンパイル」の代わりにknit2pdf()を使用するためのアドバイスを読み書きするときはいつでも「正しいと思いますが、ユーザーは結果を理解する必要があります…」

したがって、ここでの質問は次のとおりです。

RStudioの[PDFのコンパイル]ボタンの代わりにknit()/knit2pdf()を使用した場合の(望ましくない)副作用は何ですか?

この質問に対する包括的な(コミュニティwiki?)回答があった場合、knit2pdf()の使用を提案する将来の回答にリンクすることができます。

関連する質問

この問題には数十の関連する質問があります。ただし、RStudioボタンの動作を(多かれ少なかれ)再現するためのコードのみを提案するか、起こり得る落とし穴について言及せずに「基本的に」何が起こるかを説明します。他は非常によく似た質問のように見えますが、(非常に)特別なケースであることが判明しました。いくつかの例:

答えについて

この質問は、回答の一部となるべき多くの問題を引き起こしたと思います。しかし、私が知らない多くの側面があるかもしれません。それが私がこの質問に自己回答することに消極的である理由です(だれも答えない場合は試すかもしれませんが)。

おそらく、回答は3つの主要なポイントをカバーする必要があります。

  • 新しいセッションと現在のセッションの問題(グローバルオプション、作業ディレクトリ、ロードされたパッケージなど)。
  • 最初のポイントの結果:knit()が呼び出し環境のオブジェクトを使用するという事実(デフォルト:envir = parent.frame())と再現性への影響。 knit()がドキュメントの外部からオブジェクトを使用できないようにする問題に取り組みました この答え (2番目の箇条書き)。
  • RStudioが密かに行うこと…
    • …インタラクティブセッションの開始時( )->「Compile PDF」を押した場合は使用できません
    • …「PDFのコンパイル」を押すと(処理されたファイルに設定された作業ディレクトリでの新しいセッション以外に何か特別なことはありますか?)

私はこの問題についての正しい見方を知りません。 「 'Compile PDF' +の影響を押したときに何が起こるか」と「knit() +の影響を使ったときに何が起こるか」の両方が、この問題に取り組む良いアプローチだと思います。


1 同じことが、RMDドキュメントを作成するときの「Knit HTML」ボタンにも当てはまります。

55
CL.

まず、「HTMLをニット」ボタンは別の話なので、「PDFをコンパイル」ボタンに範囲を限定すると、この質問の方が答えやすいと思います。 「Compile PDF」はRnwドキュメント(R + LaTeX、またはSweaveと考える)専用です。

私はあなたが提案した3つのポイントに従ってあなたの質問に答えます:

  1. 現在、RStudioは常に新しいRセッションを起動してRnwドキュメントをコンパイルし、最初に作業ディレクトリをRnwファイルのディレクトリに変更します。次のようなシェルスクリプトとしてプロセスを想像できます。

    cd path/to/your-Rnw-directory
    Rscript -e "library(knitr); knit('your.Rnw')"
    pdflatex your.tex
    

    knitrパッケージは常に添付され、pdflatexは他のLaTeXエンジンである可能性があることに注意してください(SweaveドキュメントのRStudio構成によっては、xelatexなど)。現在のRセッションでそれを複製したい場合は、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セッションで実行されます(デフォルトではglobalenv()内)。

  2. Rnwドキュメントは常に新しいRセッションでコンパイルされるため、現在のRセッションではオブジェクトを使用しません。これは、現在のRセッションでknitr::knit()envir引数を介してのみ複製することは困難です。特に、knitr::knit(envir = new.env())は新しい環境ですが、デフォルトの親環境new.env()(通常はparent.frame())があるため、globalenv()は使用できません。 knitr::knit(envir = emptyenv())も使用できません。これは「クリーンすぎる」ため、R baseパッケージのオブジェクトでも問題が発生するためです。 「PDFのコンパイル」ボタンの機能を複製する唯一の信頼できる方法は、system2("Rscript", c("-e", shQuote("library(knitr); knit('your.Rnw')"))で私が言ったことです。この場合、knit()は新しいRセッションのglobalenv()を使用します。

  3. RStudioがreposオプションに対して何を行うかについては、完全にはわかりません。このオプションが設定されていない場合は、おそらくこのオプションが自動的に背後で設定されます。これは比較的小さな問題だと思います。 .Rprofileで設定できます。RStudioはCRANミラー設定を尊重する必要があると思います。

ユーザーは、Rnwドキュメント(またはR Markdownドキュメント)が現在のRセッションでコンパイルされない理由を常に尋ねてきました。私たちにとって、それは基本的に次の結果のどれがより意外であるか望ましくない結果であるかを要約します:

  1. 現在のRセッションでドキュメントを編成した場合、別のRセッションで結果を再現できるという保証はありません(たとえば、次にRStudioを開いたとき、または共同編集者がコンピューターでRStudioを開いたとき)。
  2. 新しいRセッションでドキュメントを編成した場合、ユーザーはオブジェクトが見つからないことに驚かれる可能性があります(Rコンソールにオブジェクト名を入力すると、オブジェクトが表示されます)。これは意外なことかもしれませんが、次回ドキュメントが動作しない可能性があることも、早い段階で思い出させてくれます。

要約すると、私は思う:

  • 新しいRセッションで編み物を行うと、再現性が向上します。

  • 現在のRセッションで編成する方が便利な場合があります(たとえば、現在のセッションで別の一時的なRオブジェクトを使用して編成しようとした場合)。特にプログラムでPDFレポートを生成している場合など、現在のRセッションで編成する必要がある場合もあります。たとえば、(for)ループを使用して一連のレポートを生成します。方法はありません。これは、[PDFをコンパイル]ボタンを使用してのみ実現できます(ボタンは、ほとんどの場合、単一のRnwドキュメント専用です)。

ところで、私が上で言ったことはKnitまたはKnit HTMLボタンにも適用できると思いますが、基本的な機能はrmarkdown::render()ではなくknitr::knit()です。

12
Yihui Xie