第1章 新しくRパッケージを作る

細かいことは抜きにしてRのパッケージを作ってみよう。RStudioとusethisパッケージを使えばそれは簡単にできる。

1.1 RStudioからRのパッケージをつくる

右上のプロジェクトアイコンからNew Projectを選ぶ。

次に、New DirectoryR Packageと選んでいく。

最後に、Rのパッケージ名を入力し、Create a git repositoryにチェックを入れたら、Create Projectをクリックする。

これでひとまずひな形が完成する。しかし、ここからまだやることは多いので油断しないように。

1.2 RStudioのプロジェクト設定を変える

ドキュメントやNAMESPACEはRoxygen(後述(たぶん))を使って書きたいので、そのあたりがビルド時に自動で生成されるように設定を変更する。 BuildメニューからConfigure Build Tools…を選び、Generate documentation with Roxygenにチェックを入れる。 チェックを入れるとポップアップが出るが、そこで選ぶべきものは特にないので、そのままOKを押せばいい。

1.3 不要なファイルを消す

初期状態ではhello.Rみたいなファイルが見本として置かれているが、不要なので消す。具体的には以下の3つ。

  • R/hello.R
  • man/hello.Rd
  • NAMESPACE

NAMESPACEを消す(usethis::use_namespace()で上書きしてもいい)のは、初期状態のNAMESPACEがあるとRoxygenによる自動生成が動かないため(Roxygenは、既に存在しているNAMESPACEがRoxygenで自動生成されたものでなければ上書きしない)。

消した後でCtrl+Shift+D(Windowsの場合)でドキュメントを生成してみよう。 以下のようなNAMESPACEができているはずだ。

# Generated by roxygen2: do not edit by hand

1.4 Git

1.4.1 コミット

このあたりまでは間違いないが、次のステップでは色々なパターンがあるので間違えた場合に備えていったんコミットしておく。 Ctrl+Alt+M(Windowsの場合)でコミット画面が開くので、全ファイルにチェックを入れ、「initial commit」のような適当なメッセージを入れてCommitを押す。

1.4.2 remoteを設定

ついでに、GitHubにレポジトリを作ってremoteに設定しておこう。 まずは同名のレポジトリを作成する。 この際、Initialize this repository with a READMEAdd a licenseは指定せず空のレポジトリにすること。 すでにファイルがコミットされた状態だと、今手元にあるものとコンフリクトが生じてしまう。

空のレポジトリをつくると、以下のようにremoteを加えるよう指示が出ているのでこれをそのままTerminalにコピペする(pushはまだしなくてもいい)。

1.5 DESCRIPTIONを修正

usethisパッケージも万能ではない。手作業でやらないといけない作業もいくつかある。 (後回しでいいが、TitleフィールドやDescriptionフィールドを適切に埋めるのも忘れずに)

1.5.1 Version

デフォルトのDESCRIPTIONだとVersionフィールドは以下のようになっている。

Version: 0.1.0

ここは好みだが、開発し始めたこのパッケージはまだ0.0.1にも達していない、という気分なら0.0.0.9000にしておく。

Version: 0.0.0.9000

1.5.2 Authors@R

デフォルトのDESCRIPTIONだとAuthorフィールドとMaintainerフィールドは以下のようになっている。

Author: Who wrote it
Maintainer: The package maintainer <yourself@somewhere.net>

ここも好みだが、まとめてAuthors@Rフィールドにした方がナウい気がするのでそうする。

Authors@R: person("Hiroaki", "Yutani", role = c("aut", "cre"), email = "yutani@example.com")

1.6 usethisパッケージで必要な設定を追加

ここから先はusethisにまとまっているのでそれを活用する。

1.6.1 ライセンス

ライセンスを追加するには、MITライセンスならuse_mit_license()を実行すればいい。 DESCRIPTIONLicenseフィールドを書き換え、LICENSELICENSE.mdを追加し、.Rbuildignoreに加えてくれる。

usethis::use_mit_license("Hiroaki Yutani")

他にも、use_gpl3_license()(GPLv3)、use_apl2_license()(Apache License 2.0)が用意されている。 データのみのパッケージの場合はuse_cc0_license()(CC0)がいいらしい。

ちなみに、引数に名前を指定するのはusethis.full_nameというオプションが設定されていれば省略できる。 .Rprofileに以下を書き加えておくのもいいだろう。.Rprofileusethis::edit_r_profile()で開くのが早い。

options(usethis.full_name = "My name")

1.6.2 Roxygen + Markdown

RoxygenにはMarkdown記法2を使うことができる。Markdown記法には落とし穴も多いが、手軽に書けるので便利ではある。 Markdown記法を有効にするにはuse_roxygen_md()を使う。といってもこの関数は特に何もせず、roxygen2md::roxygen2md()を実行するように促すだけのようだ。

usethis::use_roxygen_md()

1.6.3 README.Rmd

READMEを追加するにはuse_readme_rmd()を使う。もしくは、R MarkdownファイルではなくMarkdownファイルにしたい場合はuse_readme_md()もある。

usethis::use_readme_rmd()

ところで、このREADME.Rmdをさっそくコミットしようとすると以下のようなエラーメッセージを見ることだろう。

README.md is out of date; please re-knit README.Rmd
use 'git commit --no-verify' to override this check

これは、「Rmdとmdのどちらかに更新がある場合もう片方も更新されなければいけない」というpre-commit hookも同時に追加されているからだ。 use_readme_rmd()README.RmdだけでREADME.mdは追加してくれない。ひとまず自分でknitしよう。

このhookは、knitし忘れを防ぐという意味では役に立つが、例えば、README.Rmdには変化がないがknitしなおしたら出力が変わる、というような場合もコミットできなくなる(RStudioのGUIからは--no-verifyでコミットすることができない)。 面倒に感じるなら.git/hooks/pre-commitを削除しておいてもいい。

1.6.4 testthat

おそらくテストにはtestthatパッケージを使うだろう。use_testthat()を実行しておこう。tests/testthatディレクトリを掘ったり、Suggestsにtestthatパッケージを追加してくれたりする。

usethis::use_testthat()

紛らわしいが、テストケースを追加するにはuse_test("テストファイル名")を使う。

usethis::use_test("util")

1.6.5 CI

Travis CIはuse_travis()、AppVeyorはuse_appveyor()で設定できる。

usethis::use_travis()
usethis::use_appveyor()

具体的には、設定ファイル(.travis.ymlappveyor.yml)を追加し、各CIのウェブページを表示してくれる。バッジは勝手には追加してくれないので、以下のように表示されるコードを自分でREADMEにコピペしよう(READMEのknitし直しも忘れずに)。

Copying code to clipboard:
  [![Travis build status](https://travis-ci.org/yutannihilation/roygbiv.svg?branch=master)](https://travis-ci.org/yutannihilation/roygbiv)
Copying code to clipboard:
  [![AppVeyor build status](https://ci.appveyor.com/api/projects/status/github/yutannihilation/roygbiv?branch=master&svg=true)](https://ci.appveyor.com/project/yutannihilation/roygbiv)

1.6.6 NEWS.md

まだリリースもしていないのにちょっと気が早いかもしれないが、NEWS.mdを追加するにはuse_news_md()を使う。

usethis::use_news_md()