DS2プロシジャでは、byステートメントを入れるだけで、自動でソートが発生する。ただ、細かいけど、そのソートはproc sortじゃなくてsqlのorder byという話

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

data Q1;
x=2;y=6;output;
x=1;y=1;output;
x=2;y=5;output;
x=2;y=7;output;
x=3;y=1;output;
x=1;y=2;output;
run;














以下のようにx yでsortして、first lastを利用して条件式をかくと

proc sort data=Q1 out=_Q1;
by x y;
run;
data A1;
set _Q1;
by x y;
if ^first.x and ^last.x then FL=1;
run;













といった処理ができます。

これをDS2でやる場合ですが、DS2では事前にデータセットをsortプロシジャにかけておかなくても
byステートメントに指定するだけで、勝手にsetに指定されているデータセットがsortされます。

つまり

proc ds2 libs=work;
data A2(overwrite=yes);
declare double FL;
method run();
set Q1;
by x y;
if ^first.x and ^last.x then FL=1;
end;
enddata;
run;
quit;

で同じ結果になります。

書きやすいですね~!ただ、コード上でproc sortがなくなったとはいえ、それで実行が早くなりはしません。結局、裏でsetするデータセットにソートかけてますから。

イメージ的にはbyをつけると、set Q1がset {select * from Q1 order by X,Y}に解釈されて
実行されるイメージですね。

で、勘のよい方は気づいているかもしれませんが、実はproc sortとproc sql のorder byのソートアルゴリズムは異なります。

それはSAS社のFAQでも紹介されています

http://www.sas.com/offices/asiapacific/japan/service/technical/faq/list/body/ba093.html

でDS2のソートも含めて、SAS社の例で3つのソートの結果を比較してみましょう

DATA test1 ;
     INPUT var1 var2 $ var3 $ ;
     DATALINES ;
     2 BBB  2_BBB_3
     1 BBB  1_BBB_1
     2 AAA  2_AAA_2
     2 AAA  2_AAA_1
     1 BBB  1_BBB_2
     2 BBB  2_BBB_4
     2 BBB  2_BBB_2
     2 BBB  2_BBB_1
     1 AAA  1_AAA_2
     1 AAA  1_AAA_1
     1 BBB  1_BBB_3
     ;
     RUN ;

     PROC SORT DATA=test1 OUT=test2;
       BY var1 var2 ;
     RUN ;
     title "sortプロシジャ";
     proc print data=test2 noobs;
     run;

     title "sqlプロシジャ order by";
     PROC SQL ;
       SELECT * FROM test1 
       ORDER BY var1,var2 ;
     QUIT ;
     
     title "DS2プロシジャ by";
proc ds2 libs=work;
data test3(overwrite=yes);
method run();
set test1;
by var1 var2;
end;
enddata;
run;
quit;
proc print data=test3 noobs;
run;

結果をみると



















DS2でbyを指定した場合の自動ソートがSQLソートであることが確認できました。

0 件のコメント:

コメントを投稿