★データ解析備忘録★

ゆる〜い技術メモ

SASによる逆ジオコーディング(緯度経度から都道府県・市を求める)

SASによるジオコーディングはアメリカやカナダのデータは標準装備されていて非常にやりやすいのですが、日本のデータでやろうとするとshapfileから用意しなければならず、非常にやりづらいです。一応、動くものが作れたので備忘録としてメモ。

shapefile

シェープファイル (Shapefile) は、 他の地理情報システム(GIS)間でのデータの相互運用におけるオープン標準として用いられるファイル形式である。 例えば、井戸、川、湖などの空間要素がベクタ画像である点 (数学)、線分、多角形で示され、各要素に固有名称や温度などの任意の属性を付与できる。(Wikipediaより)

今回は、国土数値情報 ダウンロードサービスの「2014年版 行政区域データ 全国のファイル」を使います。 ダウンロード及びzipの解凍は手動でやってもいいのですが、今回はRで緯度経度から都道府県・市区町村を求める - Qiitaを参考にしてRを使いました。

library(magrittr)
library(dplyr)
library(kokudosuuchi)

## このサービスは、「国土交通省 国土数値情報(カテゴリ名)」をもとに加工者が作成
## 以下の国土数値情報ダウンロードサービスの利用約款をご確認の上ご利用ください:
## 
## http://nlftp.mlit.go.jp/ksj/other/yakkan.html

# 2014年版 行政区域データ 全国のファイルをダウンロードして解凍
dl.url <- kokudosuuchi::getKSJURL(identifier = "N03") %>%
  dplyr::filter(year == 2014, areaCode == 0) %>% use_series(zipFileUrl)

download.file(dl.url,
              destfile = "N03-150101_GML.zip")
unzip("N03-150101_GML.zip")

SASによる逆ジオコーディング

shapoefileの読み込み

shapefileの読み込みには、 mapimport プロシージャを使います。これは今後もよく使うデータなので、 libname で指定した場所にsas7bdat形式で保存しておきます。

逆ジオコーディング

まず、プログラム全体と結果を示します。 基本的なアイデアは、「shapefileの中から一番距離が近い場所を取ってくる」です。

f:id:songcunyouzai:20170711143121p:plain

1~7行目

サンプルデータを作成してます。 f:id:songcunyouzai:20170711145609p:plain

8~20行目

サンプルデータとshapefileのデータについて、全ての組み合わせで距離を算出してます。鍵になるのは geodist() 関数です。 詳細は以下のヘルプを御覧ください。

http://support.sas.com/documentation/cdl_alternate/ja/lefunctionsref/67960/HTML/default/n1korpfg2e18lon1nwpow9qijdxe.htm

22~30行目

距離が近い順に並べ替えて、customer_idベースで一番距離が小さい地点を取ってきます。

注意

サンプルデータの内、2行目の千葉県浦安市は正解なのですが(東京ディズニーシー)、1行目(金閣寺)は京都市の北区です。なので間違ってることになります。ここで、距離を求めてソートした段階のデータをみてみます。

proc print data=pairs; run;

f:id:songcunyouzai:20170711151815p:plain

なるほど、北区と右京区が同じ距離になっているのですね。 これはちょっと回避できないかもしれません…

あと、900万行くらいのshapefileに対して全組み合わせで距離を求めてるのでめっちゃ時間かかります。

もっと速くて正確な方法がある人は是非教えていただきたいです…