library(tidyverse)
library(readxl)
library(sf)
library(tmap)塗り分け地図(コロプレスマップ)の作成
塗り分け地図(コロプレスマップ)
コロプレスマップ(Choropleth Map)は、統計の数値によって色を塗り分けた地図のことです。 階級区分図と呼ばれることもあります。
佐賀県の市町別塗り分け地図
佐賀県の市町村別塗り分け地図をつくってみましょう。
地図データは、佐賀県オープンデータカタログサイトにある、ポリゴン(市町村別)のGeoJSONファイルを使います。 リンクから佐賀県オープンデータカタログサイトにアクセスして、[⬇️ダウンロード]をクリックしてください。
GeoJSONファイルがダウンロードされたと思いますが、ダウンロードされたファイル名が非常に長くなっているかもしれません。 この場合は、ファイル名の最後の部分にある「410004saga」だけを残して、ファイル名を「410004saga.geojson」に修正しておいてください。
ダウンロードした「410004saga.geojson」を、ワーキングディレクトリのdataフォルダに移動してください。 read_sf関数を使って、GeoJSONファイルをRに読み込みます。
saga_map <- read_sf("data/410004saga.geojson")統計データは、佐賀県オープンデータカタログサイトにある、男女別人口総数及ひ世帯総数(市町村別)を使います。
このExcelファイルは、先ほどダウンロードしたGeoJSONファイルと組み合わせて使うことが想定されていますので、これを例として説明します。
ダウンロードした「410004saga.xlsx」を、ワーキングディレクトリのdataフォルダに移動してください。 readxl::read_excel関数を使って読み込みます。
saga_dat <- read_excel("data/410004saga.xlsx")この読み込んだ統計データには、市町別の人口データがありますので、これを使って地図を塗り分けましょう。
そこでまず、地図データと統計データを「結合」する必要があります。 地図データの中身を見ると、このようなデータが格納されています。
View(saga_map)| KEN_NAME | GST_NAME | CSS_NAME | KEY_CODE |
|---|---|---|---|
| 佐賀県 | 鹿島市 | NA | 412074 |
| 佐賀県 | 唐津市 | NA | 412023 |
| 佐賀県 | 神埼市 | NA | 412104 |
| 佐賀県 | 杵島郡 | 江北町 | 414247 |
| 佐賀県 | 多久市 | NA | 412040 |
そして統計データの中身をみると、以下のようなデータが格納されています。
View(saga_dat)| KEY_CODE | 人口総数 | 市区町村 | 男 | 女 | 世帯総数 |
|---|---|---|---|---|---|
| 412015 | 236372 | 佐賀市 | 111453 | 124919 | 93306 |
| 412023 | 122785 | 唐津市 | 57547 | 65238 | 43872 |
| 412031 | 72902 | 鳥栖市 | 34799 | 38103 | 27630 |
| 412040 | 19749 | 多久市 | 9146 | 10603 | 6847 |
| 412058 | 55238 | 伊万里市 | 26395 | 28843 | 19698 |
両方のデータに共通するデータ列があることに気付いたと思います。 「KEY_CODE」という列に市町村コードが格納されていますが、このデータが2つのデータに共通して存在します。 そして、この市町村コードというのは全国の市町村にユニークな(一意の)番号が割り振られていますので、重複する(複数の市町村が同じコードを持つ)ことがありません。
なので、このKEY_CODEをキーにして、2つのデータを結合することにします。
2つのデータフレームを結合するには、left_join関数が便利です。 saga_mapに、KEY_CODEをキーにして、saga_datを結合するには、次のようなコードを実行します。
saga_map <- saga_map |>
left_join(saga_dat, by = join_by(KEY_CODE))結果を確認してみましょう。 saga_mapのデータに、saga_datのデータが正しく結合されていることがわかります。
View(saga_map)| KEN_NAME | GST_NAME | CSS_NAME | KEY_CODE | 人口総数 | 市区町村 | 男 | 女 | 世帯総数 |
|---|---|---|---|---|---|---|---|---|
| 佐賀県 | 鹿島市 | NA | 412074 | 29684 | 鹿島市 | 13920 | 15764 | 10124 |
| 佐賀県 | 唐津市 | NA | 412023 | 122785 | 唐津市 | 57547 | 65238 | 43872 |
| 佐賀県 | 神埼市 | NA | 412104 | 31842 | 神埼市 | 15172 | 16670 | 10913 |
| 佐賀県 | 杵島郡 | 江北町 | 414247 | 9583 | 江北町 | 4497 | 5086 | 3225 |
| 佐賀県 | 多久市 | NA | 412040 | 19749 | 多久市 | 9146 | 10603 | 6847 |
塗り分け地図を描くのは難しくありません。 tm_polygons関数のfill引数に、塗り分けに利用したいデータ列名を指定するだけです。
tm_shape(saga_map) + tm_polygons(fill = "人口総数") +
tm_crs(6670) + tm_compass() + tm_scalebar() +
tm_layout(text.fontfamily = "YuGo-Medium")日本全国の市区町村別塗り分け地図
次に、日本全国の市区町村別塗り分け地図を作ってみましょう。 市区町村の数が一気に増えますが、やることは佐賀県版の塗り分け地図と同じです。
地図データは、日本 市区町村 コロプレス地図(塗り分け地図) | 歴史的行政区域データセットβ版を使います。 リンクから、データセットの基準年月日が2023-01-01、低解像度のファイルをダウンロードしてください(リンクを右クリックして「名前を付けて保存」するといいと思います)。
ダウンロードした「jp_city.c.topojson」をデータフォルダに格納してください1。
jpn_map <- read_sf("data/jp_city.c.topojson") |> st_set_crs(6668)属性データを見てみると、N03_007というデータ列に、自治体コードが収録されていることが確認できます。
glimpse(jpn_map)Rows: 1,909
Columns: 10
$ id <chr> "gci:01101A1972", "gci:01102A1972", "gci:01103A1972", "gci:…
$ OBJECTID <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, NA, NA, NA, NA, NA, NA, 802,…
$ N03_001 <chr> "北海道", "北海道", "北海道", "北海道", "北海道", "北海道", "北海道", "北海道", "北海…
$ N03_002 <chr> "石狩振興局", "石狩振興局", "石狩振興局", "石狩振興局", "石狩振興局", "石狩振興局", "石狩振興…
$ N03_003 <chr> "札幌市", "札幌市", "札幌市", "札幌市", "札幌市", "札幌市", "札幌市", "札幌市", "札幌…
$ N03_004 <chr> "中央区", "北区", "東区", "白石区", "豊平区", "南区", "西区", "厚別区", "手稲区", …
$ N03_007 <chr> "01101", "01102", "01103", "01104", "01105", "01106", "0110…
$ Shape_Leng <dbl> 0.5516441, 0.5794416, 0.4014587, 0.3107632, 0.4389366, 1.64…
$ Shape_Area <dbl> 0.005127706, 0.007032524, 0.006300214, 0.003808508, 0.00510…
$ geometry <MULTIPOLYGON [°]> MULTIPOLYGON (((141.3552 43..., MULTIPOLYGON (…
統計データは、令和2年国勢調査の結果を利用しましょう。 国勢調査 / 令和2年国勢調査 / 人口等基本集計 (主な内容:男女・年齢・配偶関係,世帯の構成,住居の状態,母子・父子世帯,国籍など)から、Excelファイルをダウンロードし、データフォルダに格納してください。
readxl::read_excel関数を使ってファイルを読み込みます(read_excel関数の使い方については、ファイル入出力/Excelファイルの読み込み(実践編)をご覧ください)。
「地域識別コード」「自治体コード」「人口増減率」をそれぞれ「type」「code」「pop_growth_rate」というデータ列に格納しています。
jpn_dat <-
read_excel(
path = "data/b01_01.xlsx",
range = "A16:M4101",
col_names = c("type", "code", "pop_growth_rate"),
col_types = c("text", rep("skip", 4), "text", rep("skip", 6), "numeric"),
na = c("", "-")
) |>
filter(type %in% c("0", "2", "3"))読み込んだデータのうち、filter関数を使って、市区町村のデータを取り出しています。 地域識別コードの意味は、以下の表のとおりです。 ここでは地域識別コードが0、2、3のいずれかであるデータ列を抽出しています。
| コード | 地域 |
|---|---|
| a | 全国・都道府県 |
| 0 | 東京都23区及び政令指定都市の区 |
| 1 | 東京都特別区部及び政令指定都市 |
| 2 | 政令指定都市以外の市 |
| 3 | 町村 |
| 9 | 2000(平成12)年現在の市区町村 |
読み込んだデータを確認してみましょう2。
glimpse(jpn_dat)Rows: 1,896
Columns: 3
$ type <chr> "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "2",…
$ code <chr> "01101", "01102", "01103", "01104", "01105", "01106", …
$ pop_growth_rate <dbl> 4.65141, 1.40263, 1.32373, 1.07403, 3.03953, -3.83384,…
地図データと統計データをleft_join関数を使って結合します。 jpn_mapにjpn_datを結合しますが、自治体コードが前者ではN03_007という列に、後者ではcodeという列に格納されています。 その場合は、以下のようにjoin_by関数の引数を指定します。
jpn_map <- jpn_map |>
left_join(jpn_dat, by = join_by(N03_007 == code))結合したファイルを確認してみましょう。
glimpse(jpn_map)Rows: 1,909
Columns: 12
$ id <chr> "gci:01101A1972", "gci:01102A1972", "gci:01103A1972", …
$ OBJECTID <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, NA, NA, NA, NA, NA, NA,…
$ N03_001 <chr> "北海道", "北海道", "北海道", "北海道", "北海道", "北海道", "北海道", "北海道"…
$ N03_002 <chr> "石狩振興局", "石狩振興局", "石狩振興局", "石狩振興局", "石狩振興局", "石狩振興局", …
$ N03_003 <chr> "札幌市", "札幌市", "札幌市", "札幌市", "札幌市", "札幌市", "札幌市", "札幌市"…
$ N03_004 <chr> "中央区", "北区", "東区", "白石区", "豊平区", "南区", "西区", "厚別区", "手…
$ N03_007 <chr> "01101", "01102", "01103", "01104", "01105", "01106", …
$ Shape_Leng <dbl> 0.5516441, 0.5794416, 0.4014587, 0.3107632, 0.4389366,…
$ Shape_Area <dbl> 0.005127706, 0.007032524, 0.006300214, 0.003808508, 0.…
$ geometry <MULTIPOLYGON [°]> MULTIPOLYGON (((141.3552 43..., MULTIPOLY…
$ type <chr> "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "2",…
$ pop_growth_rate <dbl> 4.65141, 1.40263, 1.32373, 1.07403, 3.03953, -3.83384,…
塗り分け地図を書いてみましょう。 ここでは九州だけを抜き出して表示しています。
kyushu <- jpn_map |>
filter(N03_001 %in% c("福岡県", "佐賀県", "長崎県", "大分県", "熊本県", "宮崎県", "鹿児島県"))
tm_shape(kyushu) +
tm_polygons(
fill = "pop_growth_rate",
fill.scale = tm_scale_intervals(,
values = "tol.bu_rd",
midpoint = 0
),
fill.legend = tm_legend("人口増減率(%)")
) +
tm_crs(6670) + tm_compass() + tm_scalebar() +
tm_layout(text.fontfamily = "YuGo-Medium")
市区町村別人口増加率(2015〜2020)
