備忘ログ

チラシの裏的備忘録&メモ

Rのパッケージで作成・入力するcashや、設定、データファイルのうちRのセッション間で共有したい値をどこに保存すべきかというメモ

Rのパッケージで作成・関数実行時に入力するcashや、設定、データファイルのうちRのセッション間で共有したい値をどこに保存すべきかというメモ。

Rのパッケージを適当に作っているときに、パッケージに含まれない(含むことができない)値を関数等の挙動で使用したい場面がある。都度都度、値をつくったり入力してもらったりしてもよいが、Rのセッション間で共有して一度設定したら同じ値を次回以降は入力せずに使えるようにしたいということがある。

例えばパッケージに含めないある程度大きなデータだったり、挙動に関するユーザー固有の設定値だったり。私家パッケージであれば、データをどこに保存してもいいし、どこの値を設定値として参照してもいいといえば、それまでだけれど、私家パッケージであってもディレクトリ構造がとっちらかったりしないようにRでいい感じに管理したいと思う。また、ルールに則って管理するという点でいうとCRAN Policyに従った扱いのほうが良い気もする。

例えば設定値等であれば、環境変数を管理する{config}パッケージやログイン情報やパスワードを保存・参照する{keyring}パッケージを使うのもひとつの方法であるが……。

他にはCRAN Policyを読むと、

For R version 4.0 or later (hence a version dependency is required or only conditional use is possible), packages may store user-specific data, configuration and cache files in their respective user directories obtained from tools::R_user_dir(), provided that by default sizes are kept as small as possible and the contents are actively managed (including removing outdated material).

とあり、R 4.0.x以降では{tools}パッケージのR_user_dir()を使って指定したディレクトリにデータファイルや設定値、cash値を保存してもいいよ、とある。

tools::R_user_dir()はパッケージ名と、ディレクトリの用途をdataかconfigかcashで指定するとそれに合わせたディレクトリのパスが返されるので、そこを使うとよいということになる。

ただし、このディレクトリは存在するとは限らず(というか最初はない)、値を書き込んだりする必要があればまずはディレクトリをdir.create()を使って作る必要がある。ここにおいて、最終的に指定されたディレクトリよりも上のディレクトリが存在しない可能性があり(というか最初はだいたいない)、更に引数としてrecursive = TRUEを指定し、指定した最終パス以外も一緒に作成するように指定する必要がある。

これで、パッケージごとに自由が使えるディレクトリが作成されるので、ここにパッケージインストール後に保存すべき設定値やデータがあれば保存するとよく、必要時その値を参照すると良い。

同様の挙動を{rappdirs}パッケージのuser_*()関数でそれぞれ指定されるディレクトリを使用しているパッケージもある。

これもドキュメントを読むとCRAN Policyに沿った方法で、R セッション間で共有する必要があるファイルや値を保存できるディレクトリを指定できる。

{rappdirs}user_*()関数で指定されるディレクトリとtools::R_user_dir()で指定されるディレクトリは微妙に差異がありPolicy的にはファジーな扱いなのかもしれなく、どっちのほうが良いとか特にないのかもしれない。

ちなみにGithub上でコードを検索するとtools::R_user_dirで検索するとRのコードが約3700ほどヒットするが、rappdirs::userで検索すると約890ほどヒットする。実際のパッケージでどの程使われているかはこれだけでは実数は分からないが、{tools}パッケージはR core Team謹製だし、CRAN Policyにも書いてあるので使いやすいのかもしれない。