通常のMergeとDS2のMergeは別物という話

当初DS2プロシジャがリリースされた時,なんと文法からMergeステートメントが廃されてました.データの結合は,内部埋め込みできるFedSQLやHash Packageでも使いなさいという思い切った仕様でした

個人的には,左側外部結合の多い医薬分野の自分のプログラムの範囲では,SASにMergeステートメントは必要ない,基本ハッシュオブジェクトがあればいい,SQLの方が性にあるというならjoinする人がいても良いという過激思想なので(人に押し付けるつもりはないですが…笑)

当時は思い切ったことをしたものだと感心しました.
まあ,DS2の場合,基本的に内部処理のベースがSQLで行われているようで,byの挙動などもSQLのorder by,group byに準じていたりするので,SAS固有の特殊な挙動をするMergeステートメントを親和させれたなったんだろうなぁと推察してました

ただ,やはりちょっと思い切り過ぎたのでしょうかね,メンテナンスリリース3あたりで,突如DS2にもMergeが搭載されました.旧来のユーザーからの要望?

ただ,やっぱり,本来仕組みの違うものに,組み込んだので,ちょっと注意が必要です.
まあ,基本的なケースでは同じ結果が返るので,使わない方がとまでは言わないのですが,知った上で気を付けて使ってくださいって話です

data T1;

length K 8. A B $20.;

K=101;A="Cat";B="Apple";output;

K=101;A="Pig";B="Banana";output;

K=102;A="Duck";B="Fig";output;

run;




data T2;

length K 8. A C $20.;

K=101;A="Cow";C="Red";output;

K=102;A="";C="Yellow";output;

K=103;A="";C="Blue";output;

run;


旧来のデータステップのMergeであれば

data A1;

merge T1 T2;

by K;

run;


後続のデータが,先行の共通で変数バッティングするところを上書いていく,いかにもSASのマージっぽい結果ですね


一方,DS2のmergeはというと


proc DS2;

data A2 (overwrite=yes);

   method run();

      merge T1 T2;

      by K;

   end;

enddata;

run;

quit;

(ライブラリやSODの出力ビューが自動更新されないので,製品SASの場合はライブラリを切り替えて戻ってきて見るか,SODならライブラリ開いて確認できます)


ほぼ同じと見せかけて,Cの2行目が欠損なことに注目です.
T2に101のデータが1つしかないからこうなってます

SASの場合はkey一致分,全てに値がつくのですが,見方を変えると同key 前obsから値がretainされているとも解釈できます

そして,DS2のM5でMergeにretainオプションが追加され,これを使うと

proc DS2;

data A3 (overwrite=yes);

   method run();

      merge T1 T2 / retain;

      by K;

   end;

enddata;

run;

quit;








おっ,今度はCの2行目に値がはいった!
しかし実はよく見ると,これも旧来のデータステップの結果と違うのです
Aの2行目,1行目の値がそのままretainされています

というわけで,今までのmergeと同じ出力結果をだすのは中々に難しいのですね
挑戦してみると面白いかもですが,SQLで今回のデータステップのmergeと同じ結果だすの結構難しいはず

ただ,まあそれぞれの結果のどれが正しいという話ではないのですね.旧来の結果に見慣れてるので,DS2のマージはおかしいって言いたくなるのですが,それもあくまで仕様どおりにでてるだけということですね

0 件のコメント:

コメントを投稿