cucumber flesh

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

💮住所から緯度と経度を取得したい: 札幌市の保育所データを例にして

今北海道が熱い!(昨日、今年の初雪を観測したらしいが)

北海道関連の記事をよく見かける。例えば、

wafdata.hatenablog.com

ん? 「道内認可保育所」??

オープンデータが公開されると、Rで解析したくなってくる。茶飯インシデントである。北海道の保育施設の情報は結構多くて、こういうプロジェクトもある。

「さっぽろ保育園マップ」できました! | Code for Sapporo

github.com

今回公開された「道内認可保育所」のデータでは、住所はあるが、緯度経度といった座標情報がない。座標がないと地図にプロットできない。というわけで、すでに完成品があるが、今回新たに公開された「道内認可保育所」のデータを引き出しにして、住所から緯度と経度を求めるということをやってみたい。

使用するパッケージは次のものたち。

library(readxl)
library(readr)
library(dplyr)

オープンデータの中身を確認

# ファイルへの直接リンクではなく、ダウンロード先のURLが載っていて、
# ちっ、とか思いながらも手作業でダウンロードしてくる
path <- "/Users/uri/Downloads"
excel_sheets(paste(path, "hoikusyo.itiran.xls", sep = "/"))
## [1] "札幌市" "旭川市" "函館市" "北海道"
df_spr <- data_frame()
read_excel(path      = paste(path, "hoikusyo.itiran.xls", sep = "/"),
           sheet     = 1, 
           skip      = 4,
           col_names = c("no", "地域区分", "設置者区分", "運営者区分",
                      "主体名", "施設名", "郵便", "住所",
                      "電話", "利用定員2号", "利用定員3号",
                      "代表者", "許可年月日"),
           col_types = c("numeric", "text", "text", "text",
                         "text", "text", "text", "text",
                         "text", "numeric", "numeric",
                         "text", "text")) %>% 
  {
    df_spr <<- .
    print(class(.))
    glimpse(.)
  }
## [1] "tbl_df"     "tbl"        "data.frame"
## Observations: 250
## Variables: 13
## $ no          (dbl) 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,...
## $ 地域区分    (chr) "札幌(中)", "札幌(中)", "札幌(中)", "札幌(中)", "札幌(中)", "札幌(中)", ...
## $ 設置者区分  (chr) "市", "市", "市", "財団", "社福", "社福", "社福", "社福", "社福", "社福"...
## $ 運営者区分  (chr) "市", "社福", "社福", "財団", "社福", "社福", "社福", "社福", "社福", "社...
## $ 主体名      (chr) NA, "ろうふく会", "救世軍社会事業団", "鉄道弘済会", "北海道社会事業協会", "救世軍社会...
## $ 施設名      (chr) "札幌市あけぼの保育園", "札幌市大通夜間保育園", "札幌市しせいかん保育園", "鉄道弘済会札幌保育...
## $ 郵便        (chr) "064-0811", "060-0041", "060-0063", "060-0051", "060...
## $ 住所        (chr) "札幌市中央区南11条西10丁目1番3号", "札幌市中央区大通東4丁目5番地1  ", "札幌市中央区...
## $ 電話        (chr) "011-511-0447", "011-222-6112", "011-204-9560", "011...
## $ 利用定員2号 (dbl) 68, 36, 65, 33, 51, 48, 36, 45, 105, 51, 90, 0, 48, 55,...
## $ 利用定員3号 (dbl) 22, 24, 55, 27, 39, 42, 24, 45, 45, 39, 60, 30, 42, 35,...
## $ 代表者      (chr) "嶺 幸子", "中川 京子", "安達 津恵子", "斎藤 利幸", "磯田 憲和", "岩橋 由", ...
## $ 許可年月日  (chr) "昭35.3.1", "昭62.1.1", "平16.4.1", "昭27.11.1", "昭30.4.1",...

今回は「札幌市中央区」にある1か所だけを対象にしたい(選択の理由に意図はない。全てはset.seed(71)の意思のままに...)。また、余分な列は削除しておくために次のコードを実行する。

# 号がついていたりいなかったりする...
set.seed(71)
df_spr %<>% dplyr::filter(地域区分 == "札幌(中)") %>% 
  dplyr::mutate(., 住所 = gsub("札幌市中央区", "", 住所)) %>% 
  dplyr::select(施設名, 住所) %>% 
  slice(., purrr::rdunif(1, nrow(.) ,1))
df_spr
## Source: local data frame [1 x 2]
## 
##             施設名                 住所
##              (chr)                (chr)
## 1 救世軍桑園保育所 北5条西14丁目1番地29

位置参照情報の用意

というわけでこちらの保育施設を例に、住所から緯度経度を求めてみたい。住所から緯度経度を求めるために、国土交通省 位置参照情報ダウンロードサービスを利用する。

#  国土交通省 位置参照情報ダウンロードサービスから中央区のデータを取得
df_geo <- data_frame()
readr::read_csv(file   = paste(path, "01101-12.0a/01101_2013.csv", sep = "/"),
                locale = locale(encoding = "cp932")) %>% 
  {
    print(class(.))
    df_geo <<- . # df_geoというオブジェクトに代入
    sample_n(., 3) # 幾つかを表示
  }
## [1] "tbl_df"     "tbl"        "data.frame"

## Source: local data frame [3 x 13]
## 
##   都道府県名   市区町村名     大字・町丁目名 街区符号・地番 座標系番号
##        (chr)        (chr)              (chr)          (int)      (int)
## 1     北海道 札幌市中央区     南四条東三丁目              7         12
## 2     北海道 札幌市中央区     南八条西九丁目            775         12
## 3     北海道 札幌市中央区 南十三条西十三丁目              2         12
##      X座標   Y座標     緯度
##       (dbl)    (dbl)    (dbl)
## 1 -104345.7 -72394.7 43.05728
## 2 -105267.2 -73728.0 43.04885
## 3 -106033.1 -74230.8 43.04191
## Variables not shown: 経度 (dbl), 住居表示フラグ (int), 代表フラグ (int),
##   更新前履歴フラグ (int), 更新後履歴フラグ (int)

保育所のデータと同じく、必要な部分だけを抽出しておく。

df_geo %<>% dplyr::filter(市区町村名 == "札幌市中央区") %>% 
  dplyr::select(`大字・町丁目名`, `街区符号・地番`, 緯度, 経度)

住所から緯度と経度を取得

というわけで最後の処理。位置参照情報ダウンロードサービスでの大字・町丁目名や街区符号・地番では漢数字が適用されているので、保育所データと合わせるためにアラビア数字に変更しておく。また、該当する位置参照情報が複数あった(保育所データに合わせるため)ので、平均値を代表値として採用した。

df_geo %<>% dplyr::filter(grepl("^北五条西十四丁目", `大字・町丁目名`) 
                          & grepl("1", `街区符号・地番`)) %>% 
  dplyr::mutate(`大字・町丁目名` =  gsub("五", "5", `大字・町丁目名`),
                `大字・町丁目名` =  gsub("十四", "14", `大字・町丁目名`),
                住所 = paste0(`大字・町丁目名`, `街区符号・地番`, "番地")) %>% 
  dplyr::group_by(住所) %>% 
  dplyr::summarise(緯度 = mean(緯度), 経度 = mean(経度)) %>% 
  dplyr::select(住所, 緯度, 経度)

保育所データと位置参照情報データの結合と結果の確認。

df_spr %<>% dplyr::filter(住所 == "北5条西14丁目1番地29") %>% 
  dplyr::mutate(住所 = gsub("[[:xdigit:]]{2}$", "", 住所)) %>% 
  inner_join(df_geo)

knitr::kable(df_spr, format = "markdown")
施設名 住所 緯度 経度
救世軍桑園保育所 北5条西14丁目1番地 43.06508 141.334

一筋縄ではいかないが、なんとかできた。

SappoRo.R

kokucheese.com

11月14日、みんなで札幌に行こう(行けない)。

利用データ・ライセンス