データステップなら多分、乱数を作成するステップと、その乱数でソートするステップで2ステップ必要だと思います。
例えば以下のようなデータセットがあったとします。
data Q1;
do X= 1 to 20;
output;
end;
run;
その場合、
data _Q1;
set Q1;
SORTKEY=ranuni(2013);
run;
で
となり、それを以下のようにソートすると
proc sort data=_Q1 out=A1(drop=SORTKEY);
by SORTKEY;
run;
となり、ランダムな順番に並び変わりました。
まったく同様の処理をSQLの場合、よりスマートに表現できます。
proc sql noprint;
create table A2 as
select X
from Q1
order by ranuni(2013)
;
quit;
で同じ結果となります。
order byにいきなりranuni関数を指定できるところが味噌ですね。
で、まあ以下のようにoutobs=オプションを使えば、ログに、処理が途中で打ち切られたという
WARNINGがでますが、無作為抽出ができます。
10のデータを抽出する場合、
proc sql noprint outobs=10;
create table A3 as
select X
from Q1
order by ranuni(2013)
;
quit;
で
となり、要は前の結果のうち10obs目までを出力しているだけですが、結果としてランダムサンプリングしたような結果となります。
まあ、しかしバージョン8以降はsurveyselectプロシジャを使うことで、様々な標本抽出を表現できるようになったので、よほどの理由がない限りはそちらを使った方がいいと思います。
標本10の単純な非復元無作為抽出であれば
proc surveyselect data=Q1 noprint
method=srs
n=10
seed=2013
out=A4;
run;
で
のようになります。
処理が異なるため、ここでのseedの指定を前のプログラムのものと同じにしても
結果は違うので、古いコードをリファクタリングする場合は注意してください。
0 件のコメント:
コメントを投稿