16.6 R コードチャンク用の作業ディレクトリ
R コードチャンクの作業ディレクトリは, デフォルトでは Rmd 文書のあるディレクトリです. 例えば Rmd ファイルのパスが ~/Downloads/foo.Rmd
であるなら, R コードチャンクが評価される作業ディレクトリは ~/Downloads/
になります. ということは, チャンク内で外部ファイルを相対パスで参照するとき, そのパスは Rmd ファイルのあるディレクトリからの相対パスであることを知っておくべきことを意味します. 前述の Rmd ファイルの例では, コードチャンク内での read.csv("data/iris.csv")
は ~/Downloads/data/iris.csv
から CSV ファイルを読み込むことを意味しています.
よく分からない時は, getwd()
をコードチャンクに追加して文書をコンパイルし, getwd()
の出力を確認できます.
時には他のディレクトリを作業ディレクトリとして使いたいこともあります. 一般的な作業ディレクトリの変更方法は setwd()
ですが, setwd()
は R Markdown あるいは他の knitr ソース文書で一貫して使えるわけではないことに注意してください. これは setwd()
が現在のコードチャンクに限って動作し, 作業ディレクトリはこのコードチャンクが評価された後に元に戻ることを意味します.
全てのコードチャンクに対して作業ディレクトリを変更したい場合, 文書の冒頭で setup
コードチャンクを設定できます.
```{r, setup, include=FALSE}
knitr::opts_knit$set(root.dir = '/tmp')
```
これは以降の全てのコードチャンクの作業ディレクトリを変更します.
RStudio を使用しているなら, 作業ディレクトリをメニュの Tools -> Global Options -> R Markdown
からも選択できます (図16.1参照). デフォルトの作業ディレクトリは Rmd ファイルのディレクトリで, 他に2つの選択肢があります. “Current” オプションで R コンソールの現在の作業ディレクトリを使うか, “Project” オプションで Rmd ファイルが入っているプロジェクトのルートディレクトリを作業ディレクトリとして使うこともできます.
RStudio では, 図16.2で見せるように, 個別の Rmd 文書をそれぞれ固有の作業ディレクトリで knit することもできます. “Knit Directory” を変更し “Knit” ボタンをクリックした後で, knitr は新しい作業ディレクトリを使ってコードチャンクを評価します. これらの全ての設定は既に言及した knitr::opts_knit$set(root.dir = ...)
に集約されています. よってあなたがこれまでの選択肢のいずれにも満足しないのなら, knitr::opts_knit$set()
を使いご自分でディレクトリを指定できます.
作業ディレクトリに関して完全に正しい選択というものはありません. それぞれに長所と短所があります.
(knitr のデフォルト) Rmd 文書のディレクトリをコードチャンクの作業ディレクトリとして使うなら, ファイルパスは Rmd 文書からの相対パスだと想定していることになります. これは ウェブブラウザで相対パスを扱うのと似ています. 例えば
https://www.example.org/path/to/page.html
という HTML ページでの画像<img src="foo/bar.png" />
に対して, ウェブブラウザがhttps://www.example.org/path/to/foo/bar.png
から画像を取得するのと似ています. 言い換えるなら, 相対パスfoo/bar.png
は HTML ファイルのあるディレクトリhttps://www.example.org/path/to/
からの相対位置です.このアプローチの利点は Rmd ファイルを Rmd ファイルが参照しているファイルと一緒に, 相対的な位置関係を保っている限りどこへでも自由に移動できることです. 上記の HTML ページと画像の例では,
page.html
とfoo/bar.png
をhttps://www.example.org/another/path/
へ一緒に移動させることができます. そしてあなたは<img />
のsrc
属性の相対パスを更新する必要はありません.Rmd 文書の相対パスを「Rmd ファイルからの相対位置」とは対照的に「Rコンソールの作業ディレクトリからの相対位置」と考えるのを好むユーザもいます. よって knitr のデフォルトディレクトリは混乱を招きます. 私が knitr を設計する際に R コンソールの作業ディレクトリをデフォルトで使わないようにした理由は, ユーザがいつでも
setwd()
で作業ディレクトリを変更したければできてしまうからでした. この作業ディレクトリが安定している保証はありません. 毎度のようにユーザがsetwd()
をコンソールで呼び出すと, Rmd 文書内のファイルパスが無効になるリスクがあります. ファイルパスが Rmd ファイルの制御の手から離れてsetwd()
という外部要因に依存しているというのは不自然なことでしょう. 相対パスを考慮する際に, Rmd ファイルを「宇宙の中心」として扱えば, Rmd ファイル内にあるパスはもっと安定するでしょう.その上, あなたが相対パスを考慮するのが難しすぎて嫌だと言うなら, 図16.3のように RStudio 上で自動補完機能を使ってファイルパスを入力することもできます. RStudio は Rmd ファイルからの相対パスを補完しようと試みます.
R コンソールの作業ディレクトリはプログラミング的あるいは対話的に文書を knit するのに良い選択になりうるでしょう. 例えばループ中に文書を複数回 knit し, そこで毎回で異なる作業ディレクトリを使い, 各々のディレクトリ内の異なるデータファイル(ファイル名は同じとします) を読み込むこともできます. この種の作業ディレクトリは ezknitr パッケージ (Attali 2016) で推奨されており, 実は
knitr::opts_knit$set(root.dir)
を使って knitr のコードチャンクの作業ディレクトリを変更しています.プロジェクトディレクトリを作業ディレクトリとして使うことには明確な前提が要求されます. そもそもプロジェクト (例えば RStudio のプロジェクトか, バージョン管理プロジェクト) を使わなければならないということです. この点はアプローチにとっての欠点となりえます. この種の作業ディレクトリを使う利点はあらゆる Rmd 文書内の全ての相対パスがプロジェクトのルートディレクトリからの相対パスになることです. よってプロジェクト内で Rmd ファイルがどこにあるかを考えたり, 他のファイルの場所に対応して調整したりする必要はありません. この種の作業ディレクトリは here パッケージ (Müller 2020) で推奨されており, このパッケージでは渡された相対パスを解決し絶対パスを返す
here::here()
関数を提供しています (相対パスはプロジェクトのルートからの相対であることを忘れないでください). 欠点となるのは, 参照されているファイルを Rmd ファイルとともにプロジェクト内の他の場所に移動させた時に, Rmd 文書内の参照パスを更新する必要があることです. Rmd ファイルを他の人と共有する時は, プロジェクト全体も共有しなければなりません.これらの種類のパスは HTML でのプロトコルやドメインのない絶対パスと似ています. 例えば
https://www.example.org/path/to/page.html
というページの画像<img src="/foo/bar.png" />
はウェブサイトのルートディレクトリ以下の画像を参照しています. つまりhttps://www.example.org/foo/bar.png
です. 画像のsrc
属性の先頭の/
はウェブサイトのルートディレクトリを表しています. HTML の絶対パスと相対パスについてもっと学びたい (あるいはもっと混乱したい) なら, blogdown 本の Appendix B.1 (Xie, Hill, and Thomas 2017) を見てください.
作業ディレクトリのうんざりする問題は, ほとんどの場合, 相対パスに対処している時に抱く 「 何に対して相対的なの? 」という疑問に端を発します. 既に言及したように, いろいろな人がいろいろな好みを持っており, 完全に正しい回答はありません.