初心者チュートリアル資料

データの読み込みから可視化

作者

伊東宏樹

公開

2024年11月23日

内容

  • データの読み込み

  • ggplot2による可視化

  • 地理空間データの読み込み

  • 地理空間データの可視化

データの読み込み

準備

tidyverse(メタ)パッケージを読み込みます。

library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.5
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   3.5.1     ✔ tibble    3.2.1
✔ lubridate 1.9.3     ✔ tidyr     1.3.1
✔ purrr     1.0.2     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors

読み込み

データとして、国勢調査のデータを使用します。

e-statの「国勢調査/時系列データ/男女,年齢,配偶関係/男女別人口及び人口性比 - 全国,都道府県(大正9年~令和2年)」からCSV(列指向データ)をダウンロードします。ここでは、FEH_00200521_241003100519.csvというファイル名でダウンロードされました(ダウンロードごとにファイル名が変わると思われます)。ダウンロードされたファイルをdataフォルダの中に入れておきます。

ダウンロードされたファイルをreadrパッケージのread_csv関数を使ってRに読み込みます。fie.path関数で、使用するシステムに応じたファイルパスを作成して、data_path変数に入れておきます。

read_csv関数では、このファイルパス(data_path)からファイルを読み込みます。その他の引数は、以下のとおりです。

  • col_types: 各列の型(各文字が各列に対応、f: 因子、c: 文字列、d: 倍精度実数)
  • na: データファイル中で欠測(データなし)を表す文字(ここでは”-“)
  • locale: ここでは文字コード(CP932 (≒Shift_JIS))を指定しています
data_path <- file.path("data", "FEH_00200521_241003100519.csv")
pref_data <- read_csv(file = data_path,
                      col_types = "fcfcfccccd",
                      na = "-",
                      locale = locale(encoding = "CP932"))

結果

この段階で整然データ(tidy data)になっています。

pref_data
# A tibble: 4,200 × 10
   tab_code 表章項目 cat01_code 男女_時系列 area_code 地域_時系列 time_code 
   <fct>    <chr>    <fct>      <chr>       <fct>     <chr>       <chr>     
 1 020      人口     100        総数        00000     全国        1920000000
 2 020      人口     100        総数        00000     全国        1925000000
 3 020      人口     100        総数        00000     全国        1930000000
 4 020      人口     100        総数        00000     全国        1935000000
 5 020      人口     100        総数        00000     全国        1940000000
 6 020      人口     100        総数        00000     全国        1945000000
 7 020      人口     100        総数        00000     全国        1950000000
 8 020      人口     100        総数        00000     全国        1955000000
 9 020      人口     100        総数        00000     全国        1960000000
10 020      人口     100        総数        00000     全国        1965000000
# ℹ 4,190 more rows
# ℹ 3 more variables: `時間軸(調査年)` <chr>, unit <chr>, value <dbl>

整形(必要な部分を残す)

読み込んだデータのうち、後で使うところだけを残します。これには、dplyrパッケージのfilter関数とmutate関数を使用しています。前者で必要な行だけを残し、後者では、新しい列を作ったうえで、その他の列を捨てて(.keep = "none" )います。

また、ここでは、パイプ演算子(“|>”)を使用しています。これは、式の計算結果を次の関数の第1引数として与えるというものです。

pref_data2 <- pref_data |>
  dplyr::filter(`表章項目` == "人口" &
                 !(`地域_時系列` %in% c("人口集中地区", "人口集中地区以外の地区"))) |>
  dplyr::mutate(`男女` = factor(`男女_時系列`, levels = c("総数", "男", "女")),
                `地域` = factor(`地域_時系列`, levels = unique(pref_data$`地域_時系列`)),
                `` = as.numeric(str_sub(time_code, 1, 4)),
                `人口` = value,
                .keep = "none")

整形結果

必要な部分だけを残すと以下のようになりました。

pref_data2
# A tibble: 3,024 × 4
   男女  地域     年     人口
   <fct> <fct> <dbl>    <dbl>
 1 総数  全国   1920 55963053
 2 総数  全国   1925 59736822
 3 総数  全国   1930 64450005
 4 総数  全国   1935 69254148
 5 総数  全国   1940 73114308
 6 総数  全国   1945 71998104
 7 総数  全国   1950 84114574
 8 総数  全国   1955 90076594
 9 総数  全国   1960 94301623
10 総数  全国   1965 99209137
# ℹ 3,014 more rows

Excelファイルの場合

Excelファイルの場合の読み込み方法もちょっとだけ紹介します。

readxlパッケージのread_excel関数で、Excelファイルを読み込むことができます。例として、e-Gov/人口総数:総務省『国勢調査』から、ダウンロードしたファイル(file01.xls)を使います。

このファイルの先頭6行にはメタデータが記述されていますので、read_excel関数で、skip = 6“という引数を与えて、先頭から6行を読み飛ばすようにします。

library(readxl)

excel_file_path <- file.path("data", "file01.xls")
city_data <- read_excel(excel_file_path, skip = 6)
head(city_data)
# A tibble: 6 × 11
  市区町村名    市区町村コード `1970年` `1975年` `1980年` `1985年` `1990年`
  <chr>         <chr>             <dbl>    <dbl>    <dbl>    <dbl>    <dbl>
1 北海道 札幌市 011002          1010177  1240613  1401757  1542979  1671742
2 北海道 函館市 012025           322497   334416   345165   342540   328493
3 北海道 小樽市 012033           191802   184406   180728   172486   163211
4 北海道 旭川市 012041           297189   320526   352619   363631   359071
5 北海道 室蘭市 012050           162059   158715   150199   136208   117855
6 北海道 釧路市 012068           204793   219180   227234   226097   216423
# ℹ 4 more variables: `1995年` <dbl>, `2000年` <dbl>, `2005年` <dbl>,
#   `2010年` <dbl>

ggplot2による可視化

ここからデータをグラフにして可視化していきます。そのためにここではggplot2を使用します。データには、先に読み込んだ都道府県の人口データを使用しました。

グラフ作成の前に、使用する日本語フォントを変数にいれておきます。この部分はシステムやお好みで適宜変えてください。

jp_font <- "YuGothic"
# jp_font <- "Noto Sans JP"

折れ線グラフ

まず、全国の人口総数データを時系列で表示します。時系列データの可視化には折れ線グラフを使用します。

dplyrパッケージのfilter関数で、グラフに必要な行だけに絞り込みます。

pref_data3 <- pref_data2 |>
  dplyr::filter(`地域` == "全国", `男女` == "総数")

ggplot関数は、グラフのオブジェクトの初期化をおこなう関数です。data引数に、使用するデータのpref_data3を与えます。mapping引数にはaes(x = `年`, y = `人口`)という関数の値を与えています(aes = aesthetic mappings)。これにより、X軸に年、Y軸に人口をマッピングすると指定しています。

ggplot2では、“+”演算子で、レイヤー(層)を追加していってグラフを完成させるようになっています。次の行のgeom_line関数で折れ線グラフを描画します。

ggplot(data = pref_data3, mapping = aes(x = ``, y = `人口`)) +
  geom_line()

これでもグラフは作成されますが、さらに見やすくなるようにしていきます。具体的には以下のようにしました。

  • geom_pointで、点も加えます。
  • scale_x_continuousscale_y_continuousで軸の表示を調整します。
  • theme_grayで、テーマの設定とフォントの設定をおこないます。
ggplot(pref_data3, aes(x = ``, y = `人口`)) +
  geom_line() + geom_point() +
  scale_x_continuous(breaks = seq(1920, 2020, by = 10)) +
  scale_y_continuous(name = "人口(人)",
                     breaks = seq(6e+7, 12e+7, by = 2e+7),
                     labels = c("6000万", "8000万", "1億", "1億2000万")) +
  theme_gray(base_family = jp_font)

次に全国のデータを、総数・男・女の別に表示します。

まず、dplyr::filter関数で全国のデータだけ残します。この関数の返り値をパイプ演算子で次の行のggplot関数に渡しています。

ggplot関数のmapping引数では、aes関数colour = `男女`と引数を与えることで、男女列の要素別に色分けして線を引きます。また、scale_colour_manualで各要素の色を指定しています(カラーユニバーサルデザイン対応)。

pref_data2 |>
  dplyr::filter(`地域` == "全国") |>
  ggplot(aes(x = ``, y = `人口`, colour = `男女`)) +
  geom_line() + geom_point(size = 2.5) +
  scale_colour_manual(values = c("#000000", "#005aff", "#ff4b00")) +
  scale_x_continuous(breaks = seq(1920, 2020, 10)) +
  scale_y_continuous(name = "人口(人)",
                     breaks = seq(4e+7, 12e+7, 2e+7),
                     labels = c("4000万", "6000万", "8000万", "1億", "1億2000万")) +
  theme_gray(base_family = jp_font)

つづいて、富山県・石川県・福井県のデータを、総数・男・女の別に表示します。dplyr::filter関数で、この3県のデータだけを抽出しています。aes関数の引数で”shape = `地域`, linetype = `地域`“とすることで、県別に点の形と線の種類が変わります。

scale_y_continuous関数では、Y軸の目盛りを、2×105から12×105の間で、2×105刻みとすること、表示されるラベルは104(=1万)単位とすることを指定しています。

pref_data2 |>
  dplyr::filter(`地域` %in% c("富山県", "石川県", "福井県")) |>
  ggplot(aes(x = ``, y = `人口`, colour = `男女`, 
             shape = `地域`, linetype = `地域`)) +
  geom_line() + geom_point(size = 2.5) +
  scale_colour_manual(values = c("#000000", "#005aff", "#ff4b00")) +
  scale_x_continuous(breaks = seq(1920, 2020, 10)) +
  scale_y_continuous(name = "人口(万人)",
                     limits = c(2e+5, 12e+5),
                     breaks = seq(2e+5, 12e+5, by = 2e+5),
                     labels = \(x) x / 1e+4) +
  theme_gray(base_family = jp_font)

積み上げ折れ線グラフとグラフの分割

一応目的のグラフは描けましたが、これでは煩雑なので、グラフを分けて積み上げ折れ線グラフにします。

そのためまずデータを変形します。総数と男女別の人口が新しい列になるようにします。

pref_data4 <- pref_data2 |>
  tidyr::pivot_wider(names_from = `男女`, values_from = `人口`)

このようになります。

head(pref_data4, 10)
# A tibble: 10 × 5
   地域     年     総数       男       女
   <fct> <dbl>    <dbl>    <dbl>    <dbl>
 1 全国   1920 55963053 28044185 27918868
 2 全国   1925 59736822 30013109 29723713
 3 全国   1930 64450005 32390155 32059850
 4 全国   1935 69254148 34734133 34520015
 5 全国   1940 73114308 36566010 36548298
 6 全国   1945 71998104 33894059 38104045
 7 全国   1950 84114574 41241192 42873382
 8 全国   1955 90076594 44242657 45833937
 9 全国   1960 94301623 46300445 48001178
10 全国   1965 99209137 48692138 50516999

さらに必要な3県のデータを取り出して、グラフを描画します。ここでは、facet_wrap関数を使って各県のグラフを分割して描くようにしました。

geom_areageom_ribbonを組み合わせて使うことで、積み上げグラフにしています。また、annotate関数でグラフに直接説明を書き込んでいます。

pref_data4 |>
  dplyr::filter(`地域` %in% c("富山県", "石川県", "福井県")) |>
  ggplot() +
  geom_area(aes(x = ``, y = ``), fill ="#ff4b00") +
  geom_ribbon(aes(x = ``, ymin = ``, ymax = `総数`), fill = "#005aff") +
  annotate("text", x = 2000, y = 3e+5, label = "女", colour = "white") +
  annotate("text", x = 2000, y = 7.2e+5, label = "男", colour = "white") +
  scale_x_continuous(breaks = seq(1920, 2020, 20)) +
  scale_y_continuous(name = "人口(万人)",
                     limits = c(0, 12e+5),
                     breaks = seq(0, 12e+5, by = 2e+5),
                     labels = \(x) x / 1e+4) +
  theme_gray(base_family = jp_font) +
  facet_wrap(~`地域`, nrow = 2)

散布図

都道府県ごとに、2020年の男女の人口を比較します。

pref_data4から、地域が”全国”以外(=各都道府県)で2020年のデータを抽出します。

pref_data5 <- pref_data4 |>
  dplyr::filter(`地域` != "全国", `` == 2020)

このようになります。

head(pref_data5)
# A tibble: 6 × 5
  地域      年    総数      男      女
  <fct>  <dbl>   <dbl>   <dbl>   <dbl>
1 北海道  2020 5224614 2465088 2759526
2 青森県  2020 1237984  583402  654582
3 岩手県  2020 1210534  582952  627582
4 宮城県  2020 2301996 1122598 1179398
5 秋田県  2020  959502  452439  507063
6 山形県  2020 1068027  516438  551589

グラフにします。geom_pointで散布図を作成します。テーマはtheme_bwにしました。

ggplot(pref_data5, aes(x = ``, y = ``)) +
  geom_point() +
  theme_bw(base_family = jp_font)

見ばえを整えます。

  • geom_abline(linetype = 2, slope = 1, intercept = 0)”で、X=Yの点線を引きます。

  • coord_fixed(ratio = 1)”で、X軸とY軸の比を1:1に設定します。

ggplot(pref_data5, aes(x = ``, y = ``)) +
  geom_abline(linetype = 2, slope = 1, intercept = 0) +
  geom_point(size = 3, alpha = 0.6) +
  scale_x_continuous(name = "男性人口(万人)",
                     limits = c(0, 8e+6),
                     breaks = seq(0, 8e+6, by = 2e+6),
                     labels = \(x) x / 1e+4) +
  scale_y_continuous(name = "女性人口(万人)",
                     limits = c(0, 8e+6),
                     breaks = seq(0, 8e+6, by = 2e+6),
                     labels = \(x) x / 1e+4) +
  coord_fixed(ratio = 1) +
  theme_bw(base_family = jp_font)

棒グラフ

各都道府県の2020年の人口総数をグラフにします。

geom_colは棒グラフを描画します。テーマはtheme_classicを使用しました。

pref_data2 |>
  dplyr::filter(`地域` != "全国", `男女` == "総数", `` == 2020) |>
  ggplot(aes(x = `地域`, y = `人口`)) +
  geom_col() +
  theme_classic(base_family = jp_font)

横軸のラベルが重なっていて読めないので、scale_x_discrete関数で”guide = guide_axis(angle = 90)“と指定して、ラベルを90°回転させます。また、scale_y_continuous関数で、横軸の表示を整えます。

pref_data2 |>
  dplyr::filter(`地域` != "全国", `男女` == "総数", `` == 2020) |>
  ggplot(aes(x = `地域`, y = `人口`)) +
  geom_col() +
  scale_x_discrete(name = "都道府県", guide = guide_axis(angle = 90)) +
  scale_y_continuous(name = "人口(万人)",
                     limits = c(0, 1.5e+7),
                     breaks = seq(0, 1.5e+7, 5e+6),
                     labels = \(x) x / 1e+4) +
  theme_classic(base_family = jp_font)

横にしたほうが見やすいかもしれません。そうするには、coord_flip()を使います。そうすると、縦軸が下から並ぶようになるので、scale_x_discrete関数で、limits = revとして、上から並ぶようにさせます。

pref_data2 |>
  dplyr::filter(`地域` != "全国", `男女` == "総数", `` == 2020) |>
  ggplot(aes(x = `地域`, y = `人口`)) +
  geom_col() +
  scale_x_discrete(name = "都道府県", limits = rev) +
  scale_y_continuous(name = "人口(万人)",
                     limits = c(0, 1.5e+7),
                     breaks = seq(0, 1.5e+7, 5e+6),
                     labels = \(x) x / 1e+4) +
  coord_flip() +
  theme_classic(base_family = jp_font)

都道府県名のラベルと、横軸の0との間の隙間が気になるので、ここを詰めるようにします。これには、scale_y_continuous関数で、expand = expansion(mult = c(0, 0.05))と指定します。

pref_data2 |>
  dplyr::filter(`地域` != "全国", `男女` == "総数", `` == 2020) |>
  ggplot(aes(x = `地域`, y = `人口`)) +
  geom_col() +
  scale_x_discrete(name = "都道府県", limits = rev) +
  scale_y_continuous(name = "人口(万人)",
                     limits = c(0, 1.5e+7),
                     breaks = seq(0, 1.5e+7, 5e+6),
                     labels = \(x) x / 1e+4,
                     expand = expansion(mult = c(0, 0.05))) +
  coord_flip() +
  theme_classic(base_family = jp_font)

男女別の積み上げグラフにします。これには、geom_col関数の引数でposition = "stack"とします(実はデフォルトです)。また、scale_fill_manual(values = c("#005aff", "#ff4b00"))で色も指定します。

pref_data2 |>
  dplyr::filter(`地域` != "全国", `男女` != "総数", `` == 2020) |>
  ggplot(aes(x = `地域`, y = `人口`, fill = `男女`)) +
  geom_col(position = "stack") +
  scale_fill_manual(values = c("#005aff", "#ff4b00")) +
  scale_x_discrete(name = "都道府県", limits = rev) +
  scale_y_continuous(name = "人口(万人)",
                     limits = c(0, 1.5e+7),
                     breaks = seq(0, 1.5e+7, 5e+6),
                     labels = \(x) x / 1e+4,
                     expand = expansion(mult = c(0, 0.05))) +
  coord_flip() +
  theme_classic(base_family = jp_font)

地理空間データの読み込み

地理空間データもRで読み込んで使用することができます。この項では、国土数値情報行政区域データから石川県のデータをダウンロードして使用します。

シェープファイル

シェープファイルは複数のファイルから校正されています。sfパッケージのst_read関数でN03-20240101_17.shpを指定して読み込みます。

library(sf)

shapefile <- file.path("data", "N03-20240101_17.shp")
data_s <- st_read(shapefile)

読み込んだデータを表示します。

N03_002は北海道の振興局名、N03_003は郡名、N03_005は政令指定都市の行政区名なので、金沢市の行ではすべて欠損値(NA)になっています。

print(data_s)
Simple feature collection with 1710 features and 6 fields
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: 136.242 ymin: 36.06723 xmax: 137.3653 ymax: 37.85791
Geodetic CRS:  JGD2011
First 10 features:
   N03_001 N03_002 N03_003 N03_004 N03_005 N03_007
1   石川県    <NA>    <NA>  金沢市    <NA>   17201
2   石川県    <NA>    <NA>  金沢市    <NA>   17201
3   石川県    <NA>    <NA>  金沢市    <NA>   17201
4   石川県    <NA>    <NA>  金沢市    <NA>   17201
5   石川県    <NA>    <NA>  金沢市    <NA>   17201
6   石川県    <NA>    <NA>  金沢市    <NA>   17201
7   石川県    <NA>    <NA>  金沢市    <NA>   17201
8   石川県    <NA>    <NA>  金沢市    <NA>   17201
9   石川県    <NA>    <NA>  七尾市    <NA>   17202
10  石川県    <NA>    <NA>  七尾市    <NA>   17202
                         geometry
1  POLYGON ((136.6133 36.49857...
2  POLYGON ((136.5991 36.62053...
3  POLYGON ((136.5967 36.61824...
4  POLYGON ((136.5974 36.6189,...
5  POLYGON ((136.5958 36.61709...
6  POLYGON ((136.5943 36.61553...
7  POLYGON ((136.5952 36.61667...
8  POLYGON ((136.5992 36.62078...
9  POLYGON ((136.8624 37.08288...
10 POLYGON ((136.9981 37.11807...

GeoJSON

シェープファイルは複数のファイルに分かれていて、あつかいがやや煩雑なので、最近はGeoJSONファイルが使われることも多くなってきています。GeoJSONファイルもst_read関数で読むことができます。

jsonfile <- file.path("data", "N03-20240101_17.geojson")
data_g <- st_read(jsonfile)

こちらも表示します。

print(data_g)
Simple feature collection with 1710 features and 6 fields
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: 136.242 ymin: 36.06723 xmax: 137.3653 ymax: 37.85791
Geodetic CRS:  WGS 84
First 10 features:
   N03_001 N03_002 N03_003 N03_004 N03_005 N03_007
1   石川県    <NA>    <NA>  金沢市    <NA>   17201
2   石川県    <NA>    <NA>  金沢市    <NA>   17201
3   石川県    <NA>    <NA>  金沢市    <NA>   17201
4   石川県    <NA>    <NA>  金沢市    <NA>   17201
5   石川県    <NA>    <NA>  金沢市    <NA>   17201
6   石川県    <NA>    <NA>  金沢市    <NA>   17201
7   石川県    <NA>    <NA>  金沢市    <NA>   17201
8   石川県    <NA>    <NA>  金沢市    <NA>   17201
9   石川県    <NA>    <NA>  七尾市    <NA>   17202
10  石川県    <NA>    <NA>  七尾市    <NA>   17202
                         geometry
1  POLYGON ((136.6133 36.49857...
2  POLYGON ((136.5991 36.62053...
3  POLYGON ((136.5967 36.61824...
4  POLYGON ((136.5974 36.6189,...
5  POLYGON ((136.5958 36.61709...
6  POLYGON ((136.5943 36.61553...
7  POLYGON ((136.5952 36.61667...
8  POLYGON ((136.5992 36.62078...
9  POLYGON ((136.8624 37.08288...
10 POLYGON ((136.9981 37.11807...

シェープファイルから読み込んだものと、GeoJSONから読み込んだものでは、なぜか座標参照系(CRS)が異なっている(前者がJGD2011、後者がWGS84)のですが、実用的には問題はないでしょう。

st_crs(data_s)
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]]
st_crs(data_g)
Coordinate Reference System:
  User input: WGS 84 
  wkt:
GEOGCRS["WGS 84",
    DATUM["World Geodetic System 1984",
        ELLIPSOID["WGS 84",6378137,298.257223563,
            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]],
    ID["EPSG",4326]]

できたデータのdata_gのクラスを確認しています。sfクラス(と、data.frameクラス)に属していることがわかります。

class(data_g)
[1] "sf"         "data.frame"

地理空間データの可視化

上で読み込んだデータをggplot2のgeom_sf関数で表示してみます。

ggplot(data_g) +
  geom_sf()

この地図に、市区町村名を重ねて表示します。

そのためまず、データに含まれるポリゴンを市町村ごとにst_combine関数でまとめます。また、わかりやすいように、市区町村名のフィールドのN03_004を、nameという名前に変えておきました。

data <- data_g |>
  dplyr::group_by(N03_004) |>
  dplyr::summarise(geometry = st_combine(geometry)) |>
  dplyr::ungroup() |>
  dplyr::rename(name = N03_004)

各市区町村名を地図に重ねて表示します。

ggplot(data) +
  geom_sf() +
  geom_sf_text(aes(label = name), size = 2.5, family = jp_font) +
  scale_x_continuous(breaks = seq(136.5, 137.5, 0.5)) +
  labs(x = "経度", y = "緯度") +
  theme_bw(base_family = jp_font)

コロプレス図(塗り分け地図)

2020年の総人口データを使って、各市区町村を塗り分けてみます。

まず、各市区町村の総人口を読み込みます。このデータはe-stat 都道府県・市区町村のすがた(社会・人口統計体系)からダウンロードしたものです。

読み込んだ後、市区町村名の先頭についている都道府県名を削除し(実際には空白より後だけ残す処理)、2020年度のデータだけを抽出します。

pop_data_file <- file.path("data", "FEI_CITY_241027082628.csv")
pop_data <- read_csv(pop_data_file, skip = 1,
                     col_types = "cc_n",
                     col_names = c("year", "name", "population")) |>
  dplyr::mutate(name = str_sub(name, str_locate(name, " ")[1] + 1)) |>
  dplyr::filter(year == "2020年度")

人口データを地理空間データに結合します。left_joinは、by引数の変数をキーとして、左側のデータ(この例ではdata)を保存しつつ、右側のデータ(この例ではpop_data)から共通のキーをもつ行を結合するという関数です。

(この例では両方のデータが1対1対応するので、left_joinでもright_joinでも結果は変わりません。)

data_join <- dplyr::left_join(data, pop_data, by = "name")

2020年の総人口データを色で表現して、地図化しました。総人口は対数スケールにしています。

ggplot(data_join) +
  geom_sf(aes(fill = population)) +
  geom_sf_text(aes(label = name), size = 2.5, family = jp_font) +
  scale_x_continuous(breaks = seq(136.5, 137.5, 0.5)) +
  scale_fill_gradient(name = "人口",
                      low = "#4dc4ff",
                      high = "#ff4b00",
                      transform = "log",
                      limits = c(5e+3, 5e+5),
                      breaks = c(5e+3, 1e+4, 5e+4, 1e+5, 5e+5),
                      labels = c("5000", "1万", "5万",
                                 "10万", "50万")) +
  labs(x = NULL, y = NULL) +
  theme_bw(base_family = jp_font)