library(tidyverse) # データハンドリング
library(here) # 相対パスを使用
library(sf) # 地理データを使用
# 福島県のデータの読み込み
<- read_sf(here("data/N03-20240101_07_GML/N03-20240101_07.shp")) fukushima
はじめに
今回は地理データを集約する方法について説明します。
集約とは、例えば市町村単位のデータを県単位のデータにまとめるというイメージです。市町村単位のデータしかもっていないものの都道府県単位でプロットしたいといった場合に、今回説明する方法を使えば対応することができます。
使用するパッケージ・データ
今回は使用するデータを軽量化するために、イントロで使用した福島県のデータを使います1。日本の全市町村のような場合でも同様の流れで進めることができます。
データの確認
データのCRS(座標参照系)はデータを読み込んだら確認しておくようにしましょう。これがデータごとに異なるとデータ間で整合性が失われたり、同じデータでも思ったプロットにならなかったりします。
st_crs(fukushima)
Coordinate Reference System:
User input: JGD2011
wkt:
GEOGCRS["JGD2011",
DATUM["Japanese Geodetic Datum 2011",
ELLIPSOID["GRS 1980",6378137,298.257222101,
LENGTHUNIT["metre",1]]],
PRIMEM["Greenwich",0,
ANGLEUNIT["degree",0.0174532925199433]],
CS[ellipsoidal,2],
AXIS["geodetic latitude (Lat)",north,
ORDER[1],
ANGLEUNIT["degree",0.0174532925199433]],
AXIS["geodetic longitude (Lon)",east,
ORDER[2],
ANGLEUNIT["degree",0.0174532925199433]],
USAGE[
SCOPE["Horizontal component of 3D system."],
AREA["Japan - onshore and offshore."],
BBOX[17.09,122.38,46.05,157.65]],
ID["EPSG",6668]]
2行目にJGD2011
、1番下にID["EPSG",6668]]
と書かれています。6668
はJGD2011
に対応する数字であり、他の数字であっても1対1の関係で数字が割り振られています。JGD2011は日本測地系2011を表しているのですが、CRSの詳細は次回に回します。
ひとまずここでは問題ないので、データの中身を確認したいと思います。
N03_001 | N03_002 | N03_003 | N03_004 | N03_005 | N03_007 | geometry |
---|---|---|---|---|---|---|
福島県 | NA | NA | 福島市 | NA | 07201 | POLYGON ((140.3745 37.65095... |
福島県 | NA | NA | 会津若松市 | NA | 07202 | POLYGON ((139.949 37.33309,... |
福島県 | NA | NA | 郡山市 | NA | 07203 | POLYGON ((140.1249 37.33085... |
福島県 | NA | NA | いわき市 | NA | 07204 | POLYGON ((140.8494 36.9161,... |
福島県 | NA | NA | いわき市 | NA | 07204 | POLYGON ((140.889 36.91886,... |
福島県 | NA | NA | いわき市 | NA | 07204 | POLYGON ((140.8873 36.91099... |
1列目に県名、4列目に市町村名、6列目に市町村コード、7列目に座標データが入っているのが確認できます。
次にプロットして確認します。
ggplot() +
geom_sf(data = fukushima) +
theme_void()
このように市町村の境界が示されています。
今回の目標はこれを県でまとめることなので、最終的に県境だけが残ることになります。
データの集約
それでは本題のデータの集約に入ります。
これまでTidyverseを使ったことがある方であれば、dplyr::summarise()
が思い浮かぶ方がいらっしゃるのではないでしょうか。特定のグループごとに平均や合計を集計する際に便利な関数ですが、基本的な概念はそれと同じです。
平均を算出する場合であればmean()
を使いますが、地理データをまとめる際にはsf
パッケージのst_union()
を用います。
早速使い方を見てみると、
<- fukushima |>
fukushima_summarise summarise(geometry = st_union(geometry),
.by = N03_001)
# 先にgroup_by()をしても同じ
# fukushima_summarise <- fukushima |>
# group_by(N03_001) |>
# summarise(geometry = st_union(geometry))
このように、県を表す変数でグルーピングした上でgeometry
を上書きするような形になります。県番号のような、グループを識別できる変数があればそれを用いてもよいのですが、今回は県名しかないので、それを利用しています。
コードにもコメントアウトして書いているように、group_by()
は先に実行しても問題ありません。summarise()
内の.by
は、group_by()
を指定しているのと同様です。
集約したデータの確認
fukushima_summarise
を確認してみると、1つの行にまとまっていることがわかります。
N03_001 | geometry |
---|---|
福島県 | MULTIPOLYGON (((141.0231 37... |
さらにこれをプロットしてみると、
ggplot() +
geom_sf(data = fukushima_summarise) +
theme_void()
このように、市境がなくなり、県境のみが残っています。
今は1つの県のみを用いていますが、全国のデータを用いた場合でも、都道府県ごとにgroup_by()
されますので、都道府県単位のプロットに集約することが可能です。
おわりに
今回はsummarise()
とst_union()
を用いて地理データを集約する方法を説明しました。
市町村を都道府県単位にする以外にも、政令指定都市が区単位になっているので市単位にしたい、と言った場合にも応用することができます。
そういった場合にはTipsページでご紹介したデータフレームを用い、政令指定都市の区コードを市町村コードに書き換えた後で今回と同じ工程を踏めば、まとめることができます。
ぜひご活用ください。
注
導入 + ハンドリングに出典も示しています。↩︎