SASでランダムサンプリングしてグループ分けするマクロ

Share Button

あるデータのオブザベーションを,指定した割合で2つのグループにわけます。
元データから無作為抽出して片方のグループを作ったあとに,元データから抽出されなかった残りのオブザベーションだけをもう片方のグループとして吐き出します。
まあ大したことでもないですが,個人的にクロスバリデーションとかすんのにこの行程の頻度がやたら高いのでマクロ化しておきます。
そして作ったマクロはほぼ全部公開してるのでこれも。
 
%divideGroups(data=ライブラリ名.データセット名 ,percent=0.7とか割合)で,libname.datasetGroup1, libname.datasetGroup2に特定の割合で分割します。
勝手に永久データセットにされるのが気に食わない場合は9行目と15行目の&data.を消せばデータセット名group1とgroup2という形でworkに吐き出されるはずです。
 
大したことしてないんでマクロ名とか使いやすいように勝手に改変してくれればいいです。method=srsとかも勝手に変えてください。サンプリングの手法一覧はこの辺読めばわかるかと思います。
The SURVEYSELECT Procedure: PROC SURVEYSELECT(Method Option) Statement :: SAS/STAT(R) 9.22 User’s Guide
 
存在しないデータセットを指定した時に処理を進ませずエラーメッセージを返すようにしました。
 

%MACRO divideGroups(data,percent);
%IF %SYSFUNC(EXIST(&data)) %THEN %DO;

  DATA _temp_groupAll;
    SET &data;
	_temp_n = _n_;
  run;
  PROC SURVEYSELECT data= _temp_groupAll out=_temp_group1
    method=srs rate= &percent RANUNI NOPRINT;
  run;
  DATA &data.group2;
    DROP _temp_n;
    MERGE _temp_group1(in=inA) _temp_groupAll;
	by _temp_n;
	IF inA THEN DELETE;
  run;
  DATA &data.group1;
    DROP _temp_n;
	SET _temp_group1;
  run;
  PROC DATASETS lib=work NOLIST;
    DELETE _temp_groupAll _temp_group1 _temp_group2;
  quit;
  %END;
%ELSE %DO;
  %PUT "データセット &data. が存在しません。";
%END;
%MEND;

先日ふと指摘されて気づいたんですけど,大文字と小文字の混ぜ方が独特かもしれないです。言われてみれば確かに。
 
ドヤ顔で公開してますが,あくまで自分が通ってきた道を後ろから進んでくる人たちのために書いているので,諸先輩方がお怒りにならないことを祈りつつ。
ここまでプログラミングもSASも全部独学でやってきたので命名が変なのとかは大目に見てもらえると助かります。
 
・・・っていうか,SurveySelectで2グループに分割できたりしないの??もしかして似たようなプロシージャでできるんじゃね?なんかそんな気がする。(適当)
 
 


Share Button

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です