お肉の検査員の統計解析日記

非エンジニアのお肉の検査員が日々の業務で発見した統計解析(主にRを使った)について情報発信します

お肉の検査員でもできる!住所データの可視化方法

どうもお肉の検査員です(6回目)。

今回は、備忘録を兼ねて住所データを簡単に緯度経度情報に変換する方法と、緯度経度データを地図上に可視化する方法について書いていきたいと思います。

 可視化するのは、滋賀県が発祥の地(本店は滋賀県野洲市にあります)である来来亭の店舗の位置にしたいと思います。というのも、先日まで来来亭のラーメンパスで、1か月間ラーメン無料で美味しく食べることが出来たため、その恩返し(?)も兼ねて、どこに店舗があるのかを示したいと思います。来来亭の無料パスについての詳細は、来来亭のホームページをご覧ください。
www.rairaitei.co.jp

データの取得

 さて、ではまず来来亭滋賀県内(令和2年2月23日時点で14店舗あります)の住所データを取得します。(私にスクレイピング技術がないため人力で店舗名と住所を取得しました。やり方知っている人いれば教えてください。)


 このようなcsvファイル(ファイル名は"来来亭滋賀県店舗.csv")のデータを作りました。

> rairaitei = read.csv("来来亭滋賀県店舗.csv")
> rairaitei
     店舗名                                                 住所
1  野洲本店                                滋賀県野洲市妙光寺290
2    日野店 滋賀県蒲生郡日野町松尾4丁目4番地グランドールソシア1F
3    湖南店                       滋賀県湖南市夏見字柳ノ内1052-5
4  南彦根店     滋賀県彦根市戸賀町大字キジタ143-4キャンス夢工場2
5    栗東店                           滋賀県栗東市下鈎砂田1149-3
6  五個荘店                        滋賀県東近江市五個荘中町129-1
7    堅田店                             滋賀県大津市本堅田3-13-2
8    瀬田店                   滋賀県大津市月輪2丁目字大黒地241-1
9    膳所店                           滋賀県大津市馬場2丁目433-4
10   長浜店                            滋賀県長浜市八幡東町219-2
11   守山店                             滋賀県守山市水保町1357-2
12 西大津店                             滋賀県大津市柳が崎4番7号
13   草津店                               滋賀県草津市草津町1878
14   竜王店                      滋賀県蒲生郡竜王町薬師1172番地1

 データは住所データ(例えば野洲本店なら滋賀県野洲市妙光寺290といった感じ)なので、可視化するにはこの住所データを緯度経度に変換する必要があります。

 逐一住所データを緯度経度に人力で変換するのは大変なので、rvestパッケージの関数を使用して自動的に取得するようにします。方法は、@YM_DSKRさんの記事から学ぶことができました。ありがとうございます。
qiita.com


必要なパッケージ

 まず、必要なパッケージを紹介します。

library(ggmap)
library(rvest)
library(leaflet)

 もしパッケージがなければインストールしてください。

住所データを緯度経度に変換

 住所データを緯度経度に変換します。まずはコードを見てください。

####### import data ##############
rairaitei = read.csv("来来亭滋賀県店舗.csv")

url <- paste0("https://www.geocoding.jp/api/?v=1.1&q=", rairaitei$住所)

lat <- c()
lng <- c()

for(i in 1:length(url)){
  page <- read_html(url[i])
  
  page %>% html_nodes("lat") %>% html_text() -> lat_i
  page %>% html_nodes("lng") %>% html_text() -> lng_i
  
  lat <- c(lat, lat_i)
  lng <- c(lng, lng_i)
  Sys.sleep(5) #取得元に負担をかけないよう1データ取得ごとに5秒あける
}

 このコードで何をやっているか簡単に説明します。

  • Geocodingのサイトに接続し、先ほどのcsvに記載されている住所を緯度経度に変換します。そのための作業が2行目のpaste0(“https:…)のところになります。
  • 緯度をlat(latitudeの略)、経度をlng(longitudeの略)という空箱を用意して、自動的に取得した緯度経度をそれぞれlatとlngの箱に入れていく作業を3,4行目で行っています。
  • 5行目のfor文からは、csvに記載された住所の緯度経度をサイトから取得し、先ほどのlat,lngの箱に入れていく作業を住所データがある分だけ実行してくれます。
  • 最終行のSys.sleep(5)は一つ一つの緯度経度をとる作業の間隔を5秒あけることで、取得先に負担にならないようにしています
取得した緯度経度のデータを元のcsvファイルにくっつけて一つのファイルにする

 先ほどのlatとlngの値を、元の住所データ(今回はrairaitei)にくっつける作業をします。コードは以下のとおりです。

geo_rairai = data.frame(rairaitei, lat, lng)

str(geo_rairai) #lat と lngがfactorになっている

geo_rairai$lat = as.numeric(as.character(geo_rairai$lat))
geo_rairai$lng = as.numeric(as.character(geo_rairai$lng))

write.csv(geo_rairai, "R020223来来亭滋賀緯度経度入り.csv")
  • 1行目のdata.frame関数で元のcsvファイルのデータと先ほど取得した緯度経度データをくっつけます。ここで気を付けなければいけないのが、緯度経度は本来数値データですが、str()関数(2行目)で調べるとなぜかfactor型になっています。
  • そのため、3行目と4行目でas.numericに変換しています。なぜcharacter型に変換してからnumeric型に変換しているのかについては、id:a_habakiriさんのホームページをご覧ください。

a-habakiri.hateblo.jp


 そして、最後に再度の解析に備えて、再度緯度経度データを取得するのが面倒なので、write.csv()関数で、現状の状態を保存します。
 現段階で、このような表ができ、これで可視化のための下準備は終わりです。

> geo_rairai
     店舗名                                                 住所      lat      lng
1  野洲本店                                滋賀県野洲市妙光寺290 35.05915 136.0286
2    日野店 滋賀県蒲生郡日野町松尾4丁目4番地グランドールソシア1F 35.01629 136.2386
3    湖南店                       滋賀県湖南市夏見字柳ノ内1052-5 34.99873 136.0912
4  南彦根店     滋賀県彦根市戸賀町大字キジタ143-4キャンス夢工場2 35.25295 136.2418
5    栗東店                           滋賀県栗東市下鈎砂田1149-3 35.03217 135.9801
6  五個荘店                        滋賀県東近江市五個荘中町129-1 35.16058 136.1966
7    堅田店                             滋賀県大津市本堅田3-13-2 35.11605 135.9145
8    瀬田店                   滋賀県大津市月輪2丁目字大黒地241-1 34.98954 135.9348
9    膳所店                           滋賀県大津市馬場2丁目433-4 35.00030 135.8796
10   長浜店                            滋賀県長浜市八幡東町219-2 35.38240 136.2826
11   守山店                             滋賀県守山市水保町1357-2 35.11636 135.9464
12 西大津店                             滋賀県大津市柳が崎4番7号 35.02758 135.8654
13   草津店                               滋賀県草津市草津町1878 35.01625 135.9493
14   竜王店                      滋賀県蒲生郡竜王町薬師1172番地1 35.05507 136.0897

取得した緯度経度データを可視化する

該当する緯度経度にピンをたてる。

 可視化はleafletパッケージを使います。この作業は、Kazutanさんのホームページがとても分かりやすいので、まずこちらのサイトを見てください。この内容をなぞっていきたいと思います。
kazutan.github.io

 Google mapのようにピンをたてる作業をまずしていきます。

### 取ってきた住所を可視化する ###########

geo_rairai = read.csv("R020223来来亭滋賀緯度経度入り.csv") #先ほど作成したcsvファイルを読み込む

### まっさらな地図を用意する
m <- leaflet(geo_rairai) %>% addTiles() #地図の準備をする

###ひとまずマッピング
m_mapping = m %>% 
  addMarkers(lng=~lng,lat=~lat, label=~店舗名) #

m_mapping #実行

 すると、下図のようにピンがその住所に立ちます。

f:id:purerazz:20200223190520p:plain
来来亭滋賀県のピン

 滋賀県の南に店舗が集中していることが分かりますね。なお、店舗名はピンにマウスをあてると表示されます。

該当する緯度経度に店舗名が記載されたフラグをたてる

 次に、ピンではなく店舗名が直接記載されたフラグをたてる方法を紹介します。addPopus関数を使います。

### ポップアップ形式で施設の名前も入れる
m_name = m %>% 
  addPopups(lng=~lng,lat=~lat,popup=~名称)

m_name

 すると、下図のように店舗名が直接記載されたフラグが立つため、一目で店舗名が分かります。

f:id:purerazz:20200223190547p:plain
来来亭滋賀県の店舗名入りフラグ

図に保存する方法

 現状のままだと自分のパソコンで見る分にはgoogle mapのように拡大縮小や移動が簡単にできて便利ですが、ほかの人と情報共有するには静止画で保存するのが便利ですよね。その際のコードは以下のとおりです。なお、kazutanさんのホームページを最大限参考にしています。いつもありがとうございます。
kazutan.github.io

 保存は作業フォルダの中にpicフォルダを作りその中に静止画を保存するようにします。

library(htmltools)
library(magrittr)
library(leaflet)
library(mapview)
library(htmlwidgets)
library(webshot)

#### popup only
saveWidget(m_mapping, file = "leaflet2png.html")
webshot("leaflet2png.html", file = "pics/R020223rairaiteimap.png", delay = 6)

#### contains names
saveWidget(m_name, file = "leaflet2png.html")
webshot("leaflet2png.html", file = "pics/R020223rairaiteiname.png", delay = 6)

このコードを実行することで、ピンのものと店舗名入りのものとを保存することが出来ます。

 以上です。

 おかしな点などありましたら、指摘いただければ幸いです。

 次回は、gganimateパッケージを使った可視化方法について書きたいと思います。

 どうぞ宜しくお願い致します。