この記事はR Advent Calendar 2016DATUM STUDIO Advent Calendar 2016の20日目の記事です。

私と里傭兵

私と里傭兵の出会いは3年ほど前のTokyo.Rである。
Tokyo.Rに参加している内にそこそこ親しくなった後、前職時代に僅かな期間であるが一緒に仕事をすることになった。
その縁からか、誘いの声を度々もらうようになり紆余曲折を経てDATUM STUDIOに転職した。
自分をハンティングしてくれる人なんて後にも先にも里傭兵ぐらいだと思う。
おかげさまで楽しく愉快に働けていると思う。感謝。


里傭兵といえば

ビールである。
感謝の気持ちを込めてビールを飲みに誘いたい。


渋谷のビアバーをRで可視化

require(dplyr)
require(tidyr)
require(purrr)
require(stringr)
require(httr)
require(DT)
require(xml2)
require(rvest)
require(leaflet)

ビアバーの情報を取得

とあるグルメなサイトを{rvest}を使ってクローリング&スクレイピングしました。
雑なコードで取得したのでコードは割愛。
{rvest}の使い方はこちらを参照すると良い。
とあるグルメなサイトにはビアバーが32件あるらしい。

位置情報を取得

GoogleMapsAPIを利用してジオコーディングを実行。
ビアバーの緯度経度を取得する。
ジオコーディングするにあたって建物名や階数をふくまないでとのことなので、{stringr}を使って余分な文字列を除外。
{stringr}はRの文字列操作においてmustなので是非使いこなしたいところである。
こちらこちらの資料が非常に参考になる。
GoogleMapsAPIを叩くには{httr}を利用した。

# APIキーを取得
API_KEY_GEOCODING <- "xxxxxxxxxxxxxxxxxxxxxxxxxx"

getLatlng <- function(address) {
  raw_json <- httr::GET(
    str_c(
      "https://maps.googleapis.com/maps/api/geocode/json?language=jp&address=",
      str_split(address, pattern = " | ")[[1]][1],
      "&key=", API_KEY_GEOCODING,
      sep = ""
    )
  )
  Sys.sleep(5)
  json_content <- httr::content(raw_json)
  lat <- json_content$results[[1]]$geometry$viewport$southwest$lat
  lng <- json_content$results[[1]]$geometry$viewport$southwest$lng
  return(c(lat, lng))
}

# 実行
shop_latlng_list <- map(.x = shop_info[["address"]], .f = getLatlng)
shop_latlng_dat <- map_df(.x = shop_latlng_list,
                          .f = function(x) data.frame(lat = x[1], lng = x[2]))
shop_info <- cbind(shop_info, shop_latlng_dat)
  • 実行結果
shop_info %>% 
  select(name, address, lat, lng) %>% 
  datatable(.)

時間距離を計算する

情報を取得したビアバーは積極的に活用していきたい。
活用するためにあたって重要な要素は近さにある。
DATUM STUDIOからの徒歩時間をDistance Matrix APIを使って取得する。
こちらも{httr}を使用している。

# APIキーを取得
API_KEY_MAPSDISTANCE <- "xxxxxxxxxxxxxxxxxxxxxxxxxx"

# DATUM STUDIO
DATUM_ADDRESS <- "東京都渋谷区桜丘町2-9 第1カスヤビル1C"
datum_latlng <- getLatlng2(DATUM_ADDRESS)

# 距離計算用に緯度・経度を整形
reshapeLatlng <- function(latlng) str_c(latlng[1], latlng[2], sep = ",")

# 距離計算APIより計算
calcDistance <- function(shop_latlng) {
  raw_json <- httr::GET(
    str_c(
      "https://maps.googleapis.com/maps/api/distancematrix/json?origins=",
      datum_latlng_concat,
      "&destinations=", shop_latlng,
      "&mode=walking&language=ja&key=", API_KEY_MAPSDISTANCE,
      sep = ""
    )
  )
  Sys.sleep(3)
  print(shop_latlng)
  json_content <- httr::content(raw_json)
  walking_time <- json_content$rows[[1]]$elements[[1]]$duration$value
  return(walking_time)
}

# 実行
datum_latlng_concat <- reshapeLatlng(datum_latlng)
shop_latlng_dat_concat <- shop_latlng_dat %>% 
  tidyr::unite(latlng, lat, lng, sep = ",", remove = FALSE) %>% 
  .[["latlng"]]
shop_walkintime_list <- map(.x = shop_latlng_dat_concat, .f = calcDistance)

shop_info["time_distance"] <- unlist(shop_walkintime_list)
  • 実行結果
    • 徒歩時間(単位は秒を追加)

地図へプロット

ここまで取得したデータをOpenStreetMapにプロットする。
プロットには{leaflet}を使用する。
{leaflet}の使い方はこちらのサイトがためになります。

# ビールアイコンを用意
beerIcon <- makeIcon(
  iconUrl = "beer_icon.png",
  iconWidth = 25, iconHeight = 25
)

# プロット用のデータを整形
plot_dat <- shop_info %>% 
  mutate(
    minute = round(time_distance / 60, digits = 0),
    popup = sprintf('<a href="%s">%s</a><br><p>DATUM STUDIOから徒歩%s分</p>', url, name, minute)
  )

# map plot
m <- leaflet(plot_dat) %>% 
  addMarkers(
    lat = ~lat, lng = ~lng, icon = beerIcon,
    popup = ~popup
  ) %>% 
  addProviderTiles("Stamen.Toner")
  • 実行結果

まとめ

これで渋谷のビアバーのプロットができました。
このマップを使って里傭兵とうまいビールを飲みにいきましょう。
enjoy!

R Advent Calendarの21日は@data_sciesotistさん
DATUM STUDIO Advent Calendarの21日目は@t_nishiyamaです