tableauの平均


tableauの平均値の注意メモ(基本なんだけど、時々あれっ?ってなるので)。

tableauで以下のようなデータがあった場合

Year Month Date Query imp click
2019 4 1 a 100 10
2019 4 8 b 200 10
2019 4 8 a 10 1
2019 4 8 c 50 5
2019 4 15 c 300 50

このデータを月単位でgroup by(yearで集計)してsumとavgを取得すると以下となる

Year Month imp(sum) click(sum) imp(avg) click(avg)
2019 4 660 76 132 15.2

注意すべきは、この平均は「月」の平均ではないこと。

tableauの集計(sum,avg,min,max等)は、指定したディメンジョン粒度(ここでいえばyearとmonth)が持っているデータの最小単位粒度(Level of detail、ここでいえばdateとqueryも含めた5行の粒度)で集計する。当たり前のことだが、view上は1行だが、実際のデータは5行ある。sumやmaxなどを集計する場合特に注意することはないが、average集計の時だけは注意が必要。

このケースの場合、意味的に求めたい"月単位"での平均値は、4月の全合計データを4月1日、4月8日、4月15日の3回分で割った数だ。だがここでは、上記のtableauルールが適応され、4月の全データ÷5で平均値が計算されてしまう。

指定したディメンジョンが持っているデータの最小粒度が、平均を求めたいときに使いたい分母の粒度と一致していないのだ。

この齟齬を回避するためには、fixed関数(LOD関数)を使う。(日付はdayというディメンジョン名だとする)

impの平均 (imp(fixed_avg)とする)
imp/{fixed year[day],month[day]:countd(date[day])}

clickの平均 (click(fixed_avg)とする)
click/{fixed year[day],month[day]:countd(date[day])} 

こうすることで、無理あり元データ上にgroup byしたデータを作ってしまうことができる。
元データは↓こんな風に書き換えられている。

Yeart Month Date Query imp click imp(fixed_avg) click(fixed_avg)
2019 4 1 a 100 10 220 25.3
2019 4 8 b 200 10 220 25.3
2019 4 8 a 10 1 220 25.3
2019 4 8 c 50 5 220 25.3
2019 4 15 c 300 50 220 25.3

そして、このデータを使えば、以下のようなデータが求められる。
fixed関数で生成した数字は、view上のセグメントに左右されない。

Year Month imp(sum) click(sum) imp(fixed_avg) click(fixed_avg)
2019 4 660 76 220 25.3

■まとめ
・tableauの集計(sum,max,min,avg)は、指定しているgroup by粒度内の最小単位で集計している(group byで見えなくなっているデータの粒度で集計されている)

・その際、平均の値が求めたい値と異なって算出されるケースがある。平均は必ずしもgroup by粒度内の最小単位で求めたいケースばかりではない(上記の月のケースのように)ことがある為

・その場合はfixed関数(LOD関数)を使う。"何でgroup byしたいのか"をSQL感覚で書けばよい

■直観イメージ
excelの通常表計算でのセルの中身は、単なる単一の数字データであることが多い。
一方、tableauの表形式viewはあくまで「集計結果」の状態表示であって、中身は個別データなのだと考える。セル1つの数字の内側にどういう粒度のデータが集約されているかをイメージすると良い。