日本の人口密度を可視化する: population lines
少し前(4月下旬ごろ?)に、redditで人口密度の高さを表現した地図が話題になりました。
この地図は、James Cheshire博士 (@spatialanalysis)が2014年に投稿した “Population Lines Print” が元となっていて、再現性のあるRコード、ヨーロッパに焦点を当てた地図が描かれた(Henrik Lindberg @hnrklndbrg )ことで話題が広がっています(という印象。今週のR Weeklyでもいくつかの記事が掲載されました。
日本の人口密度の情報を世界地図から伺うことはできますが、スケールダウンしたものがあった方がわかりやすいです。…というわけで作成してみました。
続きを読む
日付から曜日を取得する関数と日本語表記の対応
日付から曜日を取得する関数としてlubridate::wday()
(days of the week)をよく使う。この関数は曜日を与えて実行し、デフォルトでは数値化した値(日曜日を起点 1とした1から7までの値)を返すが、label引数を有効化することで曜日のラベルが得られる。また省略形と正規の表現が選べる。
データフレームに含まれる日付の列から、曜日を求めて各曜日の集計値を求める、みたいなことをやる時などに便利だ。
library(lubridate) today() %>% wday(label = TRUE)
## [1] Tues
## Levels: Sun < Mon < Tues < Wed < Thurs < Fri < Sat
library(dplyr) d <- data_frame(date = make_date(2017, 5, 1:31)) %>% mutate(wd = wday(date))
ただ、時々、数値や英語の曜日ではなく日本語の「火曜日」、「金曜日」といったラベルを使いたい時がある。そういう場合にどうすれば良いかというのが今回の話。
結論から言うと、現在CRANに登録されているlubridateパッケージ (1.6.0)はこれに対応していない。しかしGitHubの開発版はこれに対応している (ref) #401, #508。
こんな感じで日本語の曜日も表示できるようになる。
d$date %>% wday(label = TRUE, locale = "ja_JP.UTF-8") # [1] 月 火 水 木 金 土 日 月 火 水 木 金 # 土 日 月 火 水 木 金 土 [21] 日 月 火 # 水 木 金 土 日 月 火 水 Levels: 日 < 月 # < 火 < 水 < 木 < 金 < 土
NEWSにも書かれているので次のバージョンが登録されたら機能することは間違い無いと思うが、今はforcats::fct_recode
を使う次の方法で対処している。早く出て欲しい…
library(forcats) d.mod <- d %>% mutate(wd_j = fct_recode(as.factor(wd), 日曜日 = "1", 月曜日 = "2", 火曜日 = "3", 水曜日 = "4", 木曜日 = "5", 金曜日 = "6", 土曜日 = "7")) d.mod$wd_j
## [1] 月曜日 火曜日 水曜日 木曜日 金曜日 土曜日 日曜日 月曜日 火曜日 水曜日
## [11] 木曜日 金曜日 土曜日 日曜日 月曜日 火曜日 水曜日 木曜日 金曜日 土曜日
## [21] 日曜日 月曜日 火曜日 水曜日 木曜日 金曜日 土曜日 日曜日 月曜日 火曜日
## [31] 水曜日
## Levels: 日曜日 月曜日 火曜日 水曜日 木曜日 金曜日 土曜日
20170510追記
そういえば、過去のr-wakalangにて同様のやりとりがあったことを思い出した(発見した)。Rに標準実装されるbeseパッケージ内の関数weekdays()
はデフォルトで現在利用中のロケールにあった曜日を返してくれる。こちらの方が手軽感がある。
weekdays(lubridate::today() - 0:6)
## [1] "水曜日" "火曜日" "月曜日" "日曜日" "土曜日" "金曜日" "木曜日"
注意として、文字列であるが因子にはなっていない。
Microsoft Cognitive Service Face APIにローカル上の画像を投げる
dichikaさんのMicrosoft Cognitive Serviceを使った記事、APIに投げる画像はサーバ上にある必要がある、ということだが、リクエストボディのContent-Type
でapplication/octet-stream
を指定することでローカルファイルをサーバを経由せずに直接投げることができる。
こんな感じでやる。検証用の画像として、件のGlobal Tokyo.R集合写真を使う(メガネのおじさんたちがメガネのお姉さんになってくれやしないか… ) 。Ocp-Apim-Subscription-Key
に与えるAPIキーは各自が用意したものを使うこと。
library(purrr) library(httr) # 対象の画像のパスを指定する x <- "~/Desktop/oretachino_globaltokyo_r.jpg" # 幅5000pxに引き伸ばし base.url <- "https://westus.api.cognitive.microsoft.com/face/v1.0/detect" result <- httr::POST(base.url, body = upload_file(x), query = list(returnFaceAttributes = "age,gender,headPose,smile,facialHair,glasses,emotion", language = "en"), httr::add_headers(.headers = c(`Content-Type` = "application/octet-stream", `Ocp-Apim-Subscription-Key` = <api_key>))) %>% httr::content()
先述の通り、Content-Type
の値をapplication/octet-stream
に変更するのと、
readBin()
を使ってローカルファイルをバイナリとして読み込ませる指定するという話。
ご指摘いただきました。ありがとうございます。
@u_ribo readBin(x, "raw", https://t.co/KtwoSQdNrQ(x)$size) の部分は、upload_file(x) でいけるはず。readBinだといちどメモリ上にファイルを読み込んでから送るけど、upload_fileは裏側でcurlがやってくれるので
— Hiroaki Yutani (@yutannihilation) 2017年4月5日
これらのアップロードにおいては,データはサーバにストリーミングで送信されます.データがRにチャンクとしてロードされ,リモートサーバに送られるのです.したがってメモリに収まらない大きなファイルもアップロードすることができます.
結果について確認しておくと、メガネ率は少し異なっている。画像のサイズが違うのだろうか。SwimmingGogglesつけてる人誰や…
result %>% map("faceAttributes") %>% map_chr("glasses") %>% table()
## .
## NoGlasses ReadingGlasses SwimmingGoggles
## 18 12 3
Enjoy!