周囲で使っている人を見かけないし、いまいち盛り上がりに欠ける感じがする、Rのパッケージ管理環境であるpackratの使い方とその使い道について割と真剣に考えてみたメモ。packrat自身はRStudio謹製だし、なかでもJ.J. AllaireとKevin Usheyが推しているのでその有益性については確実な。
既存情報の整理
packratがいまいち普及していないと感じる理由は、web上での情報が少ないためかなと思う。公式のチュートリアルがあったり、webinarが催されているが、その他packratを使ってみた、的な例が少ない。
日本語だと@dichikaさんの紹介記事(packratで人類の拡大再生産に貢献する - 盆栽日記)が良い。こちらの記事ではYouTubeの動画も埋め込まれているのでpackratに興味のある人は見てみると良い。
packratを使う
現在CRANに登録されている、インストールされているバージョンは0.4.3。packratの管理環境としてRprojectが想定されているので、IDEのRStudioとの相性が良い(GUI Rなどでは試していない)。新しくpackratでの管理を開始するには、.Rproject
のあるディレクトリでpackrat::init()
を実施するか、メニューバーのToolsから、Project Options... -> Packratを選択し、Use packrat with this project
にチェックをつける。これを行うと、Rの環境設定ファイルである.Rprofile
とpackrat/
フォルダが作成され、packrat管理の体制が整う。
またRStudioのpackageパネルを有効にしておくと何かと便利(ただし、パッケージのインストール状態を取得しているのか、起動時に動作が重くなる気がするので止めた)
主要関数
-
snapshot()
: プロジェクト中で使用しているパッケージおよびそのバージョンをprivate libraryにsnapshotとして記録する -
status()
: 最新のsnapshot状態と現在のライブラリ環境の比較を行う。登録されているがインストールされていないパッケージや、インストール済みだが使用されていないパッケージを確認する -
restore()
: snapshotに記録されたパッケージ情報をプロジェクト内のprivate libraryに反映する
それぞれの関数が何をしているのかを理解するには実行してみるのが一番。packrat管理の実際の手順は、
- Rコードを書く(コード内でパッケージの呼び出しを行う)
-
snapshot()
により必要なパッケージとそのバージョンを記録する -
restore()
でパッケージを適宜ダウンロード -
status()
でパッケージの状態を確認する(→適宜2と3を実行)
という感じだろうか。
実例
プロジェクト中のとあるコード内でtidyr
パッケージの呼び込みを指定するlibrary(tidyr)
を書いたとする。これをpackrat管理してみる。もちろんコード内で明記したパッケージが依存しているパッケージも管理の対象となるので細かいことは気にせず、普段通りにコードを書けば良い。
# library(tidyr) # と別ファイル中に記述しているときに
packrat::status()
# The following packages are referenced in your code, but are not present
# in your library nor in packrat:
#
# plyr
# reshape2
# tidyr
#
# You will need to install these packages manually, then use
# packrat::snapshot() to record these packages in packrat.
この状態では、パッケージがインストールされていない。インストールしてね、ということなのでまずsnapshotに登録してみる。
packrat::snapshot()
# Adding these packages to packrat:
# _
# plyr 1.8.2
# reshape2 1.4.1
# tidyr 0.2.0
#
# Fetching sources for plyr (1.8.2) ... OK (CRAN current)
# Fetching sources for reshape2 (1.4.1) ... OK (CRAN current)
# Fetching sources for tidyr (0.2.0) ... OK (CRAN current)
# Snapshot written to '/Users/uri/git/test/packrat/packrat.lock'
packrat.lock
というファイルを見るとパッケージ名、バージョン、インストール先が記録されていることがわかる。このファイルはテキストファイルなので、Git等のバージョン管理の対象ファイルとすることができる。プロジェクトでいつからこのパッケージを使用しているのかとかの記録をしたいときに有効だろう。
Package: tidyr
Source: CRAN
Version: 0.2.0
Hash: 3445f04db2073bc56edcf672268ad48a
Requires: dplyr, lazyeval, reshape2, stringi
この段階ではパッケージ情報が記録されただけで、パッケージ本体はpackrat/inst/
以下に圧縮ファイルとしてあるままなので、private libraryにパッケージをインストールするにはrestore()
を実施する。
packrat::status()
# The following packages are used in your code, tracked by packrat, but no longer present in your library:
# from to
# plyr 1.8.2 NA
# reshape2 1.4.1 NA
# tidyr 0.2.0 NA
#
# Use packrat::restore() to restore these libraries.
packrat::restore()
# Installing plyr (1.8.2) ... OK (downloaded binary)
# Installing reshape2 (1.4.1) ... OK (downloaded binary)
# Installing tidyr (0.2.0) ... OK (downloaded binary)
packrat::status()
# Up to date.
これでおk。コード内でのパッケージの呼び出し指定はlibrary()
でもrequire()
でも良い。注意として、コメントアウトしたコードや.Rmdファイルでのチャンクオプションでeval=FALSE
としているときには管理の対象とならない。あくまでも実行することを前提としているコードがpackrat管理の対象となるみたい。
もちろん手動でインストールしても良い。コード内で使用しないけど、使用したいパッケージやGitHubにあるパッケージをインストールしたいとき(.Rprofileで呼び出すパッケージとかはpackratの管理対象とならないので手動インストールする)は、コンソールでパッケージをインストールしてpackratに登録する。GitHubリポジトリにあるパッケージをダウンロードするpackrat::install_github()
も用意されている。
外部に環境を再現する
bundle()
およびunbundle()
を使う。bundle()
を使うとRproject内のファイルが圧縮ファイルとなる。この圧縮ファイルをunbundle()
することで異なる実行環境でもライブラリは同じ状態でコードを再現することが可能になる。第三者にプロジェクトファイルを渡す際はこちらの圧縮ファイルだけを渡せば済むのでお手軽。
packratでの管理をやめる
やっぱりこのプロジェクトではpackratを使う必要はないな、と思ったときなどにpackratで管理しているパッケージなどが邪魔になる。えーっい、っとpackratフォルダを削除するとpackratフォルダがないんだけどと怒られるので手順を踏んで解除する必要がある。packrat::disable()
でプロジェクトのpackrat管理を止めることができ、実行するとライブラリのパスを初期値に戻した旨が出力される。再度packrat管理する場合にはpackrat::init()
。
メニューバーからも実行可能。Tools -> Project Options... -> PackratでUse packrat with this project
のチェックを外せば、.Rprofile
を書き換えた旨が表示され、packratの呪縛から開放される。しかしまだpackratフォルダは残っているので、こちらは手動で削除するのがベターか?
まとめ: packratが使えそうな場面
個人、なおかつ普段の作業環境ではpackratの有り難みがわかりにくいような気がする。packratが使えそうな場面として次のような例を考えた。
開発環境
私的な場合ではないとき。おふぃしゃるな感じで開発したいとき...普段は{devtools}でGitHubからパッケージをダウンロードしているけど、パッケージの開発はCRANパッケージを利用したい、というとき。
複数人での作業(解析、パッケージ作成)。
コードを共有していても、お互いにインストールしているパッケージのバージョンが違うとかがあることもあるので、そういうときにはpackratで管理するのが良さ気。解析時には、再現性という理由からもpackratの利用が薦められる。数日なら良いが、1年3年と時間が経つとパッケージの関数も大きく変更されていたり、特定のバージョン以降は関数が利用できなくなっていたりすることがある。パッケージが新しくなって正常に動作しません、とかなると悲惨。
講習や勉強会
こちらも複数人での作業。例えばRの講習では、参加者が必要なパッケージをインストールしていないときに時間を割いてインストールする、ということがしばしばある。bundle()
はソースコードを含めて環境を再現することができるので、時間が限られる、オフラインの環境では良さ気。
パッケージ管理、煩わしいかなと考えていたけれど、上記の場合はいいかもしれない。使う機会があれば使ってみたい。