SQLでデータをランダム順に並び替える_order by ranuni() おまけで非復元無作為抽出

データを単にランダムな順番でシャッフルしたいこと、、あんまりないと思います。
データステップなら多分、乱数を作成するステップと、その乱数でソートするステップで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 件のコメント:

コメントを投稿