e-Stat APIのデータ構造を理解する
e-Statの統計データをSQLでアクセスできるようにしたいと思い、まずは仕様書を読んで、APIの構造を把握するところから始めてみました。
e-Stat APIの全体像
e-Stat APIには7種類のエンドポイントがあります。
| API | 用途 |
|---|---|
| getStatsList | 統計表の一覧・検索 |
| getMetaInfo | 統計表の構造(軸・コード体系) |
| getStatsData | 実データ+メタ情報 |
| postDataset | 絞り込み条件の保存 |
| refDataset | 保存済み条件の確認 |
| getDataCatalog | Excel/PDF含む全データカタログ |
| getStatsDatas | 複数統計表の一括取得 |
調べてみると、基本的な用途では以下の2つがメインになりそうです。
- getStatsList: 統計表の一覧取得
- getStatsData: 実データ取得(
metaGetFlg=Yでメタ情報も同時に取れる)
getMetaInfoはgetStatsDataでmetaGetFlg=Yとすれば、似た情報を取得できます。
ただ、getMetaInfoは絞り込み前の全量を取得できるため、マスターテーブルの作成などに使えそうです。
データセット系API(postDataset, refDataset)はe-Stat上で条件を保存・再利用するためのもので、用途によっては使わないこともありそうです。
レスポンス形式
e-Stat APIはXML、JSON、JSONP、CSVの4種類の形式でレスポンスを返せます。この記事では仕様書に従ってXMLでサンプルを記載していますが、実際にはJSONで取得することも可能です。
XMLが基本のレスポンスフォーマットで、JSONには下記の変換規則に従って変換されます。
属性名には@がつき、同名タグがある場合の値はネストされて、$で表現されるなど知っておかないと理解できないので注意が必要です。

政府統計名と統計表の関係
用語で混乱したのが「政府統計名」と「統計表」の関係です。
政府統計名(STAT_NAME)
└─ 統計表(TABLE_INF)
└─ 統計表
└─ 統計表
└─ ...
例えば:
国勢調査(政府統計コード: 00200521)
├─ 男女別人口(統計表)
├─ 年齢別人口(統計表)
├─ 世帯数(統計表)
└─ ... 数百〜数千テーブル
1つの政府統計から数百〜数千の統計表が生成されます。getStatsListのstatsNameListパラメータで切り替えられます:
-
statsNameList=Y: 政府統計名の一覧 -
statsNameList省略: 統計表の一覧
ちなみにe-StatのUIでは「統計表」を「データセット」と呼んでいます。同じものを指しているので、混乱しないように注意が必要ですね。
APIレスポンスの構造
全APIで共通の3ブロック構成になっています。
<GET_STATS_DATA>
<RESULT> <!-- 処理結果 -->
<PARAMETER> <!-- リクエストのエコーバック -->
<XXX_DATA> <!-- メイン情報 -->
</GET_STATS_DATA>
<XXX_DATA>の部分はエンドポイントによって以下のように変わります。
-
getStatsList:<DATALIST_INF> -
getMetaInfo:<METADATA_INF> -
getStatsData:<STATISTICAL_DATA>
統計データ(VALUE)
各セルの値です。どの軸のどの値かを属性で指定します。
<VALUE tab="00001" cat01="02" area="01000" time="2020000000" unit="人">2500000</VALUE>
これは「北海道の2020年の男の人口は250万人」を意味しています。
tabやcat01、area、timeなどはメタ情報のコードを表しています。
getMetaInfoエンドポイント、またはgetStatsDataでmetaGetFlg=Yとすることで取得可能です。
メタ情報(CLASS_INF)
統計表の「軸」を定義しています。
<CLASS_INF>
<CLASS_OBJ id="tab" name="表章項目">
<CLASS code="00001" name="人口" unit="人" />
</CLASS_OBJ>
<CLASS_OBJ id="cat01" name="男女別">
<CLASS code="01" name="総数" level="1" />
<CLASS code="02" name="男" level="2" parentCode="01" />
<CLASS code="03" name="女" level="2" parentCode="01" />
</CLASS_OBJ>
<CLASS_OBJ id="area" name="地域">
<CLASS code="00000" name="全国" />
<CLASS code="01000" name="北海道" />
</CLASS_OBJ>
<CLASS_OBJ id="time" name="時間軸">
<CLASS code="2020000000" name="2020年" />
</CLASS_OBJ>
</CLASS_INF>
VALUEの属性を整理する
VALUEに入る属性が何を意味するのか、最初は分かりにくかったです。
| 属性 | 意味 | 固定/可変 |
|---|---|---|
| tab | 表章項目(何を測っているか) | 固定 |
| area | 地域 | 固定 |
| time | 時間 | 固定 |
| cat01〜cat15 | 分類軸 | 可変 |
| unit | 単位 | - |
| annotation | 注釈記号 | - |
ポイントはcat01〜cat15の意味が統計表によって異なることです。
<!-- 統計表A -->
<CLASS_OBJ id="cat01" name="男女別">
<!-- 統計表B -->
<CLASS_OBJ id="cat01" name="年齢5歳階級">
同じcat01でも、統計表Aでは「男女別」、統計表Bでは「年齢階級」になります。tab、area、timeは意味が固定ですが、cat01〜cat15は「汎用スロット」として使われています。
tabの「観測値」とは
多くの統計表でtabがこうなっています:
<CLASS_OBJ id="tab" name="表章項目">
<CLASS code="00001" name="観測値" level="1" />
</CLASS_OBJ>
「観測値」は「この統計表には1種類の値しかない」という意味のようです。複数の指標がある場合は:
<CLASS code="00001" name="人口" />
<CLASS code="00002" name="世帯数" />
のように分かれます。e-Statの設計として全統計表に必ずtab軸を持たせているため、1種類しかない場合は「観測値」というプレースホルダー的な名前がつくみたいですね。
levelとparentCode
階層構造を表現しています。
<CLASS code="001" name="総数" level="1" />
<CLASS code="002" name="男" level="2" parentCode="001" />
<CLASS code="003" name="女" level="2" parentCode="001" />
level="1"が最上位で、数字が大きいほど下位の階層です。parentCodeで親子関係を表現しています。
データをSQLで扱う際の課題
e-Statは「公開」目的で設計されており、分析用ではありません。そのため:
- 調査ごとに構造が異なる
- 軸の数がバラバラ(2軸〜5軸以上)
- コード体系が不統一(東京都 = "13000" / "13" / "130001")
- 分類定義が経年で変化する
といった点があり、全統計表を統合するのは難しそうです。
同じ政府統計内であれば、コード体系や分類の考え方が一貫している可能性が高いので、まずは政府統計単位で整理するのが現実的かもしれません。
まとめ
- e-Stat APIはgetStatsList、getMetaInfo、getStatsDataが基本
- レスポンスはXML/JSON/JSONP/CSVから選べます
- 政府統計名 → 統計表の階層構造を理解しておくと見通しが良くなります
- VALUEの属性のうち、tab/area/timeは固定、cat01〜cat15は統計表によって意味が変わります
- SQLで扱う場合は、政府統計単位で整理するのが取り組みやすそうです
感想
複雑そうでとっつきづらく、なかなか手をつけようと思えなかったe-Stat APIですが、仕様書は実はたった1ページでまとまっており、(AIの助けを借りれば)1日あれば理解できる分量でした。
これだけ覚えておけば、とりあえずAPIを扱えるようになると思います。
あとは、多種多様なメタ情報と格闘して意味を読み取っていきましょう。
正直、使いこなすためにはとても習熟が必要そうです。。。一緒に頑張りましょう。
参考
Discussion