ハッシュオブジェクトの世界⑤ replaceメソッド key dataの指定に変数

ハッシュオブジェクトの中のレコードを増やしたり、減らしたり、消したりする方法を紹介してきました。

流れ的に予想ついているかもしれませんが、次はレコード数を変えずに、内容を変える方法です。

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 件のコメント:

コメントを投稿