政府統計e-Stat APIをプログラミング言語「R(アール)」で使ってみた
総務省が2020年8月5日に公表した人口動態調査によれば、2020年1月時点における東京圏(東京都、埼玉県、千葉県、神奈川県)の人口は、前年比で0.37%増加したことが分かった。
同調査は2020年1月1日時点におけるものであるため、COVID-19の影響はほとんど反映されていないとみられる。都市への人口の集中は「規模の経済」や「集積の経済」を発生させ、人や企業のネットワークなどがイノベーションの原動力となる。また、エンリコ・モレッティ氏の著書『年収は「住むところ」で決まる』にあるように、雇用を求めて都市へ人が移動することで地域が活性化することもある。一方で、これからはCOVID-19の影響によってリモートワークが一般的になり、リチャード・ボールドウィン氏の著書『GLOBOTICS』にある「遠隔移民」のように、国境や地域を超えて働くことが増えることも考えられる。
今後、東京圏や他の都市圏への人口集中のトレンドが変わることはあるのか。直近のデータでは、東京都の人口は転出超過になっているとのことだ(「東京都の人口、7月は再び転出超」『日本経済新聞』2020年8月28日)。本文では政府統計e-Stat APIを使用して、人口増減率のデータを調べてみることとしたい。
(´-`).。oO(イントロダクションでは人口について述べましたが、本文はe-Stat APIを使用してみることが本題である。)
1 e-Stat APIを使用してみる
1.1 e-Stat APIを使う準備をする
まず、e-Statのホームページからユーザ登録およびe-Stat APIを使用するためのアプリケーションIDの発行を行う。
今回は石田基広氏らの著書『Rによるスクレイピング入門』第5章API実践にあるe-Statのセクションを参考に、プログラミング言語「R(アール)」を利用してe-Stat APIを使用してみることにする。
1.2 プログラミング言語「R(アール)」でe-Stat APIを使用する
『Rによるスクレイピング入門』では「人口推計 平成26年10月1日現在人口推計」という統計データを対象にしていたが、本文では「2019年10月1日現在人口推計 都道府県別人口増減率-総人口」という統計データを対象にして、e-Stat APIを使用してみる(Rにおけるコードは同書に倣っています)。
まず、統計データを取得してみる。
library(httr)
appId <- "XXXX" # appIdを指定
res <- GET(
url = "http://api.e-stat.go.jp/rest/2.1/app/json/getStatsData",
query = list(
appId = appId,
statsDataId = "0003412319"
)
)
# 結果の取得
result <- content(res)
str(result, max.level = 4, list.len = 4)
List of 1
$ GET_STATS_DATA:List of 3
..$ RESULT :List of 3
.. ..$ STATUS : int 0
.. ..$ ERROR_MSG: chr "正常に終了しました。"
.. ..$ DATE : chr "2020-08-29T12:48:28.028+09:00"
..$ PARAMETER :List of 5
.. ..$ LANG : chr "J"
.. ..$ STATS_DATA_ID : chr "0003412319"
.. ..$ DATA_FORMAT : chr "J"
.. ..$ START_POSITION: int 1
.. .. [list output truncated]
..$ STATISTICAL_DATA:List of 4
.. ..$ RESULT_INF:List of 3
.. .. ..$ TOTAL_NUMBER: int 240
.. .. ..$ FROM_NUMBER : int 1
.. .. ..$ TO_NUMBER : int 240
.. ..$ TABLE_INF :List of 15
.. .. ..$ @id : chr "0003412319"
.. .. ..$ STAT_NAME :List of 2
.. .. ..$ GOV_ORG :List of 2
.. .. ..$ STATISTICS_NAME : chr "人口推計 2019年10月1日現在人口推計"
.. .. .. [list output truncated]
.. ..$ CLASS_INF :List of 1
.. .. ..$ CLASS_OBJ:List of 3
.. ..$ DATA_INF :List of 2
.. .. ..$ NOTE :List of 2
.. .. ..$ VALUE:List of 240
CLASS_INFというのがメタ情報、DATA_INFというのが統計データ本体とのことだ。そして、DATA_INFの具体的な値は、その下のVALUEに入っている。それでは、VALUEの具体的な中身を確認してみよう。
statistical_data <- result$GET_STATS_DATA$STATISTICAL_DATA
str(statistical_data$DATA_INF$VALUE[[1]])
List of 5
$ @tab : chr "004"
$ @area: chr "00000"
$ @time: chr "2014001011"
$ @unit: chr "千人比,‰"
$ $ : chr "-1.1"
都道府県別人口増減率のデータを取得したため、@areaは「都道府県」、@timeは「期間」を表しているのではないかということは何となく推測できる。この数字が何を表しているかは、メタ情報CLASS_INFに書かれているとのことだ。それでは、CLASS_INFの中にある"area"という列のメタ情報を確認してみることとする。
str(statistical_data$CLASS_INF$CLASS_OBJ[[2]])
List of 3
$ @id : chr "area"
$ @name: chr "全国・都道府県"
$ CLASS:List of 48
..$ :List of 3
.. ..$ @code : chr "00000"
.. ..$ @name : chr "全国"
.. ..$ @level: chr "1"
..$ :List of 3
.. ..$ @code : chr "01000"
.. ..$ @name : chr "北海道"
.. ..$ @level: chr "2"
..$ :List of 3
.. ..$ @code : chr "02000"
.. ..$ @name : chr "青森県"
.. ..$ @level: chr "2"
『Rによるスクレイピング入門』を参考に、さらにデータ処理を行っていく。続いて、同じ要素を持った複数のリストをデータフレームに変換してみる。
do.call(rbind, statistical_data$CLASS_INF$CLASS_OBJ[[2]]$CLASS)
@code @name @level
[1,] "00000" "全国" "1"
[2,] "01000" "北海道" "2"
[3,] "02000" "青森県" "2"
[4,] "03000" "岩手県" "2"
[5,] "04000" "宮城県" "2"
do.call(rbind, statistical_data$CLASS_INF$CLASS_OBJ[[1]]$CLASS)
[,1]
@code "004"
@name "人口増減率"
@level ""
@unit "千人比,‰"
$CLASS_OBJ[[1]]と$CLASS_OBJ[[2]]は少し構造が異なっている。str()を使って、それぞれのCLASS要素の構造を調べてみる。
str(statistical_data$CLASS_INF$CLASS_OBJ[[2]]$CLASS)
List of 48
$ :List of 3
..$ @code : chr "00000"
..$ @name : chr "全国"
..$ @level: chr "1"
$ :List of 3
..$ @code : chr "01000"
..$ @name : chr "北海道"
..$ @level: chr "2"
$ :List of 3
..$ @code : chr "02000"
..$ @name : chr "青森県"
..$ @level: chr "2"
str(statistical_data$CLASS_INF$CLASS_OBJ[[1]]$CLASS)
List of 4
$ @code : chr "004"
$ @name : chr "人口増減率"
$ @level: chr ""
$ @unit : chr "千人比,‰"
確認してみると、$CLASS_OBJ[[2]]ではCLASS要素の下にさらに複数のリストが含まれており、それぞれのリストが1つの水準(code)の説明になっている。すなわち、リストがリストの中にネストされた状態となっている。このようなネストしたリストは、dplyrパッケージのbind_rows()で扱うことが出来る。
library(dplyr)
bind_rows(statistical_data$CLASS_INF$CLASS_OBJ[[2]]$CLASS)
# A tibble: 48 x 3
`@code` `@name` `@level`
<chr> <chr> <chr>
1 00000 全国 1
2 01000 北海道 2
3 02000 青森県 2
4 03000 岩手県 2
bind_rows(statistical_data$CLASS_INF$CLASS_OBJ[[1]]$CLASS)
# A tibble: 1 x 4
`@code` `@name` `@level` `@unit`
<chr> <chr> <chr> <chr>
1 004 人口増減率 "" 千人比,‰
続いて、統計データを取り出してみる。
data_df <- bind_rows(statistical_data$DATA_INF$VALUE)
data_df
# A tibble: 240 x 5
`@tab` `@area` `@time` `@unit` `$`
<chr> <chr> <chr> <chr> <chr>
1 004 00000 2014001011 千人比,‰ -1.1
2 004 00000 2015001011 千人比,‰ -1.3
3 004 00000 2016001011 千人比,‰ -1.8
4 004 00000 2017001011 千人比,‰ -2.1
5 004 00000 2018001011 千人比,‰ -2.2
6 004 01000 2014001011 千人比,‰ -5.3
7 004 01000 2015001011 千人比,‰ -5.6
次に、メタ情報を取り出してみる。
meta_info <- statistical_data$CLASS_INF$CLASS_OBJ %>%
lapply(function(i){
i$CLASS <- bind_rows(i$CLASS)
i
})
meta_info[[2]]
$`@id`
[1] "area"
$`@name`
[1] "全国・都道府県"
$CLASS
# A tibble: 48 x 3
`@code` `@name` `@level`
<chr> <chr> <chr>
1 00000 全国 1
2 01000 北海道 2
3 02000 青森県 2
各カテゴリのメタ情報を統計データの列名と同じ名前にしてみる。
mids <- sapply(meta_info, function(x)x$`@id`)
mids
[1] "tab" "area" "time"
names(meta_info) <- paste0("@", mids)
次に、統計データとメタ情報を紐づける。
まず、統計データdata_dfの@area列にメタ情報を紐づけてみる。
meta_info_area <- meta_info[["@area"]]
$`@id`
[1] "area"
$`@name`
[1] "全国・都道府県"
$CLASS
# A tibble: 48 x 3
`@code` `@name` `@level`
<chr> <chr> <chr>
1 00000 全国 1
2 01000 北海道 2
3 02000 青森県 2
meta_info_areaのCLASS要素には@code(水準を表すコード)と@name(水準のラベル)の対応情報が入っている。これをdata_dfの@areaに入ってるコードの羅列に紐づける。
area_factor <- factor(data_df[["@area"]],
levels = meta_info_area$CLASS$`@code`,
labels = meta_info_area$CLASS$`@name`)
head(area_factor)
[1] 全国 全国 全国 全国 全国 北海道
48 Levels: 全国 北海道 青森県 岩手県 宮城県 ... 沖縄県
紐づけが終わったデータを元のdata_dfの@area列に格納する。
data_df[, "@area"] <- area_factor
meta_infoの他の要素についてもdata_dfに紐づけてみる。
meta_inf_wo_area <- meta_info[names(meta_info) != "@area"]
for(colname in names(meta_inf_wo_area)){
m <- meta_info[[colname]]
data_df[, colname] <- factor(data_df[[colname]],
levels = m$CLASS$`@code`,
labels = m$CLASS$`@name`)
}
また、@areaといった列名を、メタ情報の@nameに置き換えてみる。
mids <- names(meta_info)
mnames <- sapply(meta_info, function(x)x$`@name`)
mnames
@tab @area @time
"表章項目" "全国・都道府県" "時間軸(年間)"
names(data_df)[match(mids, names(data_df))] <- mnames
data_df
# A tibble: 240 x 5
表章項目 `全国・都道府県` `時間軸(年間)` `@unit` `$`
<fct> <fct> <fct> <chr> <chr>
1 人口増減率~ 全国 2014年10月~2015年9~ 千人比,‰~ -1.1
2 人口増減率~ 全国 2015年10月~2016年9~ 千人比,‰~ -1.3
3 人口増減率~ 全国 2016年10月~2017年9~ 千人比,‰~ -1.8
4 人口増減率~ 全国 2017年10月~2018年9~ 千人比,‰~ -2.1
5 人口増減率~ 全国 2018年10月~2019年9~ 千人比,‰~ -2.2
6 人口増減率~ 北海道 2014年10月~2015年9~ 千人比,‰~ -5.3
これでメタ情報が紐づけられた統計データが完成である。
『Rによるスクレイピング入門』を参考に、初めてe-Stat APIを使用してみましたが、これでグラフによる可視化まで出来そうだ。
1.3 e-Stat APIを使用して作成したデータを可視化してみる
それでは、1.2で作成したデータを使って都道府県別の人口増減率を可視化してみる。ここではggplot2パッケージを利用する。
library(ggplot2)
`全国・都道府県`は全国を除き、`時間軸(年間)`は2018年10月~2019年9月に絞り込むこととする(なお、`$`の列が人口増減率のデータであるが、文字列になっているため数値型に変換しておく)。
data_201810_201909 <- data_df %>%
filter(
`全国・都道府県` != "全国",
`時間軸(年間)` == "2018年10月~2019年9月"
) %>%
mutate(`人口増減率` = as.integer(`$`))
data_201810_201909
# A tibble: 47 x 6
表章項目 `全国・都道府県` `時間軸(年間)` `@unit` `$`
<fct> <fct> <fct> <chr> <chr>
1 人口増減率~ 北海道 2018年10月~2019年9~ 千人比,‰~ -6.8
2 人口増減率~ 青森県 2018年10月~2019年9~ 千人比,‰~ -13.1
3 人口増減率~ 岩手県 2018年10月~2019年9~ 千人比,‰~ -11.2
4 人口増減率~ 宮城県 2018年10月~2019年9~ 千人比,‰~ -4.0
5 人口増減率~ 秋田県 2018年10月~2019年9~ 千人比,‰~ -14.
それでは、このデータを可視化してみる。
ggplot(data_201810_201909, aes(x = `全国・都道府県`, `人口増減率`)) +
geom_point() +
geom_abline(intercept = 0, slope = 0, linetype = 2) +
theme(axis.text.x = element_text(angle = -45, hjust = 0))
可視化したグラフが下図である。
グラフを確認すると、人口を維持または増加している都道府県は東京都や愛知県、沖縄県などわずかに留まっている。
(´-`).。oO(色分けされた統計地図(コロプレス図)を作成できればよかったが、e-Stat APIを使用したコロプレス図による可視化は、今後の課題としたい。)
2 おわりに
プログラミング言語「R(アール)」でe-Stat APIを使ってみるという今回の課題は、なんとか達成することが出来た。
今後はe-Stat APIだけでなく、地域経済分析システムRESAS APIなども使いたいと考えている。
とりあえず、理論や実証等の勉強はしつつ、RやPythonを利用したnoteの投稿もしていきたい。
【参考文献】
石田基広、市川太祐、瓜生真也、湯谷啓明『Rによるスクレイピング入門』シーアンドアール研究所、2017年。
この記事が気に入ったらサポートをしてみませんか?