政府統計総合窓口e-Statの次世代統計利用システムから消費者物価指数データを取得する

最近野菜が高騰しているらしいです。
たとえばキャベツ、レタス、白菜が400円なんだとか。
これをe-Statから取得した物価指数で分析してみようと思いました。
以前物価指数のデータを取得して分析したときは分析データをe-Statから直接csvとしてダウンロードしましたが、最近読んだ本にAPIでe-Statに接続する手法が紹介されていたのでこれを使ってみます。

APIでデータを取得できればマウス操作やコピペ無しにプログラミングだけで分析が完結するので、分析の再現性が格段にアップします。
もし2年後上司に「あの分析もう一回教えて」と言われても慌てずに対応できそうですね。

野菜の価格推移。確かに2017年12月のほうれん草とレタスの価格上昇が高い

【e-Stat API】

e-Statが次世代統計利用システムとしてAPIの本格運用を始めたのは2014年10月31日。
このシステムを使えばe-Statが持つ統計データをウェブAPIを通してXMLやJSONとして取得できます。
たくさんの税金をかけてこのようなすばらしいシステムを作ってくれているのだから利用しない手はありません。

APIの使い方 | 政府統計の総合窓口(e-Stat)−API機能

【e-Stat APIアプリケーションID取得】

まずはじめにe-Statのユーザ登録を行い、『アプリケーションID』なるものを取得します。
この取得が少し分かりにくくて地味に時間がかかったのでここに手順を説明します。

step1 ユーザ登録

ユーザ登録 | 政府統計の総合窓口
上記リンクからメールアドレスを登録してユーザ登録します。
上記リンクからできるのは仮登録です。メールの案内にしたがって本登録もしてください。

step2 ログイン

ログイン | 政府統計の総合窓口
上記リンクに設定したメールアドレスとパスワードを入力してログインしてください

step3 アプリケーションIDの発行

  1. e-Statトップページから『マイページ』を押してください。
  2. 上のやや左側にある『API機能(アプリケーションID発行)』を押してください
  3. 『名称』『URL』『概要』すべて適当に入力して右側の『発行』ボタンを押してください

これでappIdにIDっぽい文字列が表示されたはずです。
これがあなたのe-StatのアプリケーションIDです。

e-StatのappId表示画面。黒く塗りつぶしている箇所にappIdが表示されている

【消費者物価指数データ】

e-Stat APIでのデータ取得はstatsDataIdというIDで取得するデータを設定します。
まずはe-StatのサイトからstatsDataIdを特定しましょう。

今回分析したいのは『消費者物価指数』です。
e-Statトップページの『キーワードで探す』のフォームから『消費者物価指数』を検索すれば次のデータが見つかりました。

2015年基準消費者物価指数

このページのAPIのボタンを押せば、APIでデータを取得するためのURLが表示されます。
この中にstatsDataId=0003143513という文字列があります。これがstatsDataIdです。

これでAPIでデータを取得する準備が整いました。

【estatapiで消費者物価データを取得】

さて、私はRで分析したいので、Rを使ってapiを通じてデータを取得したいです。
最も単純にはAPIの仕様に従ってライブラリhttrでGETを投げれば統計データのJSONを取得することができます。
しかし微妙に面倒なそこらへんの処理をいい感じにショートカットしてくれるestatapiというライブラリが存在するので今回はこれを使います。

estatapi – 政府統計の総合窓口(e-Stat)のAPIを使うためのRパッケージ

#R
install.packages("estatapi")
library(estatapi)

自分のアプリケーションIDと、対象データのstatsDataIdがあれば関数estat_getStatsDataを使ってデータを取得することができます。
しかし下記のコード、実行はしないでください。

#R
appId <- "あなたのアプリケーションID"
bukkaId <- "0003143513"

# 次のコードは実行しないで!
result <- estat_getStatsData(appId = appId, statsDataId = bukkaId)

上のコードをそのまま実行するとデータサイズが広すぎておそらくかなり取得時間がかかると思います。

これを避けるためには我々が必要な条件で絞り込んでデータを取得しなければなりません。
データの絞り込み条件は次のe-Stat公式ページを参考にしました。
表彰事項、時間軸事項、地域事項、分類事項の条件で絞り込んでデータ取得できるようです。

APIの使い方 3.4 統計データ取得

絞り込みの具体的な条件はメタデータを見て確認することができます。
メタデータはestatapiの関数estat_getMetaInfoで取得できます。

#R
meta <- estat_getMetaInfo(appId = appId, statsDataId = bukkaId)

library(dplyr)
meta %>% glimpse
#List of 5
# $ tab   :Classes ‘tbl_df’, ‘tbl’ and 'data.frame':     5 obs. of  4 variables:
#  ..$ @code : chr [1:5] "1" "2" "3" "4" ...
#  ..$ @name : chr [1:5] "指数" "前月比・前年比・前年度比" "前年同月比" "ウエイト(実数)" ...
#  ..$ @level: chr [1:5] "" "" "" "" ...
#  ..$ @unit : chr [1:5] NA "%" "%" NA ...
# $ cat01 :Classes ‘tbl_df’, ‘tbl’ and 'data.frame':     798 obs. of  4 variables:
#  ..$ @code      : chr [1:798] "0001" "0002" "0003" "0004" ...
#  ..$ @name      : chr [1:798] "0001 総合" "0002 食料" "0003 穀類" "0004 米類" ...
#  ..$ @level     : chr [1:798] "1" "1" "3" "5" ...
#  ..$ @parentCode: chr [1:798] NA NA "0002" "0003" ...
# $ area  :Classes ‘tbl_df’, ‘tbl’ and 'data.frame':     72 obs. of  3 variables:
#  ..$ @code : chr [1:72] "13A01" "00000" "00011" "00012" ...
#  ..$ @name : chr [1:72] "13100 東京都区部" "全国" "人口5万以上の市" "大都市" ...
#  ..$ @level: chr [1:72] "1" "1" "1" "1" ...
# $ time  :Classes ‘tbl_df’, ‘tbl’ and 'data.frame':     672 obs. of  4 variables:
#  ..$ @code      : chr [1:672] "2018000101" "2017001212" "2017001111" "2017001010" ...
#  ..$ @name      : chr [1:672] "2018年1月" "2017年12月" "2017年11月" "2017年10月" ...
#  ..$ @level     : chr [1:672] "4" "4" "4" "4" ...
#  ..$ @parentCode: chr [1:672] "2018000103" "2017001012" "2017001012" "2017001012" ...
# $ .names:Classes ‘tbl_df’, ‘tbl’ and 'data.frame':     4 obs. of  2 variables:
#  ..$ id  : chr [1:4] "tab" "cat01" "area" "time"
#  ..$ name: chr [1:4] "表章項目" "2015年基準品目" "地域(2015年基準)" "時間軸(年・月)"

上記の絞り込み項目との対応はtabが表彰事項、cat01が分類事項01、areaが地域事項、timeが時間軸事項、になっているようです。
一つずつ見ていきましょう。

まずはtab表彰事項です。

#R
meta$tab
## A tibble: 5 x 4
#  `@code`                  `@name` `@level` `@unit`
#    <chr>                    <chr>    <chr>   <chr>
#1       1                     指数             <NA>
#2       2 前月比・前年比・前年度比                %
#3       3               前年同月比                %
#4       4         ウエイト(実数)             <NA>
#5       5       ウエイト(万分比)             <NA>

表彰事項は取得したい値の種類です。
今回は加工されていない指数そのものを使うことにしますのでコードは"1"です。

#R
cdTab.sisu <- "1"

次はcat01分類事項01。

#R
metacat01
## A tibble: 798 x 4
#   `@code`         `@name` `@level` `@parentCode`
#     <chr>           <chr>    <chr>         <chr>
# 1    0001       0001 総合        1          <NA>
# 2    0002       0002 食料        1          <NA>
# 3    0003       0003 穀類        3          0002
# 4    0004       0004 米類        5          0003
# 5    1000   1000 うるち米        6          0004
# 6    1001 1001 うるち米A        7          1000
# 7    1002 1002 うるち米B        7          1000
# 8    1011     1011 もち米        6          0004
# 9    0005       0005 パン        5          0003
#10    1021     1021 食パン        6          0005
## ... with 788 more rows

分類事項01は物価の対象品目です。
今回は野菜の物価を調べたいので対象となるコードを次のように調べていきました。

#R
#まず一番上の階層をみる
meta$cat01 %>% filter(`@level` == "1")
## A tibble: 50 x 4
#   `@code`             `@name` `@level` `@parentCode`
#     <chr>               <chr>    <chr>         <chr>
# 1    0001           0001 総合        1          <NA>
# 2    0002           0002 食料        1          <NA>
# 3    0045           0045 住居        1          <NA>
# 4    0054     0054 光熱・水道        1          <NA>
# 5    0060 0060 家具・家事用品        1          <NA>
# 6    0082   0082 被服及び履物        1          <NA>
# 7    0107       0107 保健医療        1          <NA>
# 8    0111     0111 交通・通信        1          <NA>
# 9    0118           0118 教育        1          <NA>
#10    0122       0122 教養娯楽        1          <NA>
## ... with 40 more rows

# コード0002『食料』の下にあるような気がするので、parentCodeで絞り込んでみる
meta$cat01 %>% filter(`@parentCode` == "0002")
## A tibble: 12 x 4
#   `@code`           `@name` `@level` `@parentCode`
#     <chr>             <chr>    <chr>         <chr>
# 1    0003         0003 穀類        3          0002
# 2    0008       0008 魚介類        3          0002
# 3    0013         0013 肉類        3          0002
# 4    0016       0016 乳卵類        3          0002
# 5    0021   0021 野菜・海藻        3          0002
# 6    0027         0027 果物        3          0002
# 7    0030 0030 油脂・調味料        3          0002
# 8    0033       0033 菓子類        3          0002
# 9    0034     0034 調理食品        3          0002
#10    0037         0037 飲料        3          0002
#11    0041         0041 酒類        3          0002
#12    0042         0042 外食        3          0002

# コード0021『野菜・海藻』の下にあるような気がするので、parentCodeで絞り込んでみる
meta$cat01 %>% filter(`@parentCode` == "0021")
## A tibble: 2 x 4
#  `@code`             `@name` `@level` `@parentCode`
#    <chr>               <chr>    <chr>         <chr>
#1    0022       0022 生鮮野菜        4          0021
#2    0023 0023 乾物・加工品類        4          0021

# コード0022『生鮮野菜』の下にあるような気がするのでparentCodeでしぼりこんでみる
meta$cat01 %>% filter(`@parentCode` == "0022")
## A tibble: 30 x 4
#   `@code`           `@name` `@level` `@parentCode`
#     <chr>             <chr>    <chr>         <chr>
# 1    1401     1401 キャベツ        6          0022
# 2    1402 1402 ほうれんそう        6          0022
# 3    1403     1403 はくさい        6          0022
# 4    1405         1405 ねぎ        6          0022
# 5    1406       1406 レタス        6          0022
# 6    1409 1409 ブロッコリー        6          0022
# 7    1407       1407 もやし        6          0022
# 8    1410 1410 アスパラガス        6          0022
# 9    1411   1411 さつまいも        6          0022
#10    1412   1412 じゃがいも        6          0022
## ... with 20 more rows

# これが求めるコードの列なので保存しておく。
cdCat01.yasai <- meta$cat01 %>% filter(`@parentCode` == "0022") %>% pull(`@code`)

次にarea地域事項

#R
meta$area
## A tibble: 72 x 3
#   `@code`          `@name` `@level`
#     <chr>            <chr>    <chr>
# 1   13A01 13100 東京都区部        1
# 2   00000             全国        1
# 3   00011 人口5万以上の市        1
# 4   00012           大都市        1
# 5   00013           中都市        1
# 6   00018         小都市A        1
# 7   00021   小都市B・町村        1
# 8   00042       北海道地方        1
# 9   00043         東北地方        1
#10   00044         関東地方        1
## ... with 62 more rows

これはコード00000全国でいいでしょう。

#R
cdArea.zenkoku <- "00000"

次にtime時間軸事項

#R
meta$time
## A tibble: 672 x 4
#      `@code`    `@name` `@level` `@parentCode`
#        <chr>      <chr>    <chr>         <chr>
# 1 2018000101  2018年1月        4    2018000103
# 2 2017001212 2017年12月        4    2017001012
# 3 2017001111 2017年11月        4    2017001012
# 4 2017001010 2017年10月        4    2017001012
# 5 2017000909  2017年9月        4    2017000709
# 6 2017000808  2017年8月        4    2017000709
# 7 2017000707  2017年7月        4    2017000709
# 8 2017000606  2017年6月        4    2017000406
# 9 2017000505  2017年5月        4    2017000406
#10 2017000404  2017年4月        4    2017000406
## ... with 662 more rows

なんとなく2010年以降を取ることにします。
先程のAPIの使い方 3.4 統計データ取得でcdTimeFromを指定すればその時期以降が取れそうな気がするので、このパラメータを使います。
また欲しいのは年月データのみなのでlevel=4を指定します。

#R
cdTimeFrom <- "2010000101"
lvTime <- "4"

これで絞り込み条件が定まりました。
estat_getStatsDataを使ってデータを取得しましょう!

#R
result <- estat_getStatsData(
                            appId,
                            statsDataId = bukka_id,
                            cdTab = cdTab.sisu,
                            cdCat01 = cdCat01.yasai,
                            cdArea = cdArea.zenkoku,
                            cdTimeFrom = cdTimeFrom,
                            lvTime = lvTime
                            )
result
## A tibble: 2,804 x 9
#   tab_code 表章項目 cat01_code `2015年基準品目` area_code `地域(2015年基準)`  time_code `時間軸(年・月)` value
#      <chr>    <chr>      <chr>            <chr>     <chr>                <chr>      <chr>              <chr> <dbl>
# 1        1     指数       1401    1401 キャベツ     00000                 全国 2017001212         2017年12月 120.0
# 2        1     指数       1401    1401 キャベツ     00000                 全国 2017001111         2017年11月  92.3
# 3        1     指数       1401    1401 キャベツ     00000                 全国 2017001010         2017年10月  70.9
# 4        1     指数       1401    1401 キャベツ     00000                 全国 2017000909          2017年9月  84.8
# 5        1     指数       1401    1401 キャベツ     00000                 全国 2017000808          2017年8月  68.2
# 6        1     指数       1401    1401 キャベツ     00000                 全国 2017000707          2017年7月  69.2
# 7        1     指数       1401    1401 キャベツ     00000                 全国 2017000606          2017年6月  75.3
# 8        1     指数       1401    1401 キャベツ     00000                 全国 2017000505          2017年5月  99.9
# 9        1     指数       1401    1401 キャベツ     00000                 全国 2017000404          2017年4月 112.3
#10        1     指数       1401    1401 キャベツ     00000                 全国 2017000303          2017年3月 104.4
## ... with 3,794 more rows

library(lubridate)
library(stringr)
hamono <- result %>%
   rename(hinmoku = `2015年基準品目`) %>%
   mutate(ym = make_date(str_sub(time_code, end = 4), str_sub(time_code, start = -2), 1)) %>%
   mutate(month = month(ym, label = TRUE, abbr = TRUE), year = year(ym)) %>%
   filter(`cat01_code` %in% c("1401", "1402", "1403", "1405", "1406"))

library(ggplot2)
hamono %>%
   mutate(year = factor(year)) %>%
   ggplot(aes(month, value)) +
     geom_point(aes(color = year, shape = year)) +
     facet_wrap(~hinmoku) +
     scale_shape_manual(values = 1:8)
葉物野菜の価格推移。確かに2017年12月のほうれん草とレタスの価格上昇は異常に見える

野菜は季節変動が激しいので季節ごとに時間変化を見れるようにしました。
これを見る限り、たしかに2017年12月のレタスの価格はひどい。通常時の2倍近く値上がりしています。
ほうれん草も少し高めです。
そして思ったより白菜、ネギ、レタスは大したこと無いです。

【まとめ】

Rのライブラリestatapiを使って消費者物価指数を取得し、葉物野菜の物価動向を調べることができました。
今回はデータを取得するところに時間を割いてしまったためとても分析と言えるようなことはできなかったので、そのうち別の記事で細かい分析をやってみたいです。
またstatsDataId=0003105586小売物価統計調査では実際の価格を『市』ごとに見ることができるようです。
こっちを調べるともっと深く調べていけるかもしれません。

しかしこうやって政府統計データに効率よくアクセスできるようになると無限に遊べそうで怖い。

参考サイト

  1. e-Stat 政府統計の総合窓口
  2. e-Stat API機能

参考書籍

関連記事

  1. 長期の物価の動きを分類ごとに比較してみた。デフレ経済とはいえ教育費だけはインフレ

コメントを残す