1. okiyuki99

    No comment

    okiyuki99
Changes in body
Source | HTML | Preview

renv とは?

RStudioが開発を進めているRのPackage管理のためのパッケージである

パッケージ管理といえば、Pythonでは新しいパッケージが次々出ており、流れをキャッチアップするだけで一苦労だが、RではこれまでRStudio社のPackratくらい?しかなかったように思える(私が知らないだけかもしれないが)

パッケージ管理が必要な理由としては、Rの場合は主に分析の再現性を担保するためだと思う。とくに、複数人でRプロジェクトをおこなうときに威力を発揮する。また自分の場合、CIでテストを行うときやShiny Appを開発するときにも威力を発揮している

なぜrenvが開発されているかの背景を理解するためにrenvProject pageに書いてあるGoalを見てみる

The goal is for renv to be a robust, stable replacement for the Packrat package, with fewer surprises and better default behaviors.

この一文から、Packratを代替しながら、より安定して使いやすいものを目指していることがわかる。Packratを使ってるRユーザはどれくらいいるのだろうか。少なくとも自分の周りでPackrat使ってますという話はほとんど聞かない(自分はそこそこ使ってたほうだと思う)

Packratの使い道を考えてみたがとても詳しいので、Packratの解説は省略します)

Packratとの違い

renvPackratとの違いはProject Pageに書かれている。大きいところとしては、renv.lockというjson形式でRプロジェクトで使用しているパッケージのメタ情報を保存してくれることや、global cacheという仕組みでRプロジェクト間でパッケージを共有できる仕組みがある。そのため、Rプロジェクトを変更するごとに、毎回CRANにパッケージをダウンロードする待ち時間が発生するのはほとんどなくなった点が大きい

global cacheは簡単に言うと、ローカルのhomeディレクトリのような決められた配下にパッケージを保存して、Rプロジェクトで利用するときに、キャッシュがあるなら、そこへのリンク(正式にはシンボリックリンク)を貼ってくれる仕組みである

個人的な感想

Packratをそこそこ使ってた私の感想としては、global cacheにより待ち時間が減り、デフォルトの挙動が覚えやすいので、今のところ使いやすい印象です。そのため、Rでパッケージ管理したことがない方へも導入のしきいは低くなっていると感じます

参考情報

インストール

2019-08-16時点のversion 0.6.0.108を使用した解説になります

2019-08-16時点では、CRANにはまだアップロードされていないので、Githubからインストールする

2019-11-06にCRANについにアップロードされました! renv: Project Environments for R

> remotes::install_github("rstudio/renv")
<snip>
> packageVersion("renv")
[1] 0.6.0.108

基本的な使い方

同じホストでの作業

  1. renv::init() をする
  2. Rコードを書く
  3. renv::snapshot() をたまにする
  4. 作業を終えたら、renv::snapshot()をして、編集したファイルとともに renv/renv.lock ファイルらをgit commitする

違うホストから使うとき

  1. git clone したのちに、renv::restore()
  2. あとは同じ

それぞれ主に使うコマンドを簡単に解説する

renv::init()

renvによるパッケージ管理を始めるために使用する

実行すると、renv/というprivate R libraryの置き場と、.Rprofileが作成される

.Rprofileには、source("renv/activate.R") が記載されており、Rプロジェクト開始とともにrenvによるプロジェクト管理をスタートする処理が書かれている

> renv::init()
* Discovering package dependencies ... Done!
* Copying packages into the cache ... [300/300] Done!
* Resolving missing dependencies  ... 
* Querying repositories for available source packages ... Done!
Retrieving 'https://cloud.r-project.org/src/contrib/fclust_2.1.tar.gz' ...
    OK [downloaded 86.2 Kb in 0.8 secs]
<snip>

完了後、.libPaths()を実行してみると、private R libraryが使われている事がわかる(2つめはよくわかっていない)

> .libPaths()
[1] "/home/ooki/renv-sandbox/renv/library/R-3.6/x86_64-pc-linux-gnu"
[2] "/tmp/RtmpUk1Icd/renv-system-library"     

このときprivate R library配下にパッケージのソースが置かれるのではなく、global cache配下(Linuxだと~/.local/share/renv)に置かれ、private R libraryにはそこへのリンクが置かれる

$ ls -la ~/renv-sandbox/renv/library/R-3.6/x86_64-pc-linux-gnu/
<snip>
lrwxrwxrwx 1 ooki ooki  124 Aug 16 19:24 assertthat -> /home/ooki/.local/share/renv/cache/v4/R-3.6/x86_64-pc-linux-gnu/assertthat/0.2.1/87318c127c936afe4da4d066d1fd01c3/assertthat/
lrwxrwxrwx 1 ooki ooki  122 Aug 16 19:24 backports -> /home/ooki/.local/share/renv/cache/v4/R-3.6/x86_64-pc-linux-gnu/backports/1.1.4/8ed7589b3c92d5dc620c45b5f0909d9f/backports/
lrwxrwxrwx 1 ooki ooki  111 Aug 16 19:23 BH -> /home/ooki/.local/share/renv/cache/v4/R-3.6/x86_64-pc-linux-gnu/BH/1.69.0-1/a3839f6fcfa121ea0b5c4b3a0b42456e/BH/
<snip>

renv::snapshot()

このコマンドにより、Rプロジェクト配下のファイルに新たなライブラリが使われていたら、renv.lockに書き込んでくれる。変更がない場合は、以下のようなメッセージがでる

> renv::snapshot()
* The lockfile is already up to date.

たとえば、新たにtidyrパッケージを使うために、install.packages("tidyr") と実行する。global cacheにすでに存在する場合は、そこへのリンクを貼ってくれるだけなのですぐに完了する

> install.packages("tidyr")
Installing tidyr [0.8.3] ...
    OK (linked cache)
* Lockfile written to '~/renv-sandbox/renv.lock'.

library(tidyr)と新たに.Rファイルに追加してから実行すると、再度snapshotを実行すると、tidyrが使われていることをrenvが発見してくれて、renv.lockに書き込んでくれる。

> renv::snapshot()
The following package(s) will be added to the lockfile:
        _        
  tidyr   [0.8.3]

Do you want to proceed? [y/N]: 

この辺の発見ロジックは、https://github.com/rstudio/renv/blob/master/R/dependencies.R#L488-L494 あたりのrenv::dependecies()あたりにより実現されていると思われる。

(つい先日 pacman::p_load()renv::dependecies()に対応していないIssueをあげたのですが、翌日には対応してくれるほどのスピード感だったので驚いた : https://github.com/rstudio/renv/issues/143 )

renv::restore()

別のマシンやCIからRプロジェクトと同じパッケージをインストールするときに使う。基本的にrenv.lockファイルさえあれば動くので、Gitでrenv.lockを管理しておけばどこからでも同じ環境が再現しやすい。

今のところ自分はDocker ImageやCIのまっさらな環境に、renv::restore()させてから、Testさせるときに使っている

> renv::restore()
The following package(s) will be installed:
               _             
  BH             [1.69.0-1]  
  R6             [2.4.0]     
  RColorBrewer   [1.1-2]     
<snip>
Do you want to proceed? [y/N]: y
<snip>

renv自体をupdateしたいときは?

renv::upgrade でversionを指定すれば、renvのupdateが行われ、管理してるrenv.lockファイルも自然と更新される

renv::upgrade(version = "0.9.2-12")

その他コマンド

renv::status()

renvによるパッケージの管理状態を知るコマンド(といってもあまり使わない)

> renv::status()
* The project is already synchronized with the lockfile.

renv::dependencies()

プロジェクトにあるソースとパッケージの関係を出力。おそらく、renv::snapshot()等で使われる

> renv::dependencies()
Finding R package dependencies ... Done!
                              Source Package Require Version
1 /home/ooki/renv-sandbox/analysis.R   dplyr                
2 /home/ooki/renv-sandbox/analysis.R ggplot2                
3 /home/ooki/renv-sandbox/analysis.R   tidyr                
4   /home/ooki/renv-sandbox/script.R remotes                
5   /home/ooki/renv-sandbox/script.R    renv 

renv::hydrate()

ProjectのなかでSystem libraryから使われているPackageをprivate R libraryにインストールしてくれる。renv::init() の中でこれが実行されている模様

> renv::hydrate()

renv::clean()

使ってないライブラリをPrivate R libraryからRemoveしてくれる。たまにお掃除したくなったときに使う

> renv::clean()

renv::settings$ignored.packages()

renv管理から無視するパッケージ(testやdevtoolsなどが該当するかと思う)を設定する
参考 : https://rstudio.github.io/renv/reference/settings.html

> renv::settings$ignored.packages()
character(0)
> renv::settings$ignored.packages("devtools", persist = FALSE)
> renv::settings$ignored.packages()
[1] "devtools"

renv::settings$use.cache(FALSE)

renvのglobal cacheを使わなくする

renv::settings$snapshot.type("simple")

renvのsnapshotの方法を変更する。デフォルトはpackratsimpleにしたら、もとのRのユーザライブラリのすべてをrenv.lockに書き込もうとするようになる

今後

今のところ、version 0.7でCRANに登録予定。また、1.0に向けて実装は日々進んでいるので、今後も楽しみである。Packratはあまり周りで使ってる人はいなかったが、renvは使い勝手といい、分析の再現可能性担保のためにも流行ってほしいなと個人的には思っているので、ぜひみんな使っていってほしい

参考 : https://github.com/rstudio/renv/issues/115

追記

renvの有用な情報を更新していきます