流れ的に予想ついているかもしれませんが、次はレコード数を変えずに、内容を変える方法です。
data Q1;
X=1;Y='A';output;
X=2;Y='B';output;
X=1;Y='A';output;
X=2;Y='A';output;
X=3;Y='A';output;
run;
data Q2;
X=1;Y='A';Z='い';output;
X=2;Y='A';Z='ろ';output;
X=2;Y='B';Z='は';output;
run;
上記2つのデータセットを作ってから以下のコードを実行します
data A1;
if _N_=0 then set Q2;
if _N_=1 then do;
declare hash hq1(dataset:'Q2');
hq1.definekey('X','Y');
hq1.definedata('Z');
hq1.definedone();
hq1.replace(key:1,key:'A',data:'ほ');
hq1.replace(key:3,key:'A',data:'へ');
end;
set Q1;
rc=hq1.find();
if rc^=0 then Z='';
run;
すると結果は
となります。
hq1.replace(key:1,key:'A',data:'ほ');
によって、もともとX=1 Y=Aに対応するdataは「い」だったのが「ほ」に変えられました。
そのためfindメソッドに結果の1,3オブザベーション目のZの値は「ほ」になっているわけです。
次に
hq1.replace(key:3,key:'A',data:'へ');
ですが、ハッシュオブジェクトに存在しないkeyでreplaceメソッドを行うと、addメソッドと同じ、つまりそのレコードがハッシュオブジェクトに追加されます。
そのため5オブザベーション目に「へ」が入っているのです。
では、ハッシュオブジェクトに存在しないkeyの場合には、addするのではなくて、無視して欲しい場合はどうしましょうか?
これはもしからしたら他にやり方があるのかもですが、僕はcheckメソッドと組み合わせて以下のようにしています。
data A2;
if _N_=0 then set Q2;
if _N_=1 then do;
declare hash hq1(dataset:'Q2');
hq1.definekey('X','Y');
hq1.definedata('Z');
hq1.definedone();
if hq1.check(key:1,key:'A')=0 then
hq1.replace(key:1,key:'A',data:'ほ');
if hq1.check(key:3,key:'A')=0 then
hq1.replace(key:3,key:'A',data:'へ');
end;
set Q1;
rc=hq1.find();
if rc^=0 then Z='';
run;
こうすれば結果は
でOKです。
最後に、あまり例として意味がない処理ですが、通常のデータステップ中の変数を指定して
replaceする処理を。
奇数の行番号の場合、ハッシュオブジェクトのdataを_N_に変える処理です。
data A3;
if _N_=0 then set Q2;
if _N_=1 then do;
declare hash hq1(dataset:'Q2');
hq1.definekey('X','Y');
hq1.definedata('Z');
hq1.definedone();
end;
set Q1;
if mod(_N_,2)=1 then hq1.replace(key:X,key:Y,data:put(_N_,best. -L));
rc=hq1.find();
if rc^=0 then Z='';
run;
上のプログラムはかなり意味不な処理ですが、複数のデータセットを使ってハッシュオブジェクトの処理をする場合、あるデータセットの中身に基づいてハッシュの内容を変更し、変更されたハッシュを使って別のデータセットとマッチングしたりといったことが可能になるわけです。
0 件のコメント:
コメントを投稿