LAG関数を使用したプログラムの注意点
[OS]ALL
[リリース] 6.09e, 6.12, 8.1, 8.2
[キーワード] lag
[質問]LAG関数をIFステートメントの中で使用している場合、結果が期待と異なる場合があります。なぜでしょうか。
[回答]
この現象は、LAG関数は、キューの操作、つまり値の保存を「実行されたときだけ行なう」という性質を持っているためです。LAG関数は、nオブザベーション前の値を返すのではなく、LAG関数を実行するたびに蓄積されたキューのn個前の値を返します。nオブザベーション前の値を取得するには、LAG関数を毎回実行して全ての値をキューに蓄積する必要があります。 (例1) DATA lag ; INPUT chiku $ month kion ; dif = kion - LAG1(kion) ; IF MOD(month,2) = 0 THEN dif2 = kion - LAG2(kion) ; DATALINES; 北海道 1 -20 北海道 2 -18 北海道 3 0 北海道 4 10 北海道 5 20 北海道 6 15 北海道 7 20 北海道 8 28 北海道 9 22 北海道 10 17 北海道 11 10 北海道 12 2 ; RUN;(例1で作成されたデータセットlagの内容) month kion dif dif2 (期待していたdif2の結果) 1 -20 . . 2 -18 2 . ← . = -18 - . 3 0 18 . 4 10 10 . ← 28 = 10 - (-18) 5 20 10 . 6 15 -5 33 ← 5 = 15 - 10 7 20 5 . 8 28 8 18 ← 13 = 28 - 15 9 22 -6 . 10 17 -5 2 ← -11 = 17 - 28 11 10 -7 . 12 2 -8 -26 ← -15 = 2 - 17 上記の結果からわかるように、dif2の結果は2月前のものではなく、「2回前にLAG関数により保存された値との計算結果」となっています。 month kion dif2 (実際のdif2の計算) 1 -20 . 2 -18 . = -18 - . 3 0 . 4 10 . = 10 - . (2回前のLAGは存在しない) 5 20 . 6 15 33 = 15 - (-18) (2回前のmonth=2で保存された値) 7 20 . 8 28 18 = 28 - 10 (2回前のmonth=4で保存された値) 9 22 . 10 17 2 = 17 - 15 (2回前のmonth=6で保存された値) 11 10 . 12 2 -26 = 2 - 28 (2回前のmonth=8で保存された値) 期待しているとおりの結果を出力させる場合は、次のようなプログラムを実行します。 (例2) DATA lag ; INPUT chiku $ month kion ; dif = kion - LAG1(kion) ; dif2 = kion - LAG2(kion) ; IF MOD(month,2) THEN dif2 = . ; /* 奇数月の場合は欠損値 */ DATALINES; 北海道 1 -20 北海道 2 -18 北海道 3 0 北海道 4 10 北海道 5 20 北海道 6 15 北海道 7 20 北海道 8 28 北海道 9 22 北海道 10 17 北海道 11 10 北海道 12 2 ; RUN;(例2で作成されたデータセットlagの内容) month kion dif dif2 1 -20 . . 2 -18 2 . 3 0 18 . 4 10 10 28 5 20 10 . 6 15 -5 5 7 20 5 . 8 28 8 13 9 22 -6 . 10 17 -5 -11 11 10 -7 . 12 2 -8 -15
|