MERGEステートメントの使用方法

[OS]ALL
[リリース] 5.18, 6.07, 6.08, 6.09, 6.10
[キーワード] base, datastep, merge, by, same, variable, name, rename=

[質問]

SASデータセット[MASTER]と[TRAN]には共通の変数KEYとNUMがあります。[TRAN]の内容で[MASTER]を更新したいのですが、[MASTER]にはKEY変数が同じオベザベーションが複数存在するためUPDATEステートメントは使えません。そこで、MERGEステートメントを使いましたが、各KEY変数の2番目以降のオブザベーションは更新されず、元の値のままになってしまいます。どうすればよいでしょうか。

  [MASTER]      [TRAN]         [希望の結果]     [実際の結果]
  KEY  NUM     KEY  NUM         KEY  NUM       KEY  NUM
   A     1      A   100          A   100        A   100
   A     2      B   200   ==>    A   100        A     2
   B     1                       B   200        B   200
   B     2                       B   200        B     2
   C     1                       C     1        C     1


[回答]

まず、うまく更新できない理由から説明します。次のプログラムを実行すると[実際の結果]が得られます。

  data wrong;
    merge MASTER TRAN;
    by key;
  run;

第1オブザベーションの処理時は、まず[MASTER]のオブザベーション、次に[TRAN]のオブザベーションが読み込まれます。 この順序で読み込まれるため、NUMの値は100となります。 第2オブザベーションの処理を開始したときは、DATAステップの次のルールによって、NUMの値は100のままです。

[MERGE/BYステートメントを組み合わせて読み込むSASデータセット中の変数値は、BYグループが変るとき以外は初期化されない。]

ところが、第2オブザベーションの処理に入ると、MASTERの第2オブザベーションだけが読み込まれ、NUMの値は2になってしまいます。
さて、上のルールを理解すれば、[いったん別の変数として読み込めばよい]ということに気がつきます。次のプログラムを見てください。

  data correct;
    merge MASTER TRAN(rename=(NUM=NUM2));
    by key;
    drop NUM2;
    if NUM2 ne . then NUM=NUM2;
  run;

このプログラムでは、[TRAN]の変数NUMを変数NUM2として読み込んでいます。変数NUM2は各グループの先頭で読み込まれ、グループの処理中はその値を維持します。
また、[MASTER]のデータCのように、読み込めるオブザベーションがないときは、その値は欠損値となります。そこで、変数NUM2が欠損値でないときにだけ値を変数NUMにコピーすれば、期待する処理結果が得られます。変数NUM2の値の動きを実際に確認する場合は、DROPステートメントを削除して実行してください。