Rのパッケージをtidyに開発する
この記事は tidyポエム Advent Calendar 2017 - Adventar の24日目の記事です。
はじめに
今年はRのパッケージをゴリっと開発することが多かったので、そこで培った2つのノウハウをここにメモっておきます。
tidyなデータ処理があるようにtidyなパッケージ開発(標準的なパッケージ開発?)もあっていいと思うのです。
tidyverseを使うな
かつてHadley verseと呼ばれていた Hadley Wicham作のパッケージ群を集めたパッケージであるtidyverse、最高ですよね?
これさえあればモダンな形でR言語のコードが書けますし、データ集計に必要な機能(前処理・可視化)はほぼカバーされています。
なので、データ分析の時にこのパッケージを使うのはとても良いのですが、パッケージ開発時においては、迂闊にコヤツを使うべきではありません。
tidyポエムなのにtidyverseを否定する、これ如何に?
なぜ使ってはいけないのかというと、開発しているパッケージ内でtidyverseに含まれるパッケージ(dplyrとかggplot2とか)を使おうとすると非常にややこしくなるからです。
例えば、以下のようにDESCRIPTIONにtidyverseへの依存関係を記載しておきます。こうすることで、貴方が開発しているパッケージをインストールする際にはtidyverse、およびそこに付随するパッケージもオートマ―チックにインストールされるので、一見すると楽ができるように思います。
...(省略)... Imports: tidyverse ...(省略)...
しかし、いざ以下のように適当なtidyvereのパッケージ(ここではggplot2)を使用したコード
#' @import tidyverse NULL #' @export hello <- function() { ggplot2::ggplot(ggplot2::mpg, ggplot2::aes(displ, hwy, colour = class)) + ggplot2::geom_point() }
をパッケージ内で書こうとすると、Packageのcheck時に以下のような警告が出てしまい、CRANにパッケージをUPすることができません。
checking dependencies in R code ... WARNING '::' or ':::' import not declared from: 'ggplot2'
パッケージ開発においては、億劫がらずに1つ1つの依存パッケージをきちんとDESCRIPTIONのImportsに指定していくのがよいでしょう。
再現用のパッケージはこちら
ドキュメンテーションもDRY(Don't Repeat Yourself)の原則に従え
パッケージ開発時のドキュメンテーションはほぼroxygen2パッケージ一択になるのですが、
その中でも、私が最近知って多用するようになった、@rdname, @describeInというものを紹介します。
日本語で言及している記事が Triadsou さんとHeavyWatal さんくらいしか見つからなかったので。
詳細はroxygen2のvignettesを読んでおけばOKです。
これを使うと複数の関数に共通の引数や説明を丸っと一か所に記述するだけでよくなるので、ドキュメンテーションが楽になる&見通しが良くなります。
例えばこんなかんじ。@rdnameと@describeInの違いは上のVignettesを読めばOK。
#' Hello() series #' #' There are lots of hello() s. #' #' @param x something argument #' @name hello NULL #' @rdname hello #' @export hello1 <- function(x) {print("Hello1")} #' @rdname hello #' @export hello2 <- function(x) {print("Hello2")} #' Hoge() series #' #' There are lots of hoge() s. #' #' @param x something argument hoge <- function(x){} #' @describeIn hoge I'm hoge1 hoge1 <- function(x){"hoge1"} #' @describeIn hoge I'm hoge2 hoge2 <- function(x){"hoge2"}
皆さんのRパッケージがよりtidyになりますように。