ハッシュオブジェクトの世界② addメソッド

まず、この記事の前に「ハッシュオブジェクトの世界①」を読んでください。
http://sas-tumesas.blogspot.jp/2014/07/blog-post_11.html

さて、前回は作成したハッシュオブジェクトの中に、データセットを突っ込んで、それをマッチングに使いました。

しかし、ハッシュオブジェクトに情報(データっていうとハッシュオブジェクトのkey,dataのデータと混同しちゃうので)を入れる場合、別にそれがデータセットでなくても大丈夫です。

ハッシュオブジェクトに情報(keyとデータ)を挿入するのがaddメソッドです。

ハッシュオブジェクトのメリットの1つは、データステップの途中でハッシュオブジェクトの中身を増やしたり減らしたり変えたりできること、そしてデータステップから吸い上げた情報と、直接メソッドで挿入した情報を一緒に扱える柔軟性です。
それは、いわばハッシュオブジェクトが縦持ち構造だから可能なわけです。
例えばARRAY配列の場合、一度定義した後に、要素数をステップの途中で変えながら処理はできないはずです(中身は変更できますが)

では、「ハッシュオブジェクトの世界①」の処理と同じ処理を、Q2からデータを吸い上げずに、直接データを打つ形でやってみましょう。


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 A1;
length X 8. Y Z $2.;
 if _N_=1 then do;
  declare hash hq1();
   hq1.definekey('X','Y');
   hq1.definedata('Z');
   hq1.definedone();
   hq1.add(key:1,key:'A',data:'い');
   hq1.add(key:2,key:'A',data:'ろ');
   hq1.add(key:2,key:'B',data:'は');
  end;
 set Q1;
  rc=hq1.find();
  if rc^=0 then Z='';
run;

です。

前回のコードと見比べてみてください。
まず、「if _N_=0 then set Q2;」が「length X 8. Y Z $2.;」になってます。
これは今回はQ2を使わないので、変数の初期化問題を解決するためにlengthステートメントで
変数情報を定義しているわけです。

続いて「declare hash hq1(dataset:'Q2');」が「declare hash hq1();」になっています。そりゃそうだ。
注意点は、内容がない場合でも空括弧は必須だということです。普段のデータセットオプションのノリで、指定するものがないからって省くとエラーです。

次に「hq1.definedone();」の後に3行

   hq1.add(key:1,key:'A',data:'い');
   hq1.add(key:2,key:'A',data:'ろ');
   hq1.add(key:2,key:'B',data:'は');

とあります。これがaddメソッドです。
まあ、見れば何となく何しているかはわかるはずです。
挿入する内容の前にkeyであるのかdataであるのかを必ずつけます。コロン:を使うのが意表を
ついた感じするので注意です。
keyやdataが複数ある場合、順番はdefinekeyやdefinedataメソッドで指定した順と同期します。

結果は前回と同じなので省きます。



ちなみに、この辺がハッシュの柔軟なところでもあり、混乱するところでもあるのですが、次のようにも書けます。

data A2;
length X 8. Y Z $2.;
 if _N_=1 then do;
  declare hash hq1();
   hq1.definekey('X','Y');
   hq1.definedata('Z');
   hq1.definedone();
   X=1;Y='A';Z='い';
   hq1.add();
   X=2;Y='A';Z='ろ';
   hq1.add();
   X=2;Y='B';Z='は';
   hq1.add();
  end;
 set Q1;
  rc=hq1.find();
  if rc^=0 then Z='';
run;

のようにhq1.add();と空指定する直前に対応する変数が通常のデータステップ領域(PDV)にあれば
変数名で対応するハッシュオブジェクトのkey dataに情報を格納してくれます。

これでも結果は同じです。


最後に、①で使ったQ2と、addメソッドで加えた情報を両方ハッシュオブジェクトに入れた上でマッチングする例であれば次のようにできます。

data Q2;
 X=1;Y='A';Z='い';output;
 X=2;Y='A';Z='ろ';output;
 X=2;Y='B';Z='は';output;
run;


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();
   hq1.add(key:3,key:'A',data:'に');
  end;

 set Q1;
  rc=hq1.find();
  if rc^=0 then Z='';
run;


とすると、今までnullだった組み合わせが追加されたので結果は









となります。


この辺で、ハッシュオブジェクトがただ単に高速化のための技術ではなく、むしろ高速化は
おまけで、柔軟性がやばいんじゃないの?と感じてくれればうれしいです。


さて、最近更新頻度が落ちていましたが、
ふと気がつくと今まで投稿した記事の数が200を超えていました。

正直ここまでネタが続くとは思っていませんでした。これも色んな方から日々刺激をいただいているおかげです。コメントやメッセージは僕自身の勉強と、次の記事のネタになるにで常に大歓迎です。
またリンクサイト様からも日々刺激とアイデアを受けて、内容をパクらせていただくことで、ネタ切れせずに生きながらえています。

なので、今さらですが、このブログはリンクフリーです。ただ、こちらからもぜひリンクさせていただきたいのでご連絡はいただけるに越したことはないです。
また何か論文等の参考先に記載していただくのも全然構いません。


僕は、これからもまたあまり役に立たないコードを垂れ流していこうと思います。







0 件のコメント:

コメントを投稿