ロードスクリプトでの欠損値補完や累積値算出-Peek,Previous
はじめに
PeekやPreviousの関数を使うと、ロードスクリプトで既にロード済みのレコードの項目値を取得することができます。これらの関数は、ロード中のデータの一つ前のレコード値を参照するためなどに利用されます。ここでは、欠損値の補完と累積値の算出を行うケースを想定し、それらのケースにおいてPeekやPreviousの活用方法をご説明します。
欠損値の補完
では、まずサンプルデータを作成するために以下のロードスクリプトを実行します。
[レートテーブル]:
Load
日付,
曜日,
レート
Inline [
日付,曜日,レート
2016/02/01,月,0.5
2016/02/02,火,
2016/02/03,水,
2016/02/04,木,0.6
2016/02/05,金,0.8
2016/02/06,土,
2016/02/07,日,0.9
2016/02/08,月,
2016/02/09,火,0.7
2016/02/10,水,
] ;
このスクリプトを実行して作成される以下のレートテーブルにはレートの項目が含まれていますが、レートの変更があった日のレコードのみに値が格納されており、その他のレコードのレートには値が格納されていません。
この様なケースを想定し、Peek関数を使ってレートデータが欠損している場合には直前の日付(=一つ前のレコード)から取得して補完する処理を行います。
ここでは以下の赤字の部分の処理を追加しています。Ifの条件文で、Len(レート)=0(レート項目が空白)の場合はPeek関数で一つ前のレコードのレートデータを取得し、それ以外のレート項目に値が入っている場合にはそのままその値を出力する制御を行っています。
[レートテーブル]:
Load
日付,
曜日,
If(Len(レート)=0,Peek(レート), レート) AS レート
Inline [
日付,曜日,レート
2016/02/01,月,0.5
2016/02/02,火,
2016/02/03,水,
2016/02/04,木,0.6
2016/02/05,金,0.8
2016/02/06,土,
2016/02/07,日,0.9
2016/02/08,月,
2016/02/09,火,0.7
2016/02/10,水,
] ;
上記のスクリプトを実行すると、以下の形で欠損値が補完されてデータがロードされます。尚、今回は日付で既にソートされたデータを扱ってPeek関数で一つ前のレコード(=前日)を参照していますが、必要な形でソートされていない場合にはソートを行う必要があります。(Order By句を使ったソートの方法については「取り込み済みテーブルからのデータ読み取りと集計処理-Resident Load, Group By, Order By」で説明してます。)
累積値の算出
次に、以下のスクリプトを実行してサンプルデータを作成します。
[Temp_売上データ]:
Load * Inline [
日付,曜日,製品,売上
2016/02/01,月,製品A,100
2016/02/01,月,製品B,120
2016/02/02,火,製品A,130
2016/02/02,火,製品B,110
2016/02/03,水,製品A,90
2016/02/03,水,製品B,60
2016/02/04,木,製品A,140
2016/02/04,木,製品B,130
2016/02/05,金,製品A,180
2016/02/05,金,製品B,190
2016/02/06,土,製品A,110
2016/02/06,土,製品B,120
2016/02/07,日,製品A,80
2016/02/07,日,製品B,160
2016/02/08,月,製品A,100
2016/02/08,月,製品B,60
2016/02/09,火,製品A,150
2016/02/09,火,製品B,180
2016/02/10,水,製品A,170
2016/02/10,水,製品B,140
];
このスクリプトを実行して作成されるテーブルは以下となっており、日付と製品ごとの売上データが含まれています。
このデータに、日付と製品でグループ化して集計した累計値の列を追加したいと思います。尚、チャート側の計算で累積グラフを作成する方法は「Qlik Senseでの累積グラフの作成-RangeSum」のエントリでご紹介していますが、チャートでダイナミックに算出するのではなく、ここでは累積値をデータとして保持する必要があるケースに対応します。
以下のスクリプトを実行します。ここでは、上記のテーブルからResident Loadでデータを読み取り、「製品」と「日付」でソートしています。そして、Ifの条件文で「製品=Peek(製品)」の判別を行っています。ここで、現在のレコードの製品と、Peekで取得した一つ前のレコードの製品の値を比較しています。同じ場合には「売上+Peek(売上累積値)」で現在のレコードの売上と、一つ前のレコードの売上累積値を合算して現在のレコードの「売上累積値」に格納しています。製品の値が一つ前のレコードと異なる場合はそのまま現在のレコードの売上値を「売上累積値」に格納しています。これにより、製品を跨った時には売上累積値がリセットされます。
[売上データ]:
Load
日付,
曜日,
製品,
売上,
If(製品=Peek(製品), 売上+Peek(売上累積値), 売上) AS 売上累積値
Resident Temp_売上データ
Order By 製品,日付;
Drop Table Temp_売上データ;
また、最後にDrop Tableで元の「Temp_売上データ」を削除しています。
PeekとPreviousの違い
Qlik SenseにはPeekとPreviousという似た2つの関数が提供されており、これらはほぼ同様な動作となっていますが、以下の点のみが異なります。(「カウンターによる連番の追加-RowNo,RecNo」でご説明したRowNoとRecNoの違いと同様の考え方となっています。)
- Peek: Load文の出力データに対して作用する
- Previous: Load文の入力データに対して作用する
このエントリでご説明した利用方法ではいずれの関数を利用しても同様の結果となりますが、上記の形で作業する対象のデータが異なることからWhere句を使ってデータを絞り込む場合等では結果が異なります。
例えば、以下の形でWhere句で日曜日を除いた場合のPeekとPreviousの結果を比較してみます。
[売上データ]:
Load
日付,
曜日,
Peek(日付) AS Peek,
Previous(日付) AS Previous
Resident Temp_売上データ
Where 曜日 <> '日'
Order By 日付;
この場合、Peekでは日曜日を除いた土曜日の日付を取得していますが、Previousでは日曜日が除かれる前の日曜日の日付を取得していることが分かります。
まとめ
このエントリでは欠損値の補完と累積値の算出を行うケースの例を通じてPeekとPreviouの利用方法をご説明しました。