ハッシュオブジェクトとDS2ハッシュパッケージの差異_定義周りについて

さて、通常のデータステップではハッシュオブジェクトを利用することができます。
一方、DS2にはハッシュパッケージというものがあります。

実際に使ってみるとわかりますが、まあ、基本ほぼ同じといってしまっていいと思います。
データステップからDS2は随分違うというか、別言語ですが、ハッシュオブジェクトとハッシュパッケージはノリが同じです。
ハッシュオブジェクトをある程度使っている方であれば、ほとんど勉強しなおさなくても
同じ感覚で使いこなせると思います。

しかし、全く同じというわけではないので、あまり体系だてては無理ですが、、少しずつ解説していきたいと思います。

ただ、残念ながら僕もまだ勉強中で、半分、自分の学習のために記事を書いていくので、内容に誤りがあったり、もっといいやり方を見つけた場合は、後日、別記事で修正、更新しますのでそこはあしからずです。

今日はハッシュオブジェクトの宣言部分と、ハッシュパッケージの宣言部分を並べて見比べてみましょう。

例えば以下のデータセットQ1があって、

data Q1;
A=1;B=2;C='A';D=5;output;
A=2;B=3;C='B';D=6;output;
A=3;B=4;C='C';D=7;output;
A=1;B=2;C='D';D=8;output;
run;

そのデータセットをハッシュオブジェクト(パッケージ)の中にA Bをキー、 A B C Dをデータとして定義して、重複キーを許容した上でキー値でソートして格納して、別データセットに出力という、ソートプロシジャ使えよっ!ていう感じの、処理としてはあまり意味のないものを例にします(結果はすべて同じなので画像は割愛)。

まずハッシュオブジェクトで書くなら以下の感じでしょうか

data _NULL_;
if 0 then set Q1;
declare hash h1(dataset:'Q1',multidata:'YES',ordered:'YES');
h1.definekey('A','B');
h1.definedata('A','B','C','D');
h1.definedone();
h1.output(dataset:'A1');
stop;
run;

一方、DS2で書く場合、以下のようにかけます

proc ds2 libs=work;
data _NULL_;
declare double A B D;
declare char C;
declare package hash h1();
method init();
h1.dataset('Q1');
h1.definekey('A');
h1.definekey('B');
h1.definedata('A');
h1.definedata('B');
h1.definedata('C');
h1.definedata('D');
h1.multidata('YES');
h1.ordered('YES');
h1.defineDone();
h1.output('A2');
end;
enddata;
run;
quit;

おおっ、なかなか面白いですね。ハッシュオブジェクトでdataset:のように指定していた(タグパラメータ)の部分が独立してメソッドになっているんですね。これはこっちの方が書きやすいし、構造を把握しやすいです。

しかし、multidataやorderedのようなオプションで1回設定するようなものはさておき、keyやdataを1個1個メソッドで指定するのは流石に面倒なので、そこについてはkeysメソッドとdataメソッドというものが別途準備されていて、これは変数リストを指定できるので、以下のようにかけます。

proc ds2 libs=work;
data _NULL_;
declare double A B D;
declare char C;
declare package hash h1();
method init();
h1.dataset('Q1');
h1.keys([A B]);
h1.data([A B C D]);
h1.multidata('YES');
h1.ordered('YES');
h1.defineDone();
h1.output('A3');
end;
enddata;
run;
quit;

さらに僕はこの書き方はあまり好きではありませんが、ハッシュパッケージを宣言するdeclare packageのところでカッコ内に順番に引数を設定することで、以下の定義メソッドでやることと同じことをまかなえるようになってます

文法としては

declare package hash 任意のハッシュ名(キー変数,データ変数,ハッシュ割当サイズ,格納するデータセット名または{SQLソース},ordered,duplicate,suminc,multidata);

となっています。つまり今回の場合であれば以下のようにもかけます。

proc ds2 libs=work;
data _NULL_;
declare double A B D;
declare char C;
declare package hash h1([A B],[A B C D],8,'Q1','YES','','','YES');
method init();
h1.output('A4');
end;
enddata;
run;
quit;

上記の引数で指定する書き方は、キー変数とデータ変数の部分を省略したり、データ変数省略したりなど亜種の書き方があって計4種類の指定の仕方があるのですが、その辺については興味のある方はリファレンスのなどで調べてみてください。
引数が何を意味しているかわかりにくいのでこの書き方はあんまりだと思いますが。

僕がまだ解決できていない疑問はoutputメソッドの際に、overwrite指定ができないのかなってとこです。
それは困るけどなぁ。事前にproc deleteでもしろってことかなぁ。どなたか何か知ってたら教えてください。



0 件のコメント:

コメントを投稿