これはチュートリアルの 2 つ目のステージで、最初のステージであるTableau Prep で 2 番目の日付を検索するは完了しているものと想定しています。
最初のステージでは、元のデータ セットを使用し、それを加工して以下の質問に答えました。
各ドライバーでの 1 回目の違反から 2 回目の違反までの日数の長さはどれほどか。
1 回目の違反と 2 回目の違反の罰金額を比較する。相関しているか。
支払額が全体で最も多いのはどのドライバーか。支払額が最も少ないのは誰か。
違反の種類が複数あるドライバーは何名いるか。
交通違反者講習会に参加したことのないドライバーでの平均罰金額がいくらか。
これらの質問についてこれから考えていくと、作成した最初のデータ構造にはいくらかの長所と短所があることがはっきりとします。Tableau Prep Builder に戻って追加の整形を行い、Tableau Desktop で同じような分析をするとどのような違いが出るか確認します。最後に、元のデータで詳細レベル (LOD) 表現を使用して分析する Tableau Desktop のみのアプローチを見ていきます。
このチュートリアルの目的は、最適な方法を規定して確立することではなく、現実のシナリオを背景にさまざまな概念を提示し、オプションを確認していくことです。終えるころには、データ構造による計算や分析への影響について理解が深まるだけでなく、Tableau Prep のさまざまな側面や Tableau Desktop での計算について習熟度が増しているに違いありません。
注: このチュートリアルのタスクを完了するには、Tableau Prep Builder と Tableau Desktop (オプション) をインストールし、データをダウンロードする必要があります。
このチュートリアルを続行する前に Tableau Prep と Tableau Desktop をインストールするには、「Tableau Desktop および Tableau Prep 導入ガイドの概要」(新しいウィンドウでリンクが開く)を参照してください。または、Tableau Prep(新しいウィンドウでリンクが開く) と Tableau Desktop(新しいウィンドウでリンクが開く) の無料トライアル版をダウンロードすることもできます。
データ セットには、最初のステージで作成した Driver Infractions.tflx からの出力を使用します。
データの構成が完了したので、データを Tableau Desktop へと移します。簡単に答えられる質問もありますが、少しの (または多くの) 計算が関係している質問もあります。以下の質問に挑戦してみてください。それぞれ展開すると、行き詰まった場合にどのように続行するか基本的な情報が得られます。
注: ソリューションを背景と合わせて確認するには、Driver Infractions.twbx(新しいウィンドウでリンクが開く) のワークブックをダウンロードできます。分析を解釈する、または解答を求める他の方法もある可能性があることに留意してください。
1.各ドライバーでの 1 回目の違反から 2 回目の違反までの日数の長さはどれほどか。
この質問に Tableau Desktop で答えるには、DATEDIFF 関数を使用します。この関数には 3 つの引数があります。日付部分、開始日、終了日です。これらのイベントからイベントまでの日数を知りたいと考えているため、日付部分 "day (日)" を使用します。開始日と終了日はデータ セットに "1st Infraction Date (1 回目の違反日)" と "2nd Infraction Date (2 回目の違反日)" として含まれています。
計算は以下の通りとなります。
"Time Between Infractions (違反から違反までの期間)" = DATEDIFF('day', [1st Infraction Date], [2nd Infraction Date])
"Driver ID (ドライバー ID)" に対して棒グラフとしてプロットすることもできます。7 人のドライバーには 2 回目の違反がないため、NULL が 7 つあることに注目してください。

2.1 回目の違反と 2 回目の違反の罰金額を比較する。相関しているか。
この質問に Tableau Desktop で答えるには、"1st Fine Amount (1 回目の罰金額)" と "2nd Fine Amount (2 回目の罰金額)" の散布図を作成します。[Driver ID (ドライバー ID)] を [マーク] カードの [詳細] シェルフに移動することで、.各ドライバーのマークを作成できます。
傾向線を追加するには、左側のペインの [アナリティクス] タブを使用し、線形傾向線を作成します。傾向線にカーソルを合わせるとと、R-2 乗の値は実質的にゼロであり、P 値は有意性のカットオフよりもはるかに高いことがわかります。1 回目の額と 2 回目の額には相関性がないと判断できます。
この散布図をダッシュボードで使用する場合は、傾向線を削除する必要があります。

3.支払額が全体で最も多いのはどのドライバーか。支払額が最も少ないのは誰か。
さらに詳細に分析を行う場合は、いくつか計算の作成が必要なことがあります。
この質問に Tableau Desktop で答えるには、単一フィールドに両方の違反の罰金額を追加する必要があります。ドライバーによっては 2 回目の違反がないことがあるため、[2nd Fine Amount (2 回目の罰金額)] の NULL をゼロにするためにゼロ NULL ZN
関数を使用する必要があります。これを行わなければ、2 番目の罰金がない場合は NULL になります。
計算は以下の通りとなります。
"Total Amount Paid (合計支払額)" = [1st Fine Amount] + ZN([2nd Fine Amount])
[Total Amount Paid (合計支払額)] を [Driver ID (ドライバー ID)] に対してプロットし、棒グラフを並べ替えることができます。

4.違反の種類が複数あるドライバーは何名いるか。
この質問に Tableau Desktop で答えるには、IF
計算を実行し、1 回目の違反と 2 回目の違反の種類が同じかを比較する必要があります。同じ場合は、値 "1" を割り当てます。同じでない場合は、"2" を割り当てます。複数の違反タイプのみを処理するため、違反タイプが NULL 秒 などの他の結果には "1" が割り当てられます。
計算は以下の通りとなります。
"Number of Infraction Types (違反の種類の数)" =
IF [1st Infraction Type]=[2nd Infraction Type] THEN 1
ELSEIF [1st Infraction Type]!= [2nd Infraction Type] THEN 2
ELSE 1 END
[Number of Infraction Types (違反の種類の数)] を [Driver ID (ドライバー ID)] に対してプロットし、棒グラフを並べ替えることができます。

5.交通違反者講習会に参加したことのないドライバーでの平均罰金額がいくらか。
この質問に Tableau Desktop で答えるには、一部のドライバーでは違反が 1 回のみのため、単純に合計罰金額を 2 で割ることはできません。また、平均を平均すると矛盾が起こる可能性があるため、ドライバーあたりの平均罰金額を計算し、その値の平均を利用することもできません。別の方法としては、交通違反者講習会に参加したことのないドライバーが支払った合計金額を計算し、それらの罰金額に関連している合計違反数で割ります。
まず、各ドライバーに 2 回目の違反があったかを判断します。2 回目の違反がない場合は「2 回目」のすべてのフィールドに含まれる情報が NULL になるという点を活用し、以下の計算を作成し始めることができます。
IFNULL([2nd Infraction Type], 'no')
違反が存在する場合には 1 つの違反の種類が返され、2 回目の違反がない場合には "no" が返されます。
次に、この情報を違反数である 1 または 2 に変換する必要があります。IFNULL
の計算結果が "no" の場合、そのドライバーは 1 つの違反ありとマークします。その他の結果に関しては、2 つの違反ありとマークします。計算は以下の通りとなります。
"Number of Infractions (違反数)" =
IF IFNULL([2nd Infraction Type], 'no') = 'no' THEN 1
ELSE 2
END
次に合計罰金額について考える必要があります。上記の質問 3 と同様、1 回目と 2 回目の罰金額を追加します。2 回目あたりで ZN
関数を使用します。とはいえ、これはデータ セット全体のレベルで計算する必要があるため、計算自体の中で集計である SUM を指定するのがベスト プラクティスです。計算は以下の通りとなります。
SUM([1st Fine Amount]) + SUM( ZN([2nd Fine Amount]) )
すべてまとめるには、この合計罰金額を新しい [Number of Infractions (違反数)] 計算フィールドで割り、平均罰金額を求めます。
"Average Fine (平均罰金額)" = ( SUM([1st Fine Amount]) + SUM( ZN([2nd Fine Amount]) ) ) / SUM([Number of Infractions])
また、交通違反者講習会に参加したことのあるドライバーをフィルターにより見つける必要もありますが、この情報も 2 つのフィールドに保存されています。
Tableau では非常に効率的に数値計算が行われます。数字によりこれを分割し、可能な限りパフォーマンスが向上するようにしています。これら 2 つのフィールドを組み合わせるため、各フィールドには "Yes = 1" および "No = 0" を示す計算を作成します (2 回目の違反がないドライバーでは NULL も 0 となります)。これらの計算の結果を合計すると、全体の値が 0 のドライバーは交通違反者講習会に参加したことがありません (1 または 2 の値は何回参加したかを示します)。そして、値が 0 のドライバーのみを保持するようにフィルターできます。
今回は、IF
ではなく CASE
ステートメントを使用します。機能はとても似ていますが、構文が違います。計算の冒頭は以下のようになります。
CASE [1st Traffic School]
WHEN 'Yes' THEN 1
WHEN 'No' THEN
ELSE 0
END
次に、"2nd Traffic School (2 回目の交通違反者講習会)" でも同じように実行します。各 Case ステートメントを括弧で囲み、その間にプラスを 1 つ追加することで、同一計算内に両方の部分を加えることができます。改行をいくつか削除すると、以下のようになります。
"Number of Traffic School Attendances (交通違反者講習会の参加回数)" =
(CASE [1st Traffic School] WHEN 'Yes' THEN 1 WHEN 'No' THEN 0 ELSE 0 END)
+
(CASE [2nd Traffic School] WHEN 'Yes' THEN 1 WHEN 'No' THEN 0 ELSE 0 END)
[Number of Traffic School Attendances (交通違反者講習会の参加回数)] を [データ] ペイン (行の上) の [ディメンション] エリアにドラッグすると、0 ~ 2 の値は不連続になります。
ここで [Number of Traffic School Attendances (交通違反者講習会の参加回数)] に対してフィルターを実行すると、0 のみを選択し、交通違反者講習会に参加したことのないドライバーを把握することができます。
当初の質問への解答は、[Average Fine (平均罰金額)] を [マーク] カードの [テキスト] シェルフに移動するだけで得られます。
集計を計算に組み込んでいるため、ピルの集計は AGG になり、変更することができません。これは想定内の動作です。

操作しているデータは特に 1 回目と 2 回目の違反に関する質問に対応できるように十分に構成されていますが、Tableau Desktop での使用に推奨されている標準的な構造ではありません。分析が違反日に関する基本的な質問から外れるほど、計算で関連情報を使用可能な形に組み合わせるのは複雑になります。
通常、同じ種類のデータに対して複数の列を使用してデータを保存し (日付に 2 列、罰金額に 2 列など)、フィールド名に一意の情報を保存する場合 (1 回目の違反か 2 回目の違反かどうかなど)、データをピボット処理する目安となります。
Tableau Prep Builder で複数のピボットを実行すれば、これを上手く処理できます。前のチュートリアル 2 番目の日付を検索する で作成した Tableau Prep のTableau Prep で 2 番目の日付を検索するフローの終わりの部分から作業できます。
ヒント: これらのステップに進めるように Tableau Prep に戻っていることを確認してください。
最終的なクリーニング ステップより、複製されたすべてのフィールド別にピボット処理するピボット ステップを追加します。[ピボットされたフィールド] エリアの右上隅にあるプラス
アイコンを使用し、さらに [ピボット値] を追加します。各セットのフィールド (1 回目の罰金額と 2 回目の罰金額) は一緒にピボット処理する必要があります。
ピボット処理の詳細については、データのクリーニングと加工を参照してください。
[ピボットされたフィールド] エリアの [Pivot1 Names (Pivot1 名)] 列で、各値をダブルクリックし、名前を 1 番目と 2 番目に変更します。

結果は、NULL の日付の削除、フィールド名の変更、フィールドの並べ替えにより整理することができます。
ピボット後にクリーニング ステップを追加します。[Infraction Date (違反日)] 列で NULL のバーを右クリックし、[除外] を選択します。
フィールド名 [Pivot1 Names (ピボット1 の名前)] をダブルクリックし、名前を「Infraction Number (違反数)」に変更します。
フィールドを以下のようにドラッグし、適宜並べ替えします。

ピボット処理された新しいデータより、"Pivoted Driver Infractions (ピボット処理したドライバー違反)" という名前を付けた出力を作成し、Tableau Desktop に移動します(フローの実行は、出力ステップを追加した後にしてください)。
ここでもう一度、ピボット処理されたデータ構造を使用し、5 つの質問を見ていきましょう。それぞれ展開すると、行き詰まった場合にどのように続行するか基本的な情報が得られます。
注: 完了したフロー ファイルである Pivoted Driver Infractions.tflx をダウンロードして作業を確認するか、ワークブックの Pivoted Driver Infractions.twbx をダウンロードしてソリューションを背景と合わせて確認できます。分析を解釈する、または解答を求める他の方法もある可能性があることに留意してください。
1.各ドライバーでの 1 回目の違反から 2 回目の違反までの日数の長さはどれほどか。
この質問に Tableau Desktop で答えるには、最初のデータ セットでの場合と同様、DATEDIFF
関数を使用します。この関数には開始日と終了日が必要です。この情報はデータに入っていますが、すべてが 1 つのフィールドにあります。それを 2 つのフィールドに分ける必要があります。
仮の 2 つの計算フィールドを以下のように作成します。
1st Infraction Date (1 回目の違反日) = IF [Infraction Number] = "1st" THEN [Infraction Date] END
2nd Infraction Date (2 回目の違反日) = IF [Infraction Number] = "2nd" THEN [Infraction Date] END
これらの値の両方を各ドライバーで比較可能であることを確認したいので、[Driver ID (ドライバー ID)] のレベルで修正する必要があります。
注: 信じられないとお考えですか。次のように、これらの 2 つのフィールドをそのままの状態で DATEDIFF
計算を実行してみてください。"Time Between Infractions (違反から違反までの期間)" = DATEDIFF('day', [1st Infraction Date], [2nd Infraction Date])
Tableau は以下のようなデータ構造で比較を行おうとしているため、結果はどれも NULL になります。

ここで、1 回目の日付がわかっている行では 2 回目の日付がわかっておらず、その逆も同様です。これを回避するには、FIXED 詳細レベル表現を使用し、これらの 1 回目の日付と 2 回目の日付を [Driver ID (ドライバー ID)] に強制的に関連付けるようにします。
各計算を以下のように編集します。
1st Infraction Date (1 回目の違反日) = { FIXED [Driver ID] : MIN ( IF [Infraction Number] = "1st" THEN [Infraction Date] END ) }
2nd Infraction Date (2 回目の違反日) = { FIXED [Driver ID] : MIN ( IF [Infraction Number] = "2nd" THEN [Infraction Date] END ) }
注: LOD 表現に埋め込む場合は、元の IF
計算を集計する必要があります。日付値を維持する基本的な集計はどれも使用することができます (SUM、AVG、MIN などの集計はうまく動作しますが、CNT や CNTD はうまく動作しません)。
注: これらの計算は、Tableau Prep Builder でも作成できます。Prep での LOD 表現の詳細については、詳細レベル、ランク、タイル計算の作成を参照してください。
これで DATEDIFF
計算を以下のように作成できます。
"Time Between Infractions (違反から違反までの期間)" = DATEDIFF('day', [1st Infraction Date], [2nd Infraction Date])
週または月のレベルで確認する必要がある場合は、単に日付部分を変更します (現在は 'day'
)。
また、FIXED calcs を DATEDIFF 内に直接配置して、全体に対して 1 つの計算を作成することもできます。
DATEDIFF ( 'day',
{ FIXED [Driver ID] : MIN ( IF [Infraction Number] = "1st" THEN [Infraction Date] END ) },
{ FIXED [Driver ID] : MIN ( IF [Infraction Number] = "2nd" THEN [Infraction Date] END ) }
)
列に [Time Between Infractions (違反から違反までの期間)]、行に [Driver ID (ドライバー ID)] をプロットします。
結果は、ピボット処理されていないデータ構造での結果と同じになります。
2.1 回目の違反と 2 回目の違反の罰金額を比較する。相関しているか。
この質問に Tableau Desktop で答えるには、前の質問にとても似た論理を使用します。指定した行が 1 回目の違反か 2 回目の違反かを特定するために [Infraction Number (違反数)] を使用し、適宜罰金額を取り出します。
散布図を作成したいだけの場合は、以下のように LOD 部分を省略し、IF
計算のみを使用できます。
"1st Fine Amount (1 回目の罰金額)" = IF [Infraction Number] = "1st" THEN [Fine Amount] END
"2nd Fine Amount (2 回目の罰金額)" = IF [Infraction Number] = "2nd" THEN [Fine Amount] END
ただし、1 人のドライバーの 1 回目の罰金額と 2 回目の罰金額を比較し、差を確認する場合は、日付に関して起こったような同様の NULL の問題が起こります。これらの計算を FIXED
LOD で囲んでも問題は起こらないため、最初からそのようにするのが賢明かもしれません。
"1st Fine Amount (1 回目の罰金額)" = { FIXED [Driver ID] : MIN ( IF [Infraction Number] = "1st" THEN [Fine Amount] END ) }
"2nd Fine Amount (2 回目の罰金額)" = { FIXED [Driver ID] : MIN ( IF [Infraction Number] = "2nd" THEN [Fine Amount] END ) }
これらの計算は、Tableau Prep Builder でも作成できます。Prep での LOD 表現の詳細については、詳細レベル、ランク、タイル計算の作成を参照してください。
列の 1st Fine Amount (1 回目の罰金額) と行の 2nd Fine Amount (2 回目の罰金額) を使用して散布図を作成し、前と同じように線形の傾向線を引きます。
結果は、ピボット処理されていないデータ構造での結果と同じになります。
3.支払額が全体で最も多いのはどのドライバーか。支払額が最も少ないのは誰か。
この質問に Tableau Desktop で答えるには、ピボット処理されたデータ構造が理想的です。唯一必要な作業として、[Driver ID (ドライバー ID)] と [Fine Amount (罰金額)] より棒グラフを作成します。既定の集計は既に SUM に設定されており、ドライバーが支払った合計額は自動的にプロットされます。
結果は、ピボット処理されていないデータ構造での結果と同じになります。
4.違反の種類が複数あるドライバーは何名いるか。
この質問に Tableau Desktop で答えるには、ピボット処理されたデータ構造が理想的です。唯一必要な作業として、[Driver ID (ドライバー ID)] と [Infraction Type (違反の種類)] の [個別カウント] より棒グラフを作成すると、答えが得られます。
結果は、ピボット処理されていないデータ構造での結果と同じになります。
5.交通違反者講習会に参加したことのないドライバーでの平均罰金額がいくらか。
この質問に Tableau Desktop で答えるには、一部のドライバーでは違反が 1 回のみのため、単純に合計罰金額を 2 で割ることはできません。また、平均を平均すると矛盾が起こる可能性があるため、ドライバーあたりの平均罰金額を計算し、その値の平均を利用することもできません。別の方法としては、交通違反者講習会に参加したことのないドライバーが支払った合計金額を計算し、それらの罰金額に関連している合計違反数で割ります。
まず、各ドライバーに 2 回目の違反があったかを判断します。2 回目の違反がない場合は [2nd Infraction Date (2 回目の違反日)] が NULL になるという点を活用し、以下の計算を作成し始めることができます。
IFNULL(STR([2nd Infraction Date]), 'no')
2 回目の違反が存在する場合には それが返され、存在しない場合には「no」が返されます。
注: IFNULL
では引数のデータ型に一貫性を持たせる必要があるため、この式の STR
部分が必要となります。NULL 値には文字列 "no" を返す必要があるため、日付を文字列に変換することも必要です。
次に、この情報を違反数である 1 または 2 に変換する必要があります。IFNULL
の計算結果が "no" の場合、そのドライバーは 1 つの違反ありとマークします。その他の結果に関しては、2 つの違反ありとマークします。計算は以下の通りとなります。
"Number of Infractions (違反数)" =
IF IFNULL(STR([2nd Infraction Date]), 'no')= 'no' THEN 1
ELSE 2
END
次に平均罰金額について考える必要があります。[Fine Amount (罰金額)] には既に単一のフィールドがあります。唯一必要な作業として、これを新しい [Number of Infractions (違反数)] フィールドで割り、その両方を SUM で囲みます。
"Average Fine (平均罰金額)" = (SUM([Fine Amount]) / SUM([Number of Infractions])
交通違反者講習会に参加したことのあるドライバーをフィルターにより見つける必要もあります。[交通違反者講習会] フィールドを使用して、[交通違反者講習会 = いいえ] にフィルターをかけることができるようですが、これでは、交通違反者講習会に参加したことのない [ドライバー] ではなく、交通違反者講習会に関連付けられていない[違反] にフィルターがかけられることになります。あるドライバーがある違反で交通違反者講習会に参加し、それが他の違反とは別の講習会である場合、ここではいずれの違反も考慮に入れるべきではありません。そのドライバーは交通違反者講習会に参加したことがあるため、問題のパラメーターには適合しないからです。
ここで必要なのは、交通違反者講習会に参加したことのあるすべてのドライバーを除外することです。データの観点から、任意の行にある [Traffic School (交通違反者講習会)] が [Yes (はい)] のドライバーを除外する必要があります。何が起きているかを追加するのに役立つシンプルなビューを使用し、計算を段階的に作成しましょう。
まず、あるドライバーで [Traffic School (交通違反者講習会)] が [Yes (はい)] かどうかを把握する必要があります。[Driver ID (ドライバー ID)] を [行]、[Traffic School (交通違反者講習会)] を [列] にドラッグします。各ドライバーの関連する値を示す "Abc" というテキストのプレースホルダーが入ったテキスト テーブルが作成されます。
次に、[Traffic School (交通違反者講習会)] の値が [Yes (はい)] かどうかを特定する計算を作成する必要があります。計算の最初の段階は以下の通りです。
"Attended Traffic School (交通違反者講習会に参加あり)" = CONTAINS([Traffic School), 'Yes')
[Attended Traffic School (交通違反者講習会に参加あり)] を [マーク] カードの [色] シェルフに移動すると、[No (いいえ)] 列のすべてのマークには正確に [False] のラベルが付き、[Yes (はい)] 列のすべてのマークには [True] のラベルが付きます。

しかし、本当に必要なのは、この情報を違反ではなく違反のレベルにすることです。LOD 表現は、データの基本的な構造ではなく、異なる詳細レベルで結果を計算しようとするときに上手くいきます。これを FIXED
LOD 表現にします。しかし、ご存知のように、LOD の集計式部分を集計する必要があります。以前は MIN を使用していました。ここでは上手くいくでしょうか。計算を以下のように変更します。
"Attended Traffic School (交通違反者講習会に参加あり)" = { FIXED [Driver ID] : MIN( CONTAINS([Traffic School], 'Yes'))}

その変更をビューで適用すると、必要な内容の反対のことが表示されます。[No (いいえ)] のドライバーは一覧表全体で [False] としてマークされています。その代わりに、そのドライバーの全記録で [True] として [Yes (はい)] を使用する必要があります。ここで MIN にはどのような役割があるでしょうか。最初の回答をアルファベット順で取得しています。つまり、[No (いいえ)] です。
MAX に変更するとどうなりますか。最後の回答をアルファベット順に取得するのでしょうか。計算を以下のように変更します。
"Attended Traffic School (交通違反者講習会に参加あり)" = { FIXED [Driver ID] : MAX ( CONTAINS( [Traffic School], 'Yes') ) }

また、ここでドライバーのデータのいずれかが [Yes (はい)] の場合、交通違反者講習会の参加有無は、講習会が関係しない違反に対しても [True] とマークされます。
[Attended Traffic School (交通違反者講習会に参加あり)] を [フィルター] シェルフに移動し、[False] のみを選択する場合、交通違反者講習会に参加したことのないドライバーのみが残ります。
当初の質問への解答は、フィルターを設定し、[Average Fine (平均罰金額)] を [マーク] カードの [テキスト] シェルフに移動するだけで得られます。集計を計算に組み込んでいるため、フィールドの集計は AGG になり、変更することができません。これは想定内の動作です。
結果は、ピボット処理されていないデータ構造での結果と同じになります。
その構造で簡単に解答できる質問に答えさえすればよいのであれば、チュートリアルの元のデータ構造のままで問題ありません。しかし、ピボット処理されたデータの形式にはさらに柔軟性があります。いくらかの計算は必要ですが、一度設定すると、結果のデータ セットはより幅広い質問に解答できるように調整されます。
Tableau Prep Builder にアクセスできない場合はどうすればよいでしょうか。元のデータで行き詰まっているなら、完全に運が尽きたということでしょうか。そんなことはありません。
Tableau Desktop と LOD 表現を使用すると、分析に関する質問すべてに解答することができます。元の Traffic Violations.xlsx(新しいウィンドウでリンクが開く) に接続すると、ピボット処理されたデータ セットにとてもよく似ています。とても大切な [Infraction Number (違反数)] フィールドがないだけです。LOD 表現を使用して集計ステップの結果を真似る必要があります。
注: ソリューションを背景と合わせて確認するには、LOD Driver Infractions.twbx(新しいウィンドウでリンクが開く) のワークブックをダウンロードできます。分析を解釈する、または解答を求める他の方法もある可能性があることに留意してください。
1.各ドライバーでの 1 回目の違反から 2 回目の違反までの日数の長さはどれほどか。
この質問に Tableau Desktop で答えるには、DATEDIFF
関数を再度使用します。この関数には開始日と終了日が必要です。この情報はデータに入っていますが、すべてが 1 つのフィールドにあります。それを 2 つのフィールドに分ける必要があります。これらの値の両方を各ドライバーで比較可能であることを確認したいので、[Driver ID (ドライバー ID)] のレベルで修正する必要があります。
最初の違反日を見つけるには、以下の計算を使用します。
"1st Infraction (1 回目の違反)" = { FIXED [Driver ID] : MIN ( [Infraction Date] ) }
次に、2 回目の違反日でも行います。
初めに、最初の日付より大きな日付のみを確認する必要があります。
IF [Infraction Date] > [1st Infraction] THEN [Infraction Date] END
しかし、このようにすると最初の違反後のすべての違反が表示されてしまいます。必要なのは 2 回目の違反のみです。つまり、これらの日付のうち最小のものが必要です。全体を MIN で次のように囲います。
MIN( IF [Infraction] : [1st Infraction] THEN [Infraction Date] END )
各ドライバーで 2 回目の違反日を再計算する必要もあります。ここで LOD 表現を使用します。これを [Driver ID (ドライバー ID)] のレベルに修正します。
"2nd Infraction (2 回目の違反)" = { FIXED [Driver ID] : MIN ( IF [Infraction Date] > [1st Infraction] THEN [Infraction Date] END ) }
また、DATEDIFF
計算を作成できるようになりました。
"Time Between Infractions (違反から違反までの期間)" = DATEDIFF('day', [1st Infraction], [2nd Infraction])
結果は、他の 2 つのデータ構造での結果と同じになります。
2.1 回目の違反と 2 回目の違反の罰金額を比較する。相関しているか。
この質問に Tableau Desktop で答えるには、この質問のピボット処理されたデータのバージョンと似た論理を使用します。指定した行が 1 回目の違反か 2 回目の違反かを特定するために、質問に対して作成した [1st Infraction (1 回目の違反)] と [2nd Infraction (2 回目の違反)] を使用し、適宜罰金額を取り出します。
散布図を作成したいだけの場合は、以下のように LOD 部分を省略し、IF
計算のみを使用します。
"1st Fine Amount (1 回目の罰金額)" = IF [1st Infraction] = [Infraction Date] THEN [Fine Amount] END
"2nd Fine Amount (2 回目の罰金額)" = IF [2nd Infraction] = [Infraction Date] THEN [Fine Amount] END
ただし、1 人のドライバーの 1 回目の罰金額と 2 回目の罰金額を比較し、差を確認する場合は、最初のデータ構造と同様に問題が発生し、NULL となります。これらの計算を FIXED LOD で囲んでも問題は起こらないため、最初からそのようにするのが賢明かもしれません。
"1st Fine Amount (1 回目の罰金額)" = { FIXED [Driver ID] : MIN ( IF [1st Infraction] = [Infraction Date] THEN [Fine Amount] END
) }
"2nd Fine Amount (2 回目の罰金額)" = {FIXED [Driver ID] : MIN( IF [2ndInfraction] = [Infraction Date] THEN [Fine Amount] END
) }
結果は、他の 2 つのデータ構造での結果と同じになります。
3.支払額が全体で最も多いのはどのドライバーか。支払額が最も少ないのは誰か。
この質問に Tableau Desktop で答えるには、LOD のみの方法に関し、まず認識が必要な点があります。Tableau Prep を使用するどちらの方法でも、ドライバーの 1 回目の違反や 2 回目の違反でない記録がフィルターにより見つかります。Tableau Desktop で LOD を使用する方法では、すべての記録が保持されます。つまり、[Driver ID (ドライバー ID)] 別に [SUM(Amount Paid) (SUM(合計支払額))] の Viz を作成すると、Tableau Desktop のみのバージョンでは、違反が 2 回以上あるドライバーのより高い額が表示されます。他の方法に一致する完全なデータから [Total Amount Paid (合計支払額)] の値を取得するには、元の [Fine Amount (罰金額)] フィールドを使用するのではなく、最初のデータ構造で行ったように、1 回目と 2 回目の罰金額を合計する必要があります。
質問 2 で作成したフィールドを使用して、2 つの罰金額を追加します。ZN
は、違反が 1 回しかないドライバーの結果が NULL になるのを防ぐために必要です。計算は以下の通りとなります。
"Total Amount Paid (合計支払額)" = [1st Fine Amount] + ZN([2nd Fine Amount])
結果は、他の 2 つのデータ構造での結果と同じになります。
4.違反の種類が複数あるドライバーは何名いるか。
この質問に Tableau Desktop で答えるために、単に [Driver ID (ドライバー ID)] および [Infraction Type (違反の種類)] の [個別カウント] を作成することはできません。このデータ セットには 2 回目を超える違反が含まれているため、ドライバーによっては 2 つ以上の違反の種類がある場合があります。結果を他の方法と一致させるには、範囲を最初の 2 回の違反だけに制限する必要があります。
1 回目と 2 回目の違反の種類を取り出し、それを LOD 表現の FIXED
でドライバーを囲んでから、IF
計算を使用して種類をカウントします。
"1st Infraction Type (1 回目の違反の種類)" = { FIXED [Driver ID] : MIN ( IF [1st Infraction] = [Infraction Date] THEN [Infraction Type] END ) }
"2nd Infraction Type (2 回目の違反の種類)" = { FIXED [Driver ID] : MIN ( IF [2nd Infraction] = [Infraction Date] THEN [Infraction Type] END ) }
"Number of Infraction Types (違反の種類の数)" =
IF [1st Infraction Type] = [2nd Infraction Type] THEN 1
ELSEIF [1st Infraction Type] != [2nd Infraction Type] THEN 2
ELSE 1 END
注: より大きな計算の中で最初の計算を直接入れ子にすることにより、これらの計算の多くを単一のフィールドとして作成することもできます。ここで、組み合わせた計算は以下のようになります。
IF
{FIXED [Driver ID] : MIN(IF [1st Infraction]=[Infraction Date] THEN [Infraction Type] END)}
=
{FIXED [Driver ID] : MIN(IF [2nd Infraction]=[Infraction Date] THEN [Infraction Type] END)}
THEN 1
ELSEIF
{FIXED [Driver ID] : MIN(IF [1st Infraction]=[Infraction Date] THEN [Infraction Type] END)}
!=
{FIXED [Driver ID] : MIN(IF [2nd Infraction]=[Infraction Date] THEN [Infraction Type] END)}
THEN 2
ELSE 1
END
意味を理解するのは少し難しいですが、必要なときには上手く機能します(改行やいくらかのスペースがあっても、Tableau による計算の解釈に影響はありません)。
[Number of Infraction Types (違反の種類の数)] を [Driver ID (ドライバー ID)] に対してプロットし、棒グラフを並べ替えることができます。
結果は、他の 2 つのデータ構造での結果と同じになります。
5.交通違反者講習会に参加したことのないドライバーでの平均罰金額がいくらか。
この質問に Tableau Desktop で答えるには、一部のドライバーでは違反が 1 回のみのため、単純に合計罰金額を 2 で割ることはできません。また、平均を平均すると矛盾が起こる可能性があるため、ドライバーあたりの平均罰金額を計算し、その値の平均を利用することもできません。別の方法としては、交通違反者講習会に参加したことのないドライバーが支払った合計金額を計算し、それらの罰金額に関連している合計違反数で割ります。
まず、各ドライバーに 2 回目の違反があったかを判断します。2 回目の違反がない場合は「2 回目」のすべてのフィールドに含まれる情報が NULL になるという点を活用し、以下の計算を作成し始めることができます。
IFNULL([2nd Infraction Type], 'no')
違反が存在する場合には 1 つの違反の種類が返され、2 回目の違反がない場合には "no" が返されます。
次に、この情報を違反数である 1 または 2 に変換する必要があります。IFNULL
の計算結果が "no" の場合、そのドライバーは 1 つの違反ありとマークします。その他の結果に関しては、2 つの違反ありとマークします。計算は以下の通りとなります。
"Number of Infractions (違反数)" =
IF IFNULL([2nd Infraction Type], 'no') = 'no' THEN 1
ELSE 2
END
[Total Amount Paid (合計支払額)] に関しては、質問 3 の計算を使用することができます。すべてまとめるには、この合計罰金額を新しい [Number of Infractions (違反数)] 計算フィールドで割り、平均罰金額を求めます。
"Average Fine (平均罰金額)" = SUM([Total Amount Paid]) / SUM([Number of Infractions])
交通違反者講習会に参加したことのあるドライバーをフィルターにより見つける必要もあります。データ セットには 3 回目や 4 回目の違反があるドライバーが含まれているため、ピボット処理されたデータ構造と同じ方法を使用することはできません。代わりに、ピボット処理していないデータでの場合と同じ方法に従います。概要は以下の通りです。
まず、1 回目と 2 回目の違反が交通違反者講習会と関連しているかどうかを特定する 2 つの計算を作成する必要があります。
"1st Traffic School (1 回目の交通違反者講習会)" = { FIXED [Driver ID] : MIN (IF [1st Infraction] = [Infraction Date] THEN [Traffic School] END ) }
"2nd Traffic School (2 回目の交通違反者講習会)" = { FIXED [Driver ID] : MIN (IF [2nd Infraction] = [Infraction Date] THEN [Traffic School] END ) }
その後、それらの値を追加し、交通違反者講習会の全体の参加回数を取得します。
"Number of Traffic School Attendances (交通違反者講習会の参加回数)" =
(CASE [1st Traffic School] WHEN 'Yes' THEN 1 WHEN 'No' THEN 0 ELSE 0 END)
+
(CASE [2nd Traffic School] WHEN 'Yes' THEN 1 WHEN 'No' THEN 0 ELSE 0 END)
[Number of Traffic School Attendances (交通違反者講習会の参加回数)] を [データ] ペインの [ディメンション] エリアにドラッグすると、0 ~ 2 の値は不連続になります。
ここで [Number of Traffic School Attendances (交通違反者講習会の参加回数)] に対してフィルターを実行すると、0 のみを選択し、交通違反者講習会に参加したことのないドライバーを把握することができます。
当初の質問への解答は、[Average Fine (平均罰金額)] を [マーク] カードの [テキスト] シェルフに移動するだけで得られます。集計を計算に組み込んでいるため、フィールドの集計は AGG になり、変更することができません。これは想定内の動作です。
結果は、他の 2 つのデータ構造での結果と同じになります。
このソリューションには多数の入れ子の計算と LOD 表現があることに留意することが重要です。データ セットのサイズやデータの複雑さによっては、パフォーマンスが問題となることがあります。
では、どの方法を採用すべきでしょうか。すべてはユーザーやユーザー使用可能なツールにかかっています。
LOD を使用しない場合にはデータを加工するソリューションがありますが、分析によっては計算が必要となることがあります (Tableau Desktop での分析)。
データを加工することができ、計算 (LOD を含む) に精通しているのであれば、無難なオプションを使用することで最適な柔軟性が得られます (詳しく—ピボット処理されたデータ)。
LOD に精通しているのであれば、パフォーマンスへの影響は最小限です。Tableau Prep を使用しなくしても、LOD 単独でこれを解決するというオプションもあります (さらに詳しく—計算のみ)。
少くとも、Tableau Prep での集計や Tableau Desktop での詳細レベル表現がどのように相互に関係しているかを理解し、データ分析に影響するかを理解することは重要です。Tableau での多くの場合と同様、何をするにも方法は 1 つではありません。さまざまなオプションをすべて調べると、概念を取り合わせ、自分に最適なソリューションを選択することができます。
使用した計算は以下の通りです。
ドライバーの違反
"Time Between Infractions (違反から違反までの期間)" = DATEDIFF('day', [1st Infraction Date], [2nd Infraction Date])
"Total Amount Paid (合計支払額)" = [1st Fine Amount] + ZN([2nd Fine Amount])
"Number of Infraction Types (違反の種類の数)" = IF [1st Infraction Type]=[2nd Infraction Type] THEN 1 ELSEIF [1st Infraction Type]!= [2nd Infraction Type] THEN 2 ELSE 1 END
"Number of Infractions (違反数)" = IF IFNULL([2nd Infraction Type], 'no') = 'no' THEN 1 ELSE 2 END
"Average Fine (平均罰金額)" = ( SUM([1st Fine Amount]) + SUM( ZN([2nd Fine Amount]) ) ) / SUM([Number of Infractions])
"Number of Traffic School Attendances (交通違反者講習会の参加回数)" = (CASE [1st Traffic School] WHEN 'Yes' THEN 1 WHEN 'No' THEN 0 ELSE 0 END) + (CASE [2nd Traffic School] WHEN 'Yes' THEN 1 WHEN 'No' THEN 0 ELSE 0 END)
ピボット処理されたドライバーの違反
"1st Infraction (1 回目の違反)" = {FIXED [Driver ID] : MIN(IF [Infraction Number] = "1st" THEN [Infraction Date] END)}
"2nd Infraction (2 回目の違反)" = {FIXED [Driver ID] : MIN(IF [Infraction Number] = "2nd" THEN [Infraction Date] END)}
"Time Between Infractions (違反から違反までの期間)" = DATEDIFF('day', [1st Infraction], [2nd Infraction])
"1st Fine Amount (1 回目の罰金額)" = {FIXED [Driver ID] : MIN( IF [Infraction Number] = "1st" THEN [Fine Amount] END ) }
"Number of Infractions (違反数)" = IF IFNULL(STR([2nd Infraction]), 'no')= 'no' THEN 1 ELSE 2 END
"Average Fine (平均罰金額)" = SUM([Fine Amount])/SUM([Number of Infractions])
"Attended Traffic School (交通違反者講習会に参加あり)" = { FIXED [Driver ID] : MAX( CONTAINS([Traffic School], 'Yes'))}
LOD のドライバーの違反
"1st Infraction (1 回目の違反)" = {FIXED [Driver ID] : MIN([Infraction Date])}
"2nd Infraction (2 回目の違反)" = { FIXED [Driver ID] : MIN( IF [Infraction Date] > [1st Infraction] THEN [Infraction Date] END ) }
"Time Between Infractions (違反から違反までの期間)" = DATEDIFF('day', [1st Infraction], [2nd Infraction])
"1st Fine Amount (1 回目の罰金額)" = {FIXED [Driver ID] : MIN( IF [1st Infraction] = [Infraction Date] THEN [Fine Amount] END ) }
"2nd Fine Amount (2 回目の罰金額)" = {FIXED [Driver ID] : MIN( IF [2nd Infraction] = [Infraction Date] THEN [Fine Amount] END ) }
"Total Amount Paid (合計支払額)" = [1st Fine Amount] + ZN([2nd Fine Amount])
"1st Infraction Type (1 回目の違反の種類)" = {FIXED [Driver ID] : MIN( IF [1st Infraction] = [Infraction Date] THEN [Infraction Type] END ) }
"2nd Infraction Type (2 回目の違反の種類)" = {FIXED [Driver ID] : MIN( IF [2nd Infraction] = [Infraction Date] THEN [Infraction Type] END ) }
"Number of Infraction Types (違反の種類の数)" = IF [1st Infraction Type]=[2nd Infraction Type] THEN 1 ELSEIF [1st Infraction Type]!= [2nd Infraction Type] THEN 2 ELSE 1 END
"Number of Infractions (違反数)" = IF IFNULL([2nd Infraction Type], 'no') = 'no' THEN 1 ELSE 2 END
"Average Fine (平均罰金額)" = SUM ([Total Amount Paid]) / SUM([Number of Infractions])
"1st Traffic School (1 回目の交通違反者講習会)" = {FIXED [Driver ID] : MIN (IF [1st Infraction] = [Infraction Date] THEN [Traffic School] END ) }
"2nd Traffic School (2 回目の交通違反者講習会)" = {FIXED [Driver ID] : MIN (IF [2nd Infraction] = [Infraction Date] THEN [Traffic School] END ) }
"Number of Traffic School Attendances (交通違反者講習会の参加回数)" = (CASE [1st Traffic School] WHEN 'Yes' THEN 1 WHEN 'No' THEN 0 ELSE 0 END) + (CASE [2nd Traffic School] WHEN 'Yes' THEN 1 WHEN 'No' THEN 0 ELSE 0 END)
注: Ann Jackson の Workout Wednesday のトピック「顧客の購入額は 1 回目と 2 回目のどちらが多いか」(英語)(新しいウィンドウでリンクが開く) および Andy Kriebel の Tableau Prep のヒント「1 回目と 2 回目の購入日を求める」(英語)(新しいウィンドウでリンクが開く) は今回のチュートリアルに関し、最初の着想を与えるものとなりました。深く感謝申し上げます。これらのリンクをクリックすると、Tableau Web サイトから離れます。Tableau は外部プロバイダーによって管理されているページの正確さや最新度に関して責任を負いかねます。コンテンツに関するご質問はサイトの所有者にお問い合わせください。