緯度・経度から市区町村の情報を追加する方法

都道府県や市区町村の情報を緯度・経度から取得する方法としては、外部のAPIを利用するアプローチがよく知られていますが、APIの登録やキーの管理といった手間がかかるうえ、利用コストや1日あたりの処理件数に制限がある場合もあります。

また、AIに変換を任せる方法もありますが、処理可能な量や精度の問題が伴います。

そこで、こちらのノートでは、sfパッケージを活用し、国土交通省が公開している日本全国の行政区域データをもとに、緯度・経度から都道府県・市区町村名の情報を高精度かつ一括で付与する方法を紹介します。

API登録も不要で、大量のデータにも安定して対応できるのが大きな特長です。

処理の流れ

データの中にある緯度・経度の数値は、地球上の特定の場所を指し示す「座標」です。

今回の処理では、まずその座標を地図上の「ピン」として立てます。

次に、日本全国の市区町村の境界線データを読み込み、それぞれのピンがどの市区町村の「枠」の中に含まれるかを自動で判定します。

最後に、判定された都道府県名・市区町村名・行政コードを元のデータに新しい列として追加して返します。この一連の処理は空間結合と呼ばれる技術を使っており、sfパッケージの関数がその複雑な地理的計算をすべて担ってくれています。

必要なパッケージのインストール

まず、空間結合を実行するために必要な sfパッケージをインストールします。

プロジェクトメニューから「Rパッケージの管理」を選択します。

Rパッケージの管理のダイアログが表示されるため、「パッケージをインストール」タブをクリックしてから sfパッケージをインストールしてください。

地図情報のダウンロード

今回の処理では、緯度・経度が「日本のどの市区町村に含まれるか」を判定するために、日本全国の市区町村の境界データが必要になります。

そのため、以下のリンクから地図データのファイルをダウンロードしてください。

ダウンロードしたファイルは、後述のステップでパスを指定しますので、確認しやすいフォルダに保存、または移動しておいてください。

なお、このファイルは、国土交通省が公開している行政区域データ(国土数値情報)をもとに作成されています。

元データはShapefileと呼ばれる複数のファイルからなる形式ですが、扱いやすくするためにGeoPackage(.gpkg)形式の1つのファイルにまとめ直したもので、元データは以下のページから確認・ダウンロードいただくことが可能です。

  • 国土数値情報 行政区域データ - リンク

Rスクリプトの登録

次に、市区町村情報を追加するための関数をExploratoryにRスクリプトとして登録します。

スクリプトメニューから「スクリプト」を選択します。

任意のスクリプト名を設定します。

スクリプトエディタが開いたら、以下のコードをエディタに貼り付けます。

library(sf)
add_city_names <- function(data, 
                                 lon_col = "lon", 
                                 lat_col = "lat", 
                                 map_path = "ダウンロードしたファイルのパス") {
  
  if (!exists("cached_japan_map")) {
    if (!file.exists(map_path)) stop(paste0("ファイルが見つかりません: ", map_path))
    message("ローカルから地図データを読み込んでいます...")
    cached_japan_map <<- st_read(map_path, quiet = TRUE) %>% 
      st_transform(4326)
  }
  
  # 空間ジョイン
  joined_sf <- data %>%
    st_as_sf(coords = c(lon_col, lat_col), crs = 4326, remove = FALSE) %>%
    st_join(cached_japan_map, join = st_intersects, suffix = c("", ".map"))
  
  # 重複エラーを避けるための処理
  # 「都道府県」が既にある場合は「都道府県_地図」にする
  new_pref_name <- if ("都道府県" %in% colnames(data)) "都道府県_地図" else "都道府県"
  new_city_name <- if ("市区町村" %in% colnames(data)) "市区町村_地図" else "市区町村"
  
  joined_sf %>%
    st_drop_geometry() %>%
    # rename の代わりに、動的に名前を変えられる rename_with や変数を活用
    rename(
      !!new_pref_name := N03_001,
      !!new_city_name := N03_004,
      行政コード       = N03_007
    ) %>%
    select(everything(), all_of(c(new_pref_name, new_city_name, "行政コード")), 
           -starts_with("N03_"), -starts_with("Shape"), -any_of("OBJECTID"))
}

このとき、map_pathの引数は、map_path = "/Users/tanaka/Documents/japan_map.gpkg"のように、先ほどダウンロードした japan_map.gpkg ファイルの保存先のパスに書き換えてください。

コードを貼り付けたら、「実行」ボタンをクリックしてスクリプトを登録します。

緯度・経度から市区町村の情報を追加する

ここからは、先程作成した関数を使って、緯度・経度から都道府県・市区町村の情報を追加する手順を説明いたします。

使用するデータは、1行が1つの物件(宿泊施設)を表しており、物件の緯度や経度の列が含まれています。

まずはステップの追加メニューから「カスタムRコマンド」を選択します。

カスタムRコマンドのダイアログ開いたら、エディタに以下のコードを入力し、実行します。

add_city_names(lat_col = "緯度", lon_col = "経度")

lat_col の引数には緯度の列名を、lon_col の引数には経度の列名を指定します。

今回のデータでは列名がそれぞれ「緯度」「経度」(日本語)となっているため、上記のような設定になっています。

「実行」ボタンをクリックすると、ステップが追加され、データの最後に「都道府県」「市区町村」「行政コード」の3列が新しく追加されます。

なお、元のデータに「都道府県」や「市区町村」という列名が存在しているときには、列名の重複を避けるために自動的に「都道府県_地図」「市区町村_地図」という名前に変更されて列が追加されます。

参考情報

  • カスタムスクリプトの作り方シリーズ: スクリプト登録の方法 - リンク
  • 国土数値情報 行政区域データ - リンク
Export Chart Image
Output Format
PNG SVG
Background
Set background transparent
Size
Width (Pixel)
Height (Pixel)
Pixel Ratio