【devtools】 LINE Notify する R パッケージを作った

LINE Notify を使って R から LINE にメッセージや ggplot object を送信する {lineNotify} パッケージを作りました。

動機は 2018 年は R パッケージ開発に入門したいと思っていて最初に思いついたのが Slack への通知でしたが既に {slackr} パッケージがありましたので LINE Notify にしました。

LINE Notify

LINE Notify は様々な Web サービスからの通知を LINE で受信することが出来るサービスです。パーソナルアクセストークンを利用することで Web サービスの登録をせずに通知を設定することができます。

パーソナルアクセストークンの発行方法は以下です。

  1. LINE Notify にログインしマイページに移動
  2. マイページ下部の「トークンを発行する」ボタンをクリック
  3. 通知設定 (トークン名, トークルーム) を行い「発行する」ボタンをクリック

発行が完了すると連携中サービスに追加されます。

発行されたパーソナルアクセストークンを使いAPIエンドポイントに HTTP POST リクエストを投げるだけでメッセージを送信できます。

lineNotify

{lineNotify} パッケージは LINE Notify を使って R から LINE にメッセージや ggplot object を送信できます。Stan によるベイズ統計モデリングなど時間のかかる処理を回している間に外出し, 外出先でスマホやタブレットから結果を確認というような利用シーンを想定しています。

現在, devtools でインストールできます。

devtools::install_github("fisproject/lineNotify")

準備としてパーソナルアクセストークンは環境変数に設定します。または, 各関数の token 引数に直接指定しますがデフォルトでは Sys.setenv() で設定された環境変数を参照します。

library(lineNotify)

Sys.setenv(LINE_API_TOKEN="Your-Personal-Access-Token")

notify_msg() はメッセージを送信します。

# send a message
notify_msg("hello world")

notify_plot() は現在描画されているプロットをメッセージ付きで送信します。

# send a image
plot(iris)
notify_plot("Plotting the Iris")

notify_ggplot() は ggplot object をメッセージ付きで送信します。デフォルトは最後に生成したプロット (ggplot2::last_plot) です。

# send a ggplot object
library(ggplot2)
data(iris)
p <- ggplot(iris, aes(x = Sepal.Width, y = Sepal.Length)) +
 geom_point()
notify_ggplot("Plotting the Iris", plot = p)

上記を実行すると以下のように LINE に通知がきます。

{lineNotify} の中身はほぼ HTTP POST リクエストを組み立てて送信しているだけですが, 今回は機能の実装以上に {devtools} を使ったパッケージ開発フローが勉強になったので以下にメモを残しておきます。

devtools

{devtools} は一般的な開発タスクを自動化できる便利なパッケージです。

devtools::create

devtools::create(“.”) を実行するとパッケージのテンプレートが作成されます。

$ tree -a
.
├── .Rbuildignore
├── .gitignore
├── DESCRIPTION
├── NAMESPACE
├── R
└── example.Rproj

1 directory, 5 files

パッケージのメタデータは DESCRIPTION に記述します。

  • Package: パッケージ名
  • Title: パッケージの簡潔な説明 (1行)
  • Version: パッケージのバージョン (major.minor.patch.dev)
  • Authors@R: 開発者の情報
  • Description: パッケージの説明 (1パラグラフ)
  • Depends: 利用可能な R バージョン
  • License: ライセンス (e.g. MIT, GPL-2.0)
  • Imports: 依存パッケージ
  • Suggests: 動作には影響しない使用パッケージ

R ディレクトリ以下に機能を実装しますが, なるべくグローバル環境への影響は少なくし, 特に開発中のパッケージ内では library() や require() を使ってはいけません。

devtools::document

devtools::document() を実行すると {roxygen2} の roxygenize() が呼ばれ, コード内のコメント部分からオブジェクトのドキュメント (man/*.Rd) を自動生成します。

devtools::load_all

インストールされているパッケージは library() や require() でロードしますが, 開発中のパッケージは devtools::load_all() でロードします。

devtools::run_examples

devtools::run_examples() で各関数の @examples が実行されます。 実行環境の差異がある場合などエラーが発生する可能性のあるコードは \dontrun{} 内に記述します。

devtools::use_testthat

devtools::use_testthat() を実行すると {testthat} による単体テストのエントリ ./tests/testthat.R が作られます。./tests/testthat/ 以下にテストコードを書き, devtools:: test() を実行するとテストが実行されます。

> devtools::test()
Loading lineNotify
Testing lineNotify
✔ | OK F W S | Context
✔ |  5       | notify_ggplot.R

══ Results ═════════════════════════════════════════════════════════════════
OK:       5
Failed:   0
Warnings: 0
Skipped:  0

devtools::check

devtools::check() は依存パッケージ, ドキュメント, テストの実行など様々なチェックを行います。最後に出力される error と warning が 0 であることを確認してから git commit を実行するのが良いと思います。

> devtools::check()
Updating lineNotify documentation
Loading lineNotify

...

* checking tests ...
  Running ‘testthat.R’
 OK
* DONE

Status: OK

R CMD check results
0 errors | 0 warnings | 0 notes

devtools::build

devtools::build() でバンドルパッケージ (.tar.gz) が作成されます。 (devtools::release() で CRAN に投稿)

おわりに

参考書籍は『Rパッケージ開発入門』(原著者: Hadley Wickham 氏) です。


[1] Google’s R Style Guide
[2] こわくないRパッケージ開発!2016
[3] Writing an R package from scratch
[4] How to save a plot as image on the disk?