Tableauに読ませるデータは「必ず横持ちが正解」なのか?(複数の人口ピラミッドを、なるべく規模の大小に左右されずに表現する手法)

Tableau
TableauTableau Tips

今回の話題はだいぶ読者が限定されます

今回の主題は「複数の枠組みでの人口ピラミッドを作る」場合において、「元データの形式をどのようにしておけばいいか」と「そのデータをどのようにTableauに反映していくことが望ましいか」というものなので、「人口ピラミッドを作る機会がない」または「人口ピラミッドを単一のエリアで作ればそれでいい」という方にはあまり役立たないかもしれません。

ということで、前回同様にまずは完成したVizを先に見ていただき、「作り方を詳しく知りたいな」という場合のみ次セクション以降の解説をお読みいただければ。

使用するデータの解説

と、いきなり読者をふるいにかけたところで始めていきます。

今回の解説に用いるデータは、「住民基本台帳に基づく人口、人口動態及び世帯数(令和6年1月1日現在)」のうち、【日本人住民】令和6年住民基本台帳年齢階級別人口(市区町村別)を使います。

MK
MK

外国人を含む総数としていない理由は、「外国人住民の「男性総数が1~9人」「女性総数が1~9人」「男女計総数が49人以下」のいずれかに該当する市区町村における5歳ごと等の内訳は、非公表」とする秘匿処理により、「各年齢階層の合計」と「市区町村の総数」が一致しないからです。

なお、上記のExcelデータの形式そのままでは、Tableauのデータソースに用いるのには少々向いていません。

Tableau Prep Builderによるデータ整形、またはTableau Desktopでのデータインタプリターやピボット処理を行う必要がありますが、今回はその手順の解説は省略します。


MKの方で、このようにデータ整形を行ったものを用意しました。
「いや、なんで2つあるねん」
と言いたくなる気持ちはこらえてください(この後詳しく解説します)。

MK
MK

※以後、「人口」の数値を全て同一の列に格納し、性別の列で「合計」「男性」「女性」の区別を付けている方を「日本人(縦持ち)」「人口(合計)」「人口(男性)」「人口(女性)」それぞれの列に数値を格納している方を「日本人(横持ち)」として表記します。

あらかじめ処理する抽出フィルターの解説

「000892957.xlsx」のデータには、個別の市区町村の数値とは別に「都道府県ごとの合計」「政令市の行政区ごとの合計」「東京都島しょ部の合計」「郡部ごとの合計」や、「年齢階層ごとの合計」「性別ごとの合計」が用意されています。

これらの合計値はExcel表をそのまま目視で眺める場合には有用ですが、Tableauなどでデータを一括して取りまわす場合には逆に邪魔になります。
たとえば、これらの値を含めてそのまま総計を出すと、日本人の人口は8億人を突破してしまいます

このような値を持つデータを扱う場合は、「抽出フィルター」で早い段階から取り除いておきましょう


「日本人(縦持ち)」「日本人(横持ち)」に共通する抽出フィルターとして、「市区町村以外の区別用」(※MKがデータ整形した際に用意した区分なので、「000892957.xlsx」にはこの区分はありません)ディメンションからNULL以外を除外し、「年齢階層」ディメンションから「総数」を除外します。

また、上記に加えて「日本人(縦持ち)」の方は「性別」ディメンションから「合計」を除外しましょう。

Vizを作り始める前に、合計値に乖離が生じていないか確認しよう


これらのフィルターをあらかじめ設定した上で、「日本人(縦持ち)」の場合は「人口」メジャー、「日本人(横持ち)」の場合は「人口(合計)」メジャーをまずビューにドロップしてみると、どちらも「121,561,792」となります

MK
MK

※元のExcelデータの都道府県名が「合計」・年齢階層が「総数」の【121,561,801人】と比べ9人の差異が出ていますが、いくつかの市町村で「各年齢階層の合計」と「市区町村の総数」に1~2人の誤差(集計誤り?)があることに起因しています。今回は、この9人の差異は無視します。

このように、Viz作成に入る前に、ディメンションで区切る前の値の合計が元データと乖離がないことを確認すると、Vizを作る際に手戻りが発生しなくて良いでしょう。

まずはピラミッドを1つ作ってみよう

さて、前提の数字がきちんと揃っていることを確認したところでそれぞれのViz作成を進めていきます。

MK
MK

手順の一部は「e-StatのデータとTableau Publicで人口ピラミッドをつくろう!」のvol.2vol.3の解説と重複する箇所があるため、適宜省略します。


前回のブログで書いていなかった解説として、人口ピラミッドを作る場合は「年齢階層」の「既定のプロパティ」→「並べ替え」を手動で設定しておく手順があります。

「日本人(縦持ち)」の場合は列シェルフに「性別」ディメンションを入れた上で「人口」メジャーを配置し、「日本人(横持ち)」の場合は列シェルフに「人口(男性)」「人口(女性)」メジャーを配置します。ここまではほぼ同じ、日本全国の日本人を年齢階層ごと・男女ごとに区切ったVizができあがりました。



以前のブログと同様に、「日本人(縦持ち)」の方は計算フィールドで、「日本人(横持ち)」は軸の反転で対処することで、男女ごとの人口を左右に振り向ける「人口ピラミッド」の形ができあがりました。

このように、「ただ1つの人口ピラミッドを作る場合」は、どちらの手法を使っても大きな差異はありません

人口ピラミッドを市区町村ごとに区切ってみよう

では、いよいよ各都道府県や各市区町村に細分化してみましょう。
あ、都道府県のディメンションもしれっと既定のプロパティから並べ替えを変更しています
(市区町村の方はさすがに手動で並べ替えたくないので、ちょっとズルして元データに地方公共団体コードをくっつけています)


この時点でもまだ「日本人(縦持ち)」「日本人(横持ち)」どちらの手法でもVizの見た目に大きな差異はありませんが、そもそもの話として「人口規模が都道府県や市区町村ごとで違いすぎて、小さな自治体では年齢階層ごとの人口分布が分かりづらい」という問題が生じています。
この図だと、北海道よりも青森県の人口規模が小さく、青森県の方はピラミッドの凹凸が小さくなっていますね。


試しに、福岡県うきは市の付近を表示してみました。
高齢者の層が多いように見える?けど、この人口規模(市全体で30,000人以下)になると、Vizの見た目上では年齢階層ごとの違いはよくわかりませんね。

軸の長さは「割合」で表現すると良いんじゃないか……と思ったら、「日本人(縦持ち)」がうまくいかない

そこで考えました。
軸を「人口の実数」としているから人口規模の大小に影響されてしまうわけで、福岡県内市区町村の人口ピラミッドの割合の表現を再考してみたと同じように、「市区町村ごとの人口総数」を分母にしつつ「男女は区別しない」ようにして各階層の人口の割合を計算すればいいと。


いったん、男女の左右振り向けをする前の状態で、
[人口]/{FIXED [Sort用市区町村名]: SUM([人口])}
として計算する(今回はこの計算式の解説は省略)ことで、男女ともにそれらしい長さ(各年齢階層の総数比)は実現できました。

あとは男性の軸を再び逆転させればいいだけですが……
「日本人(縦持ち)」の場合はそもそも「軸の反転」は使わない実装方法なので、軸を反転させると女性側も反転されてしまいます


それならば、人口の実数と同じような手法で、計算フィールドで
IIF([性別]="男性",-[市区町村ごと人口割合],[市区町村ごと人口割合])
としてみると男性側の軸だけは反転されるものの、軸の基点が離れてしまいます

どうにかならないものかと、「軸の編集」から「各行または列の独立した軸範囲」を選ぶことでそれっぽく棒を寄せることができますが……

実はここにも小さな落とし穴があり、この場合は「軸の最大値は自動で設定される」状態に委ねるしかないのです(いろいろ試しましたが、この設定でしか基点を寄せることはできませんでした)。

「別に最大値が自動で設定されてもいいんじゃ?」と思われたかもしれませんが、今回の例だと、軸の表示上の男性側の最大値は0.09(9%)よりちょっと上、女性側の最大値は0.14(14%)よりちょっと上というように、左右の幅が揃っておらず、例えばスクリーンショットに写っている「宮若市」の「70~74歳」という階層は、実際は「男性: 1,241人(4.82%)」より「女性: 1,282人(4.97%)」の方が多いはずなのに、棒の長さは男性の方が長いように見えています

この解決策は(私が知る限りでは)なさそうなので、「複数の人口ピラミッドを並べたい場合」は、「日本人(縦持ち)」のような「性別の数値が1列に記録されており、別の列(ディメンション)で性別を区別する」形式はそぐわないことになります。

「日本人(横持ち)」で軸の長さを「割合」で表現するとどうなる?

では、「日本人(横持ち)」のように「性別の数値の列が分かれて記録されている」形式の方のViz作成を再び進めてみましょう。
こちらはそもそも「人口(男性)」と「人口(女性)」のようにメジャー自体が分かれているので、


SUM([人口(男性)])/
SUM({FIXED [Sort用市区町村名]:
 SUM([人口(男性)])+SUM([人口(女性)])
})

というように、割り算の分母は男性・女性の人口をそれぞれ足しこんだものとする、という計算式にしました。

MK
MK

なお、

SUM([人口(男性)])/
SUM({EXCLUDE [年齢階層]:
 SUM([人口(男性)])+SUM([人口(女性)])
})

としても同じ結果が得られます(LOD計算を深く学んだ方ならこの理屈が分かるはずですが、今回は省略)。

ここまでだと先ほどの「日本人(縦持ち)」と同様に、軸の表示上の男性側の最大値と女性側の最大値は異なる値となっていますが、こちらはそれぞれのメジャーで軸の編集ができるので、男性も女性も開始値を0、終了値を0.1(10%)に固定し、男女で棒の長さが異ならないようにしています

MK
MK

「いや、さっき『女性側の最大値は0.14(14%)』って書いていたやろ。だったら男性も女性も終了値を0.14(14%)にすべきでは?」
と思われるかもしれませんが、この割合を調べてみると北海道の音威子府村の15~19歳の女性(78人・12.28%)だけが「外れ値」となっており、それ以外の市区町村・年齢階層で10%を超える例が他になかったため、この外れ値にあわせて全ての人口ピラミッドの分布のダイナミックさを小さくするよりは、多数の人口ピラミッドの表現を優先させていただきました。

終了値を0.1とした場合に音威子府村の人口ピラミッドを表示すると、15~19歳の女性はビューをはみ出しますがご容赦ください。

終了値を0.1とした場合と、終了値を0.14とした場合を比較すると、このような見た目上の凹凸の差が生じます。

まとめ

長くなってしまいましたが、今回のまとめです。

  • 「人口ピラミッドを作る」という目的の場合、性別ごとの人口は「独立した列」(=横持ち)で記録されている方が良い
  • ただし、人口規模が大きく異なる市区町村や地区同士でピラミッドを比較しない場合や、年齢階層ごとの差異が大きくない場合は、同じ列(縦持ち)で記録されていてもまあ大丈夫
  • 割合で棒の長さを表現する場合の最大値は、全体を俯瞰して大きすぎず小さすぎずに設定する(今回の「0.1」が必ず正解、というものではない)

また、人口ピラミッドのように「左右に振り向ける」類のものでない場合でも、今回のように「実数だと規模の差異が大きくて比較しづらい」ものを「割合」で比較する、ということは応用できる手法ではないかなと思います。

コメント

タイトルとURLをコピーしました