cucumber flesh

Rを中心としたデータ分析・統計解析らへんの話題をしていくだけ

💮Rで通知

Rに管理されたい。」...そういう願望が人類共通、誰しもにあると思う。

Rじゃなくてもできるはずだけど、Rに管理されたい願望が強いので、Rに管理してほしい。

コードの実行完了を通知する

ちょっと調べた限りで以下の記事が見つかった。

Rから通知をとばす from TokorosawaYoshio

これらは特定のコードが実行した後に通知してくれるというもの。メールやらYoやら、手段はいろいろとある。ただ、メールは正直ダサいし、Yoも今では使っていない。もっとシンプルに通知してくれるものが欲しい。

更に探してみたらgistでキャプテンがすでに書いていた。惚れる。やっぱりこの人についていきたい。

Send OS X notifications from R (RStudio, R GUI or R console) · GitHub

これはMacのターミナル上で動作するterminal-notifierを利用して、コードの実行完了を通知センターに表示させるというもの。処理のあとにnotify()を実行すれば、通知センターにその旨が表示される。

なお環境によって動作しないことがあるのでちょっと書き直した(terminal-notifierのパスが異なるため)。

terminal-notifierがインストールされているMacなら、次のコードで動作確認ができる。

f:id:u_ribo:20150922120517g:plain

library(devtools) # install.packages("devtools")
source_gist("9c419af5547fde20d2a7")
system("sleep 2")
notify("Long op complete")

処理の長いコードを実行したときにはこれを使うと良さそうだ。実行しているアプリに応じてアイコンが変化するのがおしゃれ!

LaunchAgentsでRコードを自動処理する

さきのものはあくまでも自分が関数を実行しないと通知してくれないので、満足できない。もっと管理されたい。というわけで特定の時間になったら自動的にコードを実行して通知するという仕組みを考えてみた。

Unix系のOSで自動実行するコマンドとしてcronがあるが、MacではLaunchAgents使うべし、なる知見を得たので、そちらで書くことにした。

まずは、実行したいするRコードを作成する。

system(paste("/usr/local/bin/terminal-notifier", "-title R -message 時間になりました -subtitle", format(Sys.time(), "%X"), "-sender org.R-project.R -sound default", sep = " "))

ついでplistファイルを書き、/Users/<USER>/Library/LaunchAgents/なりに置いておく(保存するディレクトリに応じて挙動が異なるので注意)。起動する時間、間隔なども設定できる。

参考) launchd.plistの書き方 | Drowsy Dog's Diary

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>test-time-notice</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/bin/R</string>
        <string>-e</string>
        <string>source("/Users/<USER>/notify.R")</string>
    </array>
    <key>StartCalendarInterval</key>
    <dict>
        <key>Hour</key>
        <integer>10</integer>
        <key>Minute</key>
        <integer>13</integer>
    </dict>
    <key>StartInterval</key>
    <integer>360</integer>
</dict>
</plist>

つぎのコマンドで読み込むと、10時13分にRコードが実行される。

launchctrl load `/Users/<USER>/Library/LaunchAgents/test-time-notice.plist`

f:id:u_ribo:20150922112957p:plain

終電を逃さないようにだとか、お昼になったとか、1時間経ったから休憩するようにとか、条件に応じてRに管理されるようにしたい。

Enjoy!