以前、こわくないRパッケージ開発!2016 - Qiita という記事で、こんなことを書きました。
次のような場合、分析タスクの運用や共有を楽にするため、Rのコードをパッケージ化しましょう。
- その場限りの分析用ではなく、同じコードを今後も使用する見込があること
- 同じコードを複数人が利用すること
そこでは充分に紹介しきれなかった、R言語でコードリンターを利用する方法について書いていきます。
これは株式会社ネクスト(Lifull) Advent Calendar 2016 の20日目の記事です。
「コードを私物化しない」ことによるメリット
自己紹介が遅れましたが、@wakuteka といいます。株式会社ネクスト(Lifull)では、@ninomiyt くんと同じ部署で、主にR言語を使って集計や前処理や分析を行っています。今年で、ようやく入社2年目になりました。
今ではあたりまえに思うようになったのですが、会社に入って驚いたことの1つは、「コードの体裁に関するコーディング規約があり、それに従っていない箇所はコードレビューで指摘される」ということでした。
大学の研究室でプログラムを書いていた頃はコードを人に読んでもらうという習慣や文化がなかったこともあり、コーディング規約というものについて、なんて堅苦しくて不自由なんだろう、と以前は感じていました。
けれど、業務を通じて、むしろ逆なんだなと今では思うようになりました。コーディング規約によって体裁が統一されて「他人に読みやすく」なったコードは、本質的な処理の理解に集中できるという利点があるだけでなく、コードの引き継ぎやメンテナンス・自分が不在のときの改修などを同僚に頼む際のハードルを下げてくれるのです!
とはいえ、そうしたコーディングの規約を漏らさず覚えているのは大変すぎます。そのために、コードリンターと呼ばれるしくみがあります。要はテキストの体裁が一定の基準に合っているかチェックできるツールです。開発の現場では、このようなツールを使って体裁のチェックは自動化されることが多いです。
こうした習慣やツールの利点などについて興味を持たれた方は、97 Things Every Programmer should know(邦題:「プログラマが知るべき97のこと」)という書籍に、
といった項目があるので、ぜひ読んでみてください。
Rでどうやるか
{lintr}
というパッケージがあります。「りんとあーる」「りんたー」どちらでもいいですが、個人的には後者で呼んでいます。
ここでは、説明のために、6月に私が書いたコードを血祭りに上げることにします。
https://github.com/wakuteka/exampler を zipで落としてきて解凍するか、cloneしてRStudioなどで開いてください。
次に、{lintr}
パッケージをインストールして、
> lintr::lint_package()
を実行しましょう。Rでパッケージ開発をする際は、絶えずこのコマンドを実行すると良いと思います。Travis CIと連携したりRStudio 1.0から導入されたAddin機能を使うことで、ショートカットを割り振るなどもおすすめです。
さて、このコマンドをさきほどの{wakuteka/exampler}
パッケージのディレクトリ直下で実行すると、
図のように、Consoleの位置にMarkersタブが現れ、コードの修正候補が表示されます。
Markersタブに表示されたそれらの修正候補の中からひとつを選択すると、対応するコードの「修正すべき」箇所に文字入力カーソルが移動します。べんり。
これらの中で、
- 二項演算子の周りにはスペースを置く
- カンマの後にはスペースを置く
という指摘に従って修正してそれぞれのソースを保存した後、再度lintr::lint_package()
を実行してみましょう。
Markersタブの指摘項目が、無事減っています!
こうしたチェック項目、コーディング規約はHadley WickhamのRコーディングスタイルガイドに則っており、人によってはそれらのなかで運用に合わない、好みに合わないものがあるでしょう。「一行をいまどき80文字に収めないといけないなんて!」みたいなやつです。
そういった場合は、パッケージごとに.lintr
ファイルを用意することで、lintrの規約のいくつかをカスタマイズしたり、選択して無効化したりすることができます。
上の例であれば、たとえば
- 二項演算子の周りにはスペースを置く
- カンマの後にはスペースを置く
というルールに従った後で、「一行が80文字に収まってない」というルールを無視したいとします。
さきほどの画面になった後で、
https://github.com/jimhester/lintr のREADMEにあるように、以下のコードを実行してみましょう。
library(magrittr)
library(dplyr)
lintr::lint_package() %>%
as.data.frame %>%
group_by(linter) %>%
tally(sort = TRUE) %$%
sprintf("linters: with_defaults(\n %s\n NULL\n )\n",
paste0(linter, " = NULL, # ", n, collapse="\n ")) %>%
cat(file = ".lintr")
すると、パッケージのディレクトリ直下に、.lintr
というファイルができています。
> dir(all.files = TRUE)
[1] "." ".." ".git" ".gitignore"
[5] ".lintr" ".Rbuildignore" ".Rproj.user" "DESCRIPTION"
[9] "exampler.Rproj" "LICENSE" "man" "NAMESPACE"
[13] "R" "README.md"
いま作った.lintr
ファイルの中身は以下のようになっています。これで、一行の長さに関するリンターの項目を無効化できているわけです。
linters: with_defaults(
line_length_linter = NULL, # 1
NULL
)
念のためlintr::lint_package()
を再度実行してみると、
無事、無効化が効いていることがわかります!
さらに知りたい方は、help("linters")
や、Creating new lintersを読んでみてください。
コードリンターを使うことでプログラミングスキルや分析スキルが上がるわけではありませんが、「本質的な作業に集中する」という目的には、きっとプラスに働いてくれるでしょう。
##おまけ
[Rのコーディングルールについて]
(http://rstudio-pubs-static.s3.amazonaws.com/85463_ab84b5964c4c4c129d8601dc495b4e51.html) @yamano357 さんによるコーディングルールまとめです。2015年の記事ですが、こちらもご一読を。
Enjoy!
あしたは @shimada-k さんです!