備忘ログ

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

CRANからremoveされた他の人の作ったパッケージを再登録させた話(ポエム)

この記事はR言語 Advent Calendar 2023の2日目の記事です。Rに少しでも関連していれば誰でもなんでもOKとのことで、本稿はその趣旨を信じて次に記載する本稿の要旨の通り、R言語のHOW TOやトリビア的な内容ではありません(お祭りに参加したいけど手持ちネタがない人です)。基本的にはポエム的な内容なので敬体で記述していきます。

qiita.com

本稿の要旨

CRANからremoveされた{mvnmle}パッケージを開発者である元のメンテナーの許諾を得てCRANへの再登録を行ったので、その経緯と経過、この経験から感じたことについて書いています。

Rで使いたい(使っていた)パッケージがCRANからremoveされてしまったらどうする(まえがきのまえがき)

R言語でさまざまなデータや統計処理などを行うときには、追加でパッケージをインストールし読み込み利用することが多いと思います。特に、「◯◯という処理をするにはどうしたらいいだろう」と書籍やwebページにあたり、その中に記載されているパッケージをインストールしようと考える場面はそうした中ではしばしばあると思います。

このとき、やや古めの書籍やwebページの場合には紹介されているパッケージがCRAN(The Comprehensive R Archive Network)からremove*1されており、install.packages()を用いてCRANからインストールしようとすると、

##  Error: package '***' is not available

などエラーメッセージがでてきてしまいインストールできないという場面に遭遇することがあります。

GitHubなどの他のリポジトリで公開が継続されている場合にはそちらからインストールするという方法を取ることができますが、CRANにしか公開されていないパッケージの場合の解決策としては

  • CRANからremoveされたパッケージをArchiveからインストールする。

  • 同じような機能を有する現在CRANに登録されている(あるいはGitHubなどに公開されている)他のパッケージを探し、インストールする。

という方法*2が考えられます。

CRANからremoveされたパッケージをArchiveからインストールする方法としては、Posit社のInstalling older versions of packagesという記事にも書いているとおり、{remotes}パッケージ*3install_version()関数を用いてインストールする方法*4と、Archiveされたソースパッケージ(.tar.gz)をCRAN(Index of /src/contrib/Archive)からダウンロードしてソースパッケージをインストールする要領でinstall.package()を使ってインストールする方法があります(ソースパッケージをダウンロードする手間の問題くらいの差)。

また手間的にはそんなに変わりませんが、CRANの非公式のパッケージのミラーであるcran · GitHubから{remotes}install_github()をつかってインストールする、という方法もあります。

ただし、依存関係にあるパッケージもCRANからremoveされている場合には先にremoveされている依存関係にあるパッケージをインストール必要があったり、新しいRに対応しておらずうまく挙動しない可能性があるなど、Posit社の記事にもあるとおり潜在的な問題を有する可能性もあります。

また、CRANからremoveされたパッケージの代替案を探すという方法をとることができれば長期的な視座からはメンテナンスがなされているパッケージを使用できるということでとても良いのですが、そもそも代替案のパッケージを探すのに手間がかかる場合があることや、手法の勉強中などにとりあえず書籍やwebページの記載どおりに出力結果を得たい場合(例えば書籍に一行ずつの処理のコードが書いてあり、ライブラリを使った結果と一緒だよね、みたいなのを示してくる場合*5など)には全く同じ出力結果が欲しくなりますが、そういうパッケージが見つかるとは限らないというのが、パッケージの代替案を探すという手法の大きなデメリットです。

CRANからremoveされたパッケージの作者に連絡をとり再登録を図るという第三の選択肢について(はじめに)

CRANからremoveされたパッケージを利用したい場合に、

  • Archiveされたパッケージを利用する。

  • 代替となるパッケージを探す。

という2つの選択肢(再実装を加えると3つの選択肢)について上記で記載しましたが、第三の選択肢として、CRANからremoveされたパッケージの作者に連絡をとり再登録を図るという方法について本稿では書いていきます。

ところで、CRANからパッケージがremoveされるのは、パッケージ作者(メンテナー)自らが取り下げを行うこともできるようです*6が、多くの場合はCRANが定期的に行っているパッケージのR CMD checkの結果ERRORとなり、更新がなされない場合にCRANからremoveされArchiveとなります*7。これは、特にR本体のマイナーバージョン以上のアップデートでしばしば起こるとのことで*8、コードそのものよりもRのPolicyや細かい挙動の変更に伴って弾かれてしまっている例があるのではないかと思っています。その証左として、removeされたパッケージもArchiveからインストールして以前の通り利用できる(場合もある)のだと思います。

パッケージメンテナー自らがパッケージの取り下げを行った場合には何らかの複雑な事情を抱えている可能性があり、再登録は困難であると思いますが、それ以外の場合には上記のようにR CMD checkERRORさえ回避できれば再登録できそうです。

ここで選択肢としてもう一つ、CRANに登録されているパッケージは基本的にオープンソースソフトウェアライセンスなので、

  • removeされたパッケージをフォークして適切な修正を加えた上で新しいパッケージとしてCRANに登録し、利用する*9

という方法を取ることができます。

そもそも、

  • removeされたパッケージがR CMD checkERRORが解消されCRAN再登録され、利用する。

と幸せになれる気がします。これは、既存の資産としてそのパッケージをほぼそのまま利用できるだけでなく、そのパッケージを使って今まで処理していたものがそのままパッケージ名、関数名を変えずに今までの通りのコードを欠くことができ、今後も同様にコードを書くことができるというメリットがあります。

このメリットはCRANからremoveされたパッケージをフォークし再登録した場合には享受することができません。なぜなら、フォークして再登録してもCRANのPolicy上、現在と過去にCRAN(とBioconductor)に登録されたパッケージと同じ名前のパッケージを登録することができないという制約上*10、パッケージ名は必ず変更となるため既存のそのパッケージを使ったコードの少なくともパッケージ名は修正する必要があるためです。

また、CRANからremoveされたパッケージを再登録した場合、再登録した個人のメリットというよりRを利用している全体の利益として、書籍やwebページ等で紹介されているが現在はCRAN上からremoveされたパッケージが(いつの間にか)同じパッケージ名で再登録されれば、「あれ、このパッケージを使いたいのにCRANから削除されてる」などと思って困る人が一人でも減り、余計な手間(Archiveからインストールしたりするなど)が減り幸せになる人が増えるのではないかと思います。

今回、CRANからremoveされたパッケージで元のパッケージメンテナーに連絡をとり、CRANに再登録したという経験をしたため、あまりそういう記事を少なくとも邦文で読んだことがないので記事にしておこうと思います。

経緯と経過

欠測値の処理について考えていたときに、{mvnmle}パッケージのmlest()という関数があることを知りました*11

このパッケージを最初に使うにあたって、CRANからパッケージがremoveされていたので前述した手法を用いてArchiveからインストールして使用しており、個人的には特段の問題はありませんでしたが、いろいろ調べていると{mvnmle}がCRANからremoveされてインストールできなくて困っている的な話を見かける機会がありました(が、当該文書を見つけることができなかったので口頭で聞いたのかもしれません)。

また、今年のはじめ頃にr - Orphaned package etiquette - Stack Overflowという記事をみて、ちょうど前の作業が一段落ついて手が空いたこともあって、「そいうえば{mvnmle}もORPHANEDだった」と思い出して、なんとなく{mvnmle}の周辺事情を調べてみました。

ちなみに、r - Orphaned package etiquette - Stack Overflowの内容は、自分が使っているパッケージのメンテナーがORPHANEDになってしまったけど、将来メンテナンス不足でArchivesになるのは惜しいからメンテナー引き継ぎたいけどどうしたらいい?という質問内容で、とりあえず元のメンテナーにコンタクト取ったらいいんじゃない。という回答内容でした。

{mvnmle}パッケージの生まれはとても古くArchive*12を見ると最も古い版が2001年のもので、20年以上も前に作成されたことがわかりました。そしてremoveされた当時の0.1-11.1バージョンではメンテナーがORPHANEDとなっており、元のメンテナーがメンテナンス指定ない状態でした。ArchiveのDESCRIPTIONを辿っていくと2011年の0.1-10まではパッケージの開発者であるKevin Grossがメンテナーですが、2012年の0.1-11からメンテナーがORPHANEDとなっていました。

ORPHANEDとなった理由は、「メンテナーにR 2.14.0に対応するように依頼したが返事がなかったから」とDESCRIPTIONに書いてありました。そこからメンテナーがORPHANEDとなった0.1-11バージョンと、その次の2018年の0.1-11.1バージョンとで0.1-10バージョンから(おそらくCRANの中の人の手によって)軽微な修正が加えられて、最終的に2020年にR CMD checkの結果ERRORとなりCRANからremoveされていました。

R CMD checkERRORとなった理由は、当時の{mvnmle}パッケージのCRANのページにcheck results archiveがあり、正確な文言は忘れてしまったけれどRcpp::compileAttributes() Error - Stack Overflowと同じような内容で、多変量正規分布最尤推定を行う計算自体のコードには問題はなく、CRANへの対応は比較的に簡単に対応できそうだと考えました。

そこで、r - Orphaned package etiquette - Stack Overflowに記載されている通り、元のメンテナーに「{mvnmle}のメンテナーがORPHANEDになりその後、現在CRANからremoveされていますが、再投稿する予定ありますか?もし再投稿するのであれば、removeされた原因解決のお手伝いできるかと思います。その気がなければ、もし気を悪くしなければでいいのですが、私の方でremoveされた原因を解決して再投稿しても良いですか?」(要旨)とメールしました。

だいぶ長いことメンテナンスしてない初版が20年以上前のパッケージの件だから返信ないかもな、と思っていたら数日の間をあけて返信があり、「私の方では再投稿する予定はないから、もし再投稿したいのであればいいよ。」(要旨)と返事がありました。

そこで、CRANからremoveされたパッケージのソースファイル(tar.gzファイル)をダウンロードし、R CMD checkERRORとならないような最低限の処置を施し、その他は元のコードのまま(もちろん、R-hub package builderでもERRORが出ないことを確認し)CRANに再投稿してみました。CRANにパッケージを再投稿を行う手順については、新規にパッケージを投稿する手順と同じように行いました*13

そうしたところ、CRANからドキュメントの文献リストの文献はDOIやISBNをつけてくださいなど複数の指摘を受けました。

うけた指摘自体はCRANのRepository Policyに記載されている*14とおりなのですが、以前から存在するパッケージ、例えば{GPArotation}などは現在でもDOIやISBNが記載されていない文献リストが記載されており、過去のPolicyに適合し登録されたパッケージのアップデートなどではその点についてはreject理由とされていないようですが、一旦removeとなったパッケージについてはそうとは言われていませんが新規投稿と同じように現在のCRANのRepository Policyに合致しているかチェックされるようでした*15

そこで、コードそのものは書き換えないようにしつつ、それなりにいろいろな点をモディファイして再投稿を図りました。

その結果、挙動は変わらないままCRANに受理され、再登録されることとなりました。

めでたしめでたし。

ORPHANEDについて

今回、この記事を書くに当たり、RのパッケージのORPHANEDについて少し調べたところORPHANEDになったパッケージを誰かが引き継いでいる例はいくつか見つけることができました。

たとえば、先に上げたr - Orphaned package etiquette - Stack Overflowで話題にされていた{sapa}もそうです。また、先に脚注で少し触れた{nrom}も一度ORPHANEDとなって現在別のメンテナーによりメンテナンスされているようです。ほかにもさまざさまざまなパッケージメンテナーがORPHANEDとなり、他のメンテナーに引き継がれたものがあるようです。

ORPHANEDになる経緯は元のメンテナーが時間がなくなったり興味がなくなったりしたなどの経緯から自主的にORPHANEDにする場合と、CRANからの連絡にメンテナーからの返事がなかった場合になるようです*16。また、パッケージメンテナーがORPHANEDになったパッケージのメンテナーの引き継ぎはCRANとしては歓迎されているようです。

ORPHANEDになった(なる)経緯はわかったのですが、ORPHANEDになる条件は上記以上はわからなかったです。ORPHANEDになるとき(またその後も)に、当時のRのPackage Policyに適合する処置が(おそらくCRANによって)なされていますが、現在のCRANの運用的には再投稿が必要な修正がある場合にはパッケージメンテナーに連絡が行き軽微な修正であっても修正・再投稿がなされない場合にはCRANからremoveされるという運用になっているはずです*17

2. 石田基広徳島大学教授との対談 | R Radio for the Rest of us.石田基広氏が昔のCRANのパッケージ登録について比較的ファジーな運用がなされていたと話しており*18、私が確認できたORPHANEDになったパッケージが比較的古いパッケージが多いことから、想像の域は出ませんがパッケージメンテナーがORPHANEDになるパッケージの存在はCRANの運用が比較的牧歌的な時代の産物なのかもしれないと思っています。

もしこの点についてご存じの方がいたらお教えいただければ嬉しいです。

メンテナーを引き続くことについて

Posit社の社員が開発しているパッケージなどのごく一部のパッケージを除けば、CRANに登録されているパッケージの多くは基本的にボランティアが開発、メンテナンスしています。そのためさまざまな事情でCRANのPolicyに適合できずremoveされてしまうのはやむを得ません。これはパッケージメンテナーをORPHANEDから引き継いだ場合も例外ではなく、{sapa}はORPHANEDから次のメンテナーに引き継がれたあと、現在、CRANから昨年removeされています。

{mvnmle}パッケージの元のメンテナーからのメールにもあったとおり興味が変わったり、CRANのORPHANEDの文書にもある通り忙しくなったなどのさまざまな理由からパッケージをメンテナンスすることができなくなる可能性はありえます。なので、普段使っているパッケージがRのPolicy変更にともない突然にCRANからremoveされてしまう可能性は大いにありえます。

現状、パッケージを引き継ぐためにはORPHANEDとなっていないパッケージはCRANに元のメンテナーからメールしてもらう必要があります*19。なので、今回はパッケージメンテナーがORPHANEDとなっていたことと、元のメンテナーが親切にも返事をくれたことは大変幸いでしたが、CRANからremoveされてもパッケージメンテナーの引き継ぎに興味がなかったり、忙しかったりなどのさまざまな理由により返信をされない可能性もおおいにあると思います。ただし、元のメンテナーと連絡がつかないなど、場合にはメンテナーを元のメンテナーの了承を得ずにメンテナーを引き継ぐこともできるようです*20が、引き継げないパッケージは無理せずに他のパッケージを探すかCRANに登録されているパッケージは基本的にはオープンソースソフトウェアなのでフォークして使っていく(場合によってはCRANへの登録をはかっていく)*21のがいいのかもしれないと思いました。

Rのパッケージのメンテナーの引き継ぎについては、Rパッケージを査読し支援するコミュニティーであるrOpenSciはパッケージメンテナーをやめたい人とパッケージメンテナーを引き継ぎたい人をつなぐ活動も行っています*22。そして、実際にその成果も上がっています*23。ただし、科学的な解析解析に使われるパッケージのみがrOpenSciの守備範囲なのでそれ以外の膨大なパッケージは対象外となります*24

なんでこんなことを思っているかというと、今後、自分自身がパッケージをメンテナンスできなくなるときがきたときに、もし自分で意図してメンテナンスをやめてCRANからremoveした場合を除いては、「もし、CRAN Policyに適合できず、CRANからパッケージがremoveされた場合またされそうな場合は、それは私の望んだ結果ではなく誰でもパッケージメンテナーを引き継いでCRANへの再登録を図っていただいてかまいません。」などと宣言しておいて誰かが勝手に引き継ぎたかったら引き継いでもらえるような感じ(そういう制度があれば)にしておけたら、人間ですのでいつ何があるかわからないのでパッケージがある日突然使えなくなって困る人が減るのではないかと考えたためです。

ところで、パッケージメンテナーは、元のメンテナーからパッケージを引き継いただ場合、新たなRの仕様変更に追随しパッケージが動作するようなコードの修正や追加は期待されていますし、当然の役割と思います。ここで私が問題になると思うのは、メンテナーはCRAN側としてはパッケージに含まれるコードの変更や追加の全権を有して(パッケージ側の開発体制・プロセスのいかんはここでは問題とはしません)いますが、元メンテナーからメンテナーを引き継いだパッケージでも保守以上の部分、つまり新メンテナーが従来の挙動を変更するようなコード変更や機能追加は期待(許容)されるかのかという点です。

アクティブに開発されていたパッケージを、元メンテナーから引き継いだ場合などは元の開発方針を引き継いでアクティブに開発していけば良いと思いますし、メンテナー変わったから今後はコードの保全しかしないと宣言して動態保存のような保守管理に徹するという方針を取るのもよいと思います。ただし、アクティブに開発されていなかったパッケージのメンテナーを引き継いだ場合、どうするかというのはアクティブに開発されていたパッケージとは少し事情がかわると思います。前述したように引き継いだパッケージメンテナーがコードを修正・変更・追加しCRANに登録する権限を有しているので、従来の挙動を変更しCRANに登録することは可能です。可能な一方で、それは期待される役割なのだろうかという問題です。

まさに{mvnmle}がこの、アクティブに開発されていなかったパッケージに当たるのですか、この点をどうするかというのは、私個人の考えとしては基本的にはR上でパッケージの関数が動作するための保守に徹したほうがよいと思っています。アクティブに開発されていないパッケージでも、見逃されていた重大な計算上の誤り等があれば修正する必要があるかもしれませんが、従来から出ていたメッセージを制御したりするのは個人的には望まれておらず、従来どおりの動作をすることのほうが重要ではないかと思っています。ただし、これは個人的な見解でそれぞれの意見があるかもしれません。ただ、個人的な見解としては、アクティブに開発されていなかったパッケージに手を入れたいのであればメンテナーを引き継いでアクティブに開発し始めるよりも、フォークして新しいパッケージとして開発を進めたほうが良いのではないかと思っています。

CRANへの再登録後の経過

パッケージ登録の手続きなどは通常のCRANのパッケージ登録(再登録)の手順と同じなので、CRANにパッケージ登録をしたことがあれば(込み入った修正が必要な場合を除いて)それほど難渋することはないかと思いました。ただ、一度、CRANからremoveされ1年以上経過したパッケージを再登録して、誰が使うんだろうというところはもちろんあるかと思います。

{mvnmle}については再登録されたことについては再投稿、{cranlogs}パッケージのcran_downloads()をつかってパッケージのダウンロード数をみるとおおよそ平均16件/日程度ダウンロードされているようです*25

そのため、世界の誰かの一助になっているのではないかと思っています。

その他雑感

CRANからremoveされたパッケージを再登録したわけですが、やや「寝た子を起こしてしまった」感を感じています。平均16件/日のダウンロードがあるということは割りと需要がどこかしらかにあったというわけですが、需要があるなら再開発されてもよかったかはず。そうではなかったということは……。と考えてしまいます。

*1:removeについて、本稿ではそのままremoveと記載していきます。削除とするとCRAN上から抹消された印象を受けますが、Archivesとしてソースパッケージ(tar.gz)は残っており削除されたというよりも表舞台から除かれたという印象を個人的には抱いているからです。表舞台から除かれたという表現についてはCRANから消えた"Archived R package"をインストールしたい - Yoshi Nishikawa Blogでみて穏健な言い回しだなと感じ使っていますが、一般的かどうかはわかりません。

*2:もちろん、どういう処理をしたいのかわかっているのであれば自分で再実装するという方法ももちろんありえます。再実装した関数を含むパッケージをCRANに登録し周知することで誰かの助けになる可能性は大いにあると思います。

*3:記事中は{devtools}となっているが、本体は{remotes}のinstall_version()関数を呼び出しているだけ。

*4:上記の記事中は記載がありませんが、{remotes}のinstall_url()でArchiveのURLを直接しても変わらないです 。 r - Install the package that has been removed from the CRAN repository easily - Stack Overflow

*5:Jonathon D. Brown(2018). Advanced Statistics for the Behavioral Sciences A Computational Approach with R. Springer Cham. 354 - 356. https://doi.org/10.1007/978-3-319-93549-2

*6:Packages will not normally be removed from CRAN: however, they may be archived, including at the maintainer’s request. CRAN Repository Policy

*7:Packages for which R CMD check gives an ‘ERROR’ when a new R x.y.0 version is released will be archived (or in exceptional circumstances updated by the CRAN team) unless the maintainer has set a firm deadline for an upcoming update (and keeps to it). CRAN Repository Policy

*8:Maintainers will be asked to update packages which show any warnings or significant notes, especially at around the time of a new x.y.0 release. Packages which are not updated are liable to be archived. CRAN Repository Policy

*9:当然、元のパッケージのライセンスなどに注意が必要。

*10:Packages should be named in a way that does not conflict (irrespective of case) with any current or past CRAN package (the Archive area can be consulted), nor any current Bioconductor package. Package maintainers give the right to use that package name to CRAN when they submit, so the CRAN team may orphan a package and allow another maintainer to take it over. CRAN Repository Policy

*11:{mvnmle}は欠損値のあるデータの多変量正規分布の平均と分散共分散行列の最尤推定値を計算するためのパッケージです。他に同じような計算を行うパッケージとしては{nrom}があります

*12:Index of /src/contrib/Archive/mvnmle

*13:CRANへの投稿自体は、「cran package submission」と検索しでくる内容を参考にするとできる。R Packages (2e) - 22  Releasing to CRANが参考になります。だいたい{devtools}パッケージを使っとけばなんとかなる。 Thank you, Hadley . 自分の他のパッケージの投稿時の記録としては次の通りCRANにパッケージを登録したのでその思い出をメモしておく - 備忘ログ

*14:たとえば、文献リストのDOIややISBNの記載については"Citations in the ‘Description’ field of the DESCRIPTION file should be in author-year style, followed by a DOI or ISBN for published materials, or a URL otherwise. Preferably, the year and identifier would be enclosed, respectively, in parentheses and angle brackets."とあります。 CRAN Repository Policy

*15:もしかしたらCARNからパッケージがremoveされてからの期間がかなりあいているのも関係あるかもしれませんが、その点の詳細はわかりません。

*16:https://cran.r-project.org/src/contrib/Orphaned/README

*17:実際にはORPHANEDになっているパッケージもあるのかもしれませんが私が観測した範囲では近年新たにORPHANEDになったパッケージは見つけられず そこらへんの運用基準はわかりませんでした。

*18:2. 石田基広徳島大学教授との対談 | R Radio for the Rest of us.の5分程度から

*19:When a new maintainer wishes to take over a package, this should be accompanied by the written agreement of the previous maintainer (unless the package has been formally orphaned). CRAN Repository Policy

*20:[R-pkg-devel] How to fix Archived Package Rpdb?の結果、CRAN - Package Rpdbと再登録に至っている

*21:もちろん新たに実装し直すというのもありだと思います。本稿の趣旨はremoveされたパッケージの再登録なので。 {mvnmle}について調べているときに、中澤港氏が「メンテされていないパッケージを使うより,(中略)を読んで自分でコーディングした方が良いと思う。」と書かれていてぐうの音も出ないと思いました。 鐵人三國誌・アーカイヴ【第615回】 年明け初ミーティング(2021年1月7日)

*22:Chapter 11 Changing package maintainers | rOpenSci Packages: Development, Maintenance, and Peer Review

*23:rOpenSci | Relaunching the qualtRics package

*24:ほかにもなにかパッケージのメンテナーの引き継ぎを支援している活動があるかもしれませんが、私の観測範囲では見つけることができませんでした。

*25:いまはPosit社(旧RStdio社)のCRANパッケージミラーがRStudioユーザの初期設定のミラーであり、CRANパッケージのミラーとして選択している人が多いとは思いますが、唯一のミラーではないので実際にはもう少しだけうわぶれする可能性はあります。