例えば以下のデータセットがあって
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 件のコメント:
コメントを投稿