9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[Power BI] RANKX関数を紐解く。JAPAN RUGBY LEAGUE ONE 選手たちの身長・体重で。

Last updated at Posted at 2022-02-03

はじめに

先日、JAPAN RUGBY LEAGUE ONE の開幕を記念して、選手の身長・体重をPower Queryのカスタム関数を利用してPower BI Desktopに取り込み、可視化しました。

今回取り組むこと

RANKX関数を使って身長、体重のランキングを作成します。
そのなかでRANKX関数の仕様を紐解いていきます。

作ったレポート

こんなものを作りました。

image.png

RANKX関数の構文

RANKX(<table>, <expression>[, <value>[, <order>[, <ties>]]])

身長のランキングを作成する

身長を並べるテーブルを作成します。ここにRANKX関数を書いて、ランキングをつけていきます。
200m以上の選手がこんなにいるんですね。

image.png

最低限のRANKX関数を書いてみます。1つ目の引数には身長・体重が入っているHeight&Weightテーブルを指定して、2個めの引数は単一の結果をだす式でないといけないので、今回はMAXX関数をつかっています。

MAX_Height.dax
MAX_Height = MAXX('Height&Weight','Height&Weight'[Height])

datastudio HeightRank 0 = RANKX( 'Height&Weight', [MAX_Height] )

これを適用してみると↓のようになります。

image.png

期待した動きではないですよね。これは、RANKX関数が行ごとに評価をしていく仕組みになっているので、このままだと1行の中にある、1つの身長に対してランキングを返すだけの謎の関数になってしまっています。

改善1つ目

ということで、分母を表全体に変えたいと思います。そういうときはALL関数を使用します。
1つ目の引数に対してALL関数を適用して、

分母 → 表全体
分子 → 行ごとの身長

となるように書いていきます。

HeightRank 1 = RANKX(
    ALL('Height&Weight'),
    [MAX_Height]
)

結果

期待した結果になりました。

image.png

改善2つ目

Power BIは合計列も行もひとつとしてDAX関数の評価が行われているので注意が必要です。
いまは合計列にも数字が表示されてしまっているので、ここに数字が表示されないようにしたいです。今回はISINSCOPE関数を使用します。指定した階層にいるときだけtrueを返します。

HeightRank 2 = IF(
    ISINSCOPE( 'Height&Weight'[Name] ),
    RANKX( ALL( 'Height&Weight' ), [MAX_Height] )
)

結果

期待した通り、合計行の数字がなくなりました。

image.png

改善3つ目

次に考えるのは、選手個人名のスライサーを作成して数名を選んだときに、分母が全員のママなのでランキングが直感的ではなくなっている点です。選択した選手の中でだけランキングをされるように改善します。

この場合はALLSELECTED関数を使用します。名前の通り、スライサーで選択したものすべてを分母とするときに使用します。

HeightRank 3 = IF(
    ISINSCOPE( 'Height&Weight'[Name] ),
    RANKX( ALLSELECTED( 'Height&Weight' ), [MAX_Height] )
)

結果

期待したとおり、5人をスライサーで選択すると、1~5位までが表示されています。

image.png

改善4つ目

レポートを作るに当たり、チームごとでのランキングも表示させたいなぁと思っています。いまの関数でチームの階層を加えると、選択したすべての選手が分母になっているので、チームをまたいでランキングが計算されています。これをチーム別にランキングが計算されるようにしていきます。

これを実現するために、ALLEXCEPT関数を使います。指定した列にかかっているフィルター以外はすべてなくなります。今回の場合、チーム名のフィルターコンテキストだけ残し、「選択した選手」フィルターは削除します。この関数を使用することで、分母がチーム全員、分子がその行の身長となり、期待したランキングを作成できます。

指定した列に適用されているフィルターを除く、テーブル内のすべてのコンテキスト フィルターを削除します。

ALLEXCEPT(<table>,<column>[,<column>[,…]])

HeightRank 4 =
IF (
    ISINSCOPE ( 'Height&Weight'[Name] ),
    RANKX (
        ALLEXCEPT (
            'Height&Weight',
            'Height&Weight'[Team_Name]
        ),
        [MAX_Height]
    )
)

結果

チームごとの選手数が分母になり、ランキングされているのがわかりますね。

image.png

改善5つ目

チーム別にランキングが計算されるようになりましたが、さらにポジション別の階層も追加したいと思っています。そのときは、さきほどのALLEXCEPT関数'Height&Weight'[Position]カラムを追加してあげます。

HeightRank 5 =
IF (
    ISINSCOPE ( 'Height&Weight'[Name] ),
    RANKX (
        ALLEXCEPT (
            'Height&Weight',
            'Height&Weight'[Position],
            'Height&Weight'[Team_Name]
        ),
        [MAX_Height]
    )
)

結果

チームとポジションでフィルターをかけたときにも期待した動作になっています。

image.png

ポジションを2つ選んでもそれぞれのポジションごとにランキングが計算されています。

image.png

複数のチーム、複数のポジションを選んでも大丈夫。

image.png

まとめ

RANKX関数単体ではあまり期待したランキングは作成できなさそう。ALL関数、ALLSELECTED関数、ALLEXCEPT関数、ISINSCOPE関数などを組み合わせて状況に合わせたDAXを書いてあげることが大事。

成果物

選手のポジションごとに身長/体重を可視化できました。ランキングも機能しています。

image.png

スクラムハーフとプロップの体型の違いもばっちり可視化できています!

image.png

9
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?