💮Moves + Rで行う行動データの可視化
私の趣味の一つにお気に入りユーザーのネットストーキングがあります。ネットストーキングをしている、というのを公言するとウケが良くないことは経験上明らかなので、ひとまず自分をストーキングしてみたい(というのを今年の目標の一つにしています)。今回は、Movesというスマートフォン向けの行動記録アプリケーションのウェブAPIを利用した自分ストーキングをRを使ってやってみたいと思います。
❓ Movesとは
Activity Diary of Your Life
をキャッチコピーとしていているように、一度ユーザー登録、ログの開始をしておくと自動的に自分の行動を記録してくれるアプリケーションでAndroidおよびiPhoneで利用可能となっています(参考: 【Android】完全自動行動記録アプリ「Moves」が待望のリリース!さっそく使ってみた)。
MovesではウェブAPIが提供されていて、第三者が開発したアプリも充実しているのですが、R用のパッケージが見つかりません(Pythonはあるのに...)。APIさえ利用できるなら、Rでもあれこれできるはずだ、といういつもの気持ちでやってみましょう。また、APIを使わずとも自分のデータは取得できるのでそちらも使ってみたいと思います。
🚶 Moves APIを利用する
準備
いくつかの作業が必要です。流れとしては
- Movesで新しいアプリケーションを作成し、Client IDとClient secretを取得
ブラウザで "https://api.moves-app.com/oauth/v1/authorize?response_type=code&client_id=
&scope=location%20activity" にアクセス httr::POST()
でアクセストークンを取得
という感じになります。これらは一度実行しておけば、アクセストークンの有効期間が過ぎるまではやる必要がなくなります。リフレッシュトークンも取得できるのでそれをメモしておいて、期限が近づいてきたら再度アクセストークンを有効にするのが良いのではないでしょうか。
まずはAPIを叩くために{httr}
パッケージを読み込みます。
library(httr)
作成したアプリケーション固有のClient IDとClient secretを用意しておきましょう。
ci <- "<Client ID>" cs <- "<Client secret>"
ブラウザで "https://api.moves-app.com/oauth/v1/authorize?response_type=code&client_id=g2XylBJ2IHmkN64cfCvyGt5oCgy8p6Qb&scope=location%20activity" にアクセスします。
BROWSE(paste0("https://api.moves-app.com/oauth/v1/authorize?response_type=code&client_id=", ci, "&scope=location%20activity"))
ac <- "<authorizationcode>" get.token <- POST("https://api.moves-app.com/oauth/v1/access_token?", body = list(grant_type = "authorization_code", code = ac, client_id = ci, client_secret = cs), encode = "form") %>% content() access.token <- get.token$access_token
Moves APIの利用には、リクエストヘッダーかリクエストURLにアクセストークンを含める必要があるので、ヘッダーにアクセストークンの値を渡しておく。
http.header <- add_headers(Authorization = paste("Bearer", access.token))
APIの操作
再度必要なパッケージを読み込んでおく。
library(purrr) library(ggplot2) library(formattable)
Moves APIでは取得対象のデータに対してエンドポイントが与えられているので、いくつかのエンドポイントを叩いてみます。まずはユーザー情報から。
# Profile # ユーザーを特定できそうな一部の結果を改変している GET("https://api.moves-app.com/api/1.1/user/profile", config = http.header) %>% content()
## $userId
## [1] XXXXXXXXXXXXXXX
##
## $profile
## $profile$firstDate
## [1] "XXXXXXXX"
##
## $profile$currentTimeZone
## $profile$currentTimeZone$id
## [1] "Asia/Tokyo"
##
## $profile$currentTimeZone$offset
## [1] 32400
##
##
## $profile$localization
## $profile$localization$language
## [1] "ja-JP"
##
## $profile$localization$locale
## [1] "ja_JP"
##
## $profile$localization$firstWeekDay
## [1] 1
##
## $profile$localization$metric
## [1] FALSE
##
##
## $profile$caloriesAvailable
## [1] TRUE
##
## $profile$platform
## [1] "ios"
ある特定の日の記録を取得して、Movesが定める運動(移動手段を含める)の種類に応じた時間を図にしてみます。こういうこと簡単にできるのはRの強みではないでしょうか。
# Summaries summary.sigle.date <- GET("https://api.moves-app.com/api/1.1/user/summary/daily/20160212", config = http.header) %>% content() summary.sigle.date[[1]]$summary %>% map_df(~.[c("group", "duration")]) %>% ggplot(., aes(group, duration, fill = group)) + geom_bar(stat = "identity")
# Summaries その2 # pastDaysパラメータの指定により31日前まで遡れるが、記録が少ないので7日間にする summary.past.date <- GET("https://api.moves-app.com/api/1.1/user/summary/daily?pastDays=7", config = http.header) %>% content() df.group.summary <- summary.past.date %>% at_depth(1, map_if, is_list, map_df, ~.[c("group", "duration", "distance")]) %>% map(c("summary")) %>% dplyr::bind_rows() df.group.summary %>% dplyr::filter(group == "walking") %>% dplyr::add_rownames(var = "Day") %>% dplyr::select(-group) %>% dplyr::rename(`duration (sec.)` = duration, `distance (m)` = distance) %>% formattable(list(`duration (sec.)` = color_bar("tomato"), `distance (m)` = color_tile("white", "olivedrab")))
Day | duration (sec.) | distance (m) |
---|---|---|
1 | 16069 | 18576 |
2 | 212 | 235 |
3 | 3703 | 3951 |
4 | 824 | 915 |
🌏 Leaflet上へのマッピング
{leaflet}
パッケージを使えば、地図上へのマッピングも簡単です。APIデータの加工が結構面倒だったので、ここはダウンロードしてきたデータを使うことにしました(今後の課題)。
library(leaflet) geojson <- readLines("~/Downloads/moves_export/geojson/daily/storyline/storyline_yyyyyMMdd.geojson", warn = FALSE) %>% paste(collapse = "\n") leaflet() %>% addTiles() %>% setView(lng = 139.53, lat = 35.6, zoom = 10) %>% addGeoJSON(geojson, fill = FALSE)
📚 参考
💻 実行環境
package | version | source |
---|---|---|
formattable | 0.1.5 | CRAN (R 3.2.2) |
ggplot2 | 2.0.0 | CRAN (R 3.2.3) |
httr | 1.1.0.9000 | Github (hadley/httr@7261a52) |
leaflet | 1.0.0 | CRAN (R 3.2.0) |
magrittr | 1.5 | Github (smbache/magrittr@00a1fe3) |
purrr | 0.2.1 | CRAN (R 3.2.3) |
remoji | 0.1.0 | Github (richfitz/remoji@dc00779) |
🍵 所感
- 自分ストーキングでも十分に楽しめたので、ストーキング癖のある皆様におかれましてもMovesアプリによる行動の記録とRによる可視化を行ってみることをお勧めです
- 各種のエンドポイントデータを統合したstorylineからうまくデータを整形すれば、API経由でleafletへの可視化ができるはずなのだけど、前処理の壁が厚かったのでここは課題