(2021/5/27 追記: もっと簡単に作る方法を書きました)
今回のブログ記事のテーマは「Self-UNIONでSankey Diagramを作成する方法」です。
過去様々な方法でSankey Diagramを作成してきましたが、最終的にSelf-UNIONで作る方法が一番簡単なのでは?と思いました。
一方でSelf-UNIONを使用して作成する方法のドキュメントが見当たらないので、自分で書き起こすことにしました。
(ExcelでJOIN用データを作成する方法か、前処理なし版かの2つしか見当たりませんでした)
データはSample Superstoreを使用しています。
今回使用したワークブックは以下からダウンロードできます。
Sankey Diagram作成方法それぞれについて
まず、上記2つの方法について簡単にメリット/デメリットを記載します。
ExcelでJOIN用データを作成する方法
メリット:昔から使われており、比較的計算式も簡単
デメリット:各レコードを100件近く複製させるので、データ量が100倍になる。
前処理なし版
メリット:データ件数を一切増やさない、前処理できないデータコネクタの際に有用(Google Analyticsコネクタなど)
デメリット:計算式が煩雑、原理的にはレコードを一意にする行が欲しい(行IDなど)
上記の既存手法と比べて、今回ご紹介する方法の利点を簡潔に述べます。
Self-UNION自体は曲線描画等において広く使用されているテクニックであり、前処理版と比較して計算フィールド数や計算式イメージも比較的簡素。
Self-UNIONなのでデータ増加量はたった2倍。
過去全部の作成方法を試してきましたが、Self-UNIONを使用する方法が一番バランスが取れていて良いかなと思います。
何よりも、Self-UNION自体は多くの活用場面があることが強いです。
作成Sankey Diagramを応用発展させたい際に、他のSelf-UNIONを使用するチャートのノウハウを流用できます。
ということで、早速作り方を見ていきましょう。
下準備
まずはSelf-UNIONをします。
次に、以下の計算式を用意します。
Chosen Measure
SUM([Sales])
Dimension 1
[Region]
Dimension 2
[Category]
Path Frame
IIF([Table Name] = 'Orders', 0, 97)
Path Frame (bin)
基本的には上記で作成したカラムを用いて、Sankey Diagramのそれぞれの組み合わせでのポリゴンを描写していきます。
SIGMOIDカーブの計算
Sankey DiagramではSigmoid曲線を使用します。
そのために下記計算フィールドを用意します。
Path Index (Path Frame(bin)に沿って計算)
INDEX()
T
IF [Path Index] <= 49
THEN (([Path Index] - 1) % 49) / 4 - 6
ELSE - (([Path Index] - 1) % 49) / 4 + 6
END
Sigmoid
1 / (1+EXP(1)^-[T])
Path Indexについて解説します。
まず、今回の方法ではData Densificationを使用します。具体的には、下図の手順により、表示されるPath Frame(bin)を増やします。
元々Path Frameは0または97の値のみを持つので、もちろんPath Frame(bin)も(bin sizeが1のとき)0または97のbinのみを持ちます。
一方で「欠損値を表示」オプションをオンにすると、0から97までの1刻みbinが作成されます。元々のデータに存在しないものをTableau上で表示させるため、
Data DensificationまたはData Paddingと呼んでいます。
このParh Frame(bin)に沿わせたPath Indexは、以下のように1~98の整数値をもちます。
このPath Indexを使用したTは、以下のようにPath Indexが49以下かの条件に応じて、2回数値がアサインされます。
このようにして、Sigmoid曲線は以下のように、Path Indexに応じて2本作成されます。
最終的には、この2本の曲線の位置をそれぞれズラしたものを繋ぎ、ポリゴンを描写します。
このあたりの議論については、こちらの記事も理解の役に立つかもしれません。
SANKEY DIAGRAM CALCULATIONS
準備が揃ったので、Polygon描写のための計算フィールド作成に入ります。
Sankey Arm Size (dimention1とdimension2を表計算に使用)
[Chosen Measure] / TOTAL([Chosen Measure])
この計算式はいたってシンプルで、各Dimension1とDimension2の組み合わせごとの、全体に対する割合を返します。
また、以下の計算式を作成します。
表計算の設定は後に続きます。
Max Position 1
RUNNING_SUM([Sankey Arm Size])
Min Position 1
[Max Position 1] - [Sankey Arm Size]
Max Position 1 Wrap
WINDOW_MIN([Max Position 1])
Min Position 1 Wrap
WINDOW_MIN([Min Position 1])
Max Position 2
RUNNING_SUM([Sankey Arm Size])
Min Position 2
[Max Position 2] - [Sankey Arm Size]
Max Position 2 Wrap
WINDOW_MIN([Max Position 2])
Min Position 2 Wrap
WINDOW_MIN([Min Position 2])
表計算の設定
上記について、例えばMax Position 1であれば、以下のように設定できます。
(ワークシート上でも設定できますが、以下手順でデフォルト設定を施しておいた方が楽です)
ここまでの計算を簡単に見てみましょう。
まず、Min Positionは「Polygonの始点」を与えます。
もし一番最初のPolygonであれば、Y軸の0からPolygonは描写されるので、0を返します。
(Central - FurnitureのMin Positionが、この場合にあたります)
もし2番目のPolygonであれば、その始点は1番目のPolygonの太さ分(Sankey Arm Size)の位置になります。
3番目のPolygonであれば、1番目と2番目の(つまり、ひとつ前のPolygonまでの)Sankey Arm Sizeの累計値を返します。
Max Positionは逆にPolygonの終点、つまりSankey Arm Sizeの累計値を返します。
Wrapと末尾につく計算フィールドは、計算式の通り、単にPath Frame(bin)に関してのWINDOW_MIN()をとっているのみです。
上図に出ているように、これは対応するMin/Max Positionの数値を、Path Frame(bin)全体に与えています。
さて、ここまでの計算フィールドを用いて、Polygon描写のための計算フィールドを完成させます。
Sankey Polygons
IF [Path Index] > 49
THEN
[Max Position 1 Wrap]
+ ([Max Position 2 Wrap] - [Max Position 1 Wrap])
* [Sigmoid]
ELSE
[Min Position 1 Wrap]
+ ([Min Position 2 Wrap] - [Min Position 1 Wrap])
* [Sigmoid]
END
作成したSankey Polygon等々を下図のように配置すれば、目的のSankey Diagramが作成できます。
もし下図のようなものが出来なかった場合、表計算の設定が一番疑わしいと思います。
ワークブックや記事中の設定と見比べてみて下さい。
ちなみに余白も作れます
上記までで今回の記事の本題は終わっていますが、おまけとして。
余白を作る計算フィールドもワークブック中に記載しておきました。
ご興味あるかたは、ぜひ計算フィールドを見てみて下さい。
基本的にはこちらの記事と同じです。
最後に
Self-UNIONによるSankey Diagram、いかがでしたか。
作り方で言えば、この方法が一番楽だと思います。
(逆にどうして今まであまり言及されてこなかったのか...)