Japan Power BI User Group に投稿された質問
お久しぶりです。
今回は Facebook グループの Japan Power BI User Group で投稿された質問が元ネタです。
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
実際の質問は こちら
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
お題
さっそくお題です。
こんなデータをこうしたい
会計データのイメージですかね。
Excelでこんな「表」があって、これをグラフにしたい、という要望は多いのではないでしょうか。
このデータを元に、こんな計算がしたいという要望でした。
要は一番右の [売上高比率] を表の中に計算したいということです。
さて、あなたならどうしますか?
方法は無数に存在します。しばし考えてみてください。
いかがですか?
出来た方は、それで OK です。
正しい方法、というのをよく質問されますが、ぶっちゃけ、やりたいことができているのであれば、とりあえず及第点じゃん?と思います。
で、Facebook に投稿された質問に対して、複数の方が方法を示されていました。
質問者の方も、ここまでやったけど、ここから先ができませんという内容でした。
みなさんに共通していたことがあります。
それは
DAX でとても複雑な式を書いていた
ということです。
言い方を変えると
DAX で解決しようとしていた
ということです。
別に DAX で頑張って計算式を考えて答えを出す、ということ自体が悪いことではありません。
先ほど書いた通り、やりたいことができていれば、及第点 だと思います。
ただ
「その DAX、他のどんなビジュアル(グラフ)でも、正しい値を返しますか?」
Power BI 関連のコンサルティングをやっているので、実際のお仕事でもよく出会うのですが、
なぜだか、みなさんとても複雑な計算を DAX でやりたがるんですよね。
そして、とあるグラフ専用のメジャー、よく見ます。他のグラフでは、正常に動作しない**メジャー(DAX)**ですね。もし、あなたが書いている DAX がそうであるならば、もったいないです。DAX ってそういうものじゃないです。適切なモデリングができていれば、少なくともそのレポート内では、どのグラフでも正常な値を返すものです。
**「こういうことがしたくて、ここまで書いたんですが…」**と言って、見せられた DAX はたいていとても複雑なものです。
そして、そういう場合、もうひとつとても大事な 共通点 があります。
大事な共通点
それは、データ準備 と モデリング が不完全、ということです。
データ準備 とは Power Query による ETL のことです。
モデリング とは、正確にはデータモデリングと言いますが、
- テーブル間のリレーションシップの定義
- 新しい計算の追加(計算列とメジャー)
- 列やメジャーの名前変更や非表示
- 階層の定義
- 列の書式、既定の概要作成、並べ替え順序の定義
- 値のグループ化またはクラスタリング
などのことです。
データをビジュアライズしやすい形にすることはとても重要です。ビジュアライズするには適切なモデリングが必要です。Power BI において適切なモデリングとは、スタースキーマにすることを意味します。スタースキーマにするには、適切にテーブル間のリレーションシップを構築する必要があります。従って、データ準備において適切な単位でテーブルとして分けておかなければなりません。
この辺りは以下の公式ドキュメントを参考にしてください。
【公式ドキュメント】
スター スキーマと Power BI での重要性を理解する
https://docs.microsoft.com/ja-jp/power-bi/guidance/star-schema
また以下の Microsoft Learn もとてもオススメです。
【Micorosoft Learn】
Power BI でデータ モデルを設計する
https://docs.microsoft.com/ja-jp/learn/modules/design-model-power-bi
Power BI でデータをモデル化する
https://docs.microsoft.com/ja-jp/learn/modules/model-data-power-bi
今回のケースでは
もういちど最初の Excel を見てください。
これを見て、
「うわー、めちゃくちゃ扱いずらいな、これ」
「これって、かろうじてデータのカタチしてるけど、表じゃない?」
と思われた方、鋭いです。
言葉で説明するのは難しいですが、こう考えたら伝わるかもしれません。
「売上と経費が一つのテーブルに入ってるのって、なんか気持ち悪い...」
そうなんです。なぜ気持ち悪いのか?
売上って通常プラスの値ですよね。儲けたお金ですから。
経費って通常マイナスの値ですよね。使ったお金ですから。
これは何も経費は常にマイナス値で保持しなければいけない、と言っているのではありません。
そうではなくて、売上と経費ではベクトルの方向が異なる、ということです。
売上 - 経費 = 利益 ですよね?
なので、経費をプラスの値で持っていること自体は全然いいのですが、ベクトルの方向が異なる値が一つのテーブルの一つの列に同居しているのが、とても気持ち悪いのです。従って、これを分ける必要があります。
ちなみにデータモデリングとは、実業務をモデル化することです。優れたアーキテクトは、データモデルを見ると、そのビジネスモデルがわかると言います。その通りです。なぜなら、データモデルとはビジネスモデルそのものを具現化したものだからです。ここがデータモデリングを難しくしているところかもしれません。つまり、ビジネスの経験や知識がないと、データモデリングはとてもハードルが高いものになってしまいます。
実ビジネスを知っていたり、経験があると、モデリングのハードルを下げることができます。もちろんモデリングそのものの技術的知識も必要なので、データモデリングには実業と技術を双方持っていることが求められるのかもしれません。
さて、話を戻して、まずは売上と経費をテーブルとして分ける必要があります。これは Power Query エディターでやれば簡単です。クエリをクリックして、[参照] or [複製] 後に、片方は売上のみ、片方は経費のみにフィルターして、クエリの名前をそれぞれ適切に変えてしまえばいいのです。
そして、事業も分けておきます。ディメンションとして使用するためです。これも元のExcelデータを [参照] してクエリを増やし、[事業]以外の列を削除後、重複を削除してください。そうすると、事業を一意の値にできるので、ディメンションとして、使用することができます。本当は数値型のキーを作りたいとこですが、今回は省きます。
データ準備が終わったら、適切なモデリングを
[閉じて適用] で Power Query エディターを閉じて、Power BI Desktop に戻ります。
日付テーブル(date) を作りましょう。DAX の Calendar() 関数 or Calendarauto() 関数を調べてみてください。日付テーブルが簡単に作成できます。
そうしたらあとは以下のように、モデルビューでリレーションを作成してください。
ここまで来たら、あとはメジャーです。
メジャーはとってもシンプルに
売上 = SUM( sales[実績] )
売上テーブルの [実績] には売上しかないので、SUMっちゃいましょう。
経費 = SUM( cost[実績] )
経費テーブルの [実績] には経費しかないので、SUMっちゃいましょう。
売上高比率 = DIVIDE( [経費], [売上], 0 )
売上と経費がメジャーで表せたので、DIVIDE 関数で割り算をすれば、売上高比率が計算できますね。DIVIDE 関数の第三引数は、分母がゼロの時、どんな値を返すかを指定できるので、ゼロを入れておきましょう。割り算は必ず DIVIDE 関数でやりましょうね。これはもう覚えておいてよいものです。
はい、ようやく準備完了
ここまでやって、ようやく準備完了です。
こんな表ができましたか?
出来た方は、OKです!上手くいかなかったら、もう一度、手順を見直してください。必ずできますので。
まとめ
スタートは単純な Excel ファイルの表でしたが、Power BI でレポートを作る際は、基本的に この手順を必ず取ります。
どんな単純なデータでも、必ずです。
- データを観察する
- 必要なファクトとディメンションを考える
- クエリを分けて、テーブルを分ける
- リレーションを作る
- 計算列やメジャーを作る (数値は必ずメジャーにする。数値に関しては素の列は使わない)
これらのルールを守っておけば、だいたい大丈夫です。あとはいろんなデータで練習してみてください。
適切なモデリングができるようになってから、いろんな DAX を練習してみましょう。(私もまだまだ DAX は勉強中です)
おわり
はい、ということで今回は以上です。
Power BI でレポートを作る時の基本的な手順をご紹介しました。
最後まで読んでいただきありがとうございました。また気が向いたら、Power BI Tips シリーズを書きます。
皆様からのリクエスト、お待ちしております。
何かリクエストがあれば、以下までー🤗
Twitter: https://twitter.com/yugoes1021
Facebook: https://www.facebook.com/yugoes1021
LinkedIn: https://www.linkedin.com/in/yugoes1021/