proc planを使って定義から、それっぽい値のテストデータを生成する

新しいプログラムを作るときに、使用するデータの仕様はある程度決まっているけど
実際テストデータはまだ存在していないみたいな状況で、
動き始めなければならないことってあると思います。なければそれは幸せです。
下手すりゃ初めて実行するのが、実際の本番データってこともあるかもです。

やっぱり作り手としては、データ無しで書けなくもないけど
ある程度、テストデータ使って、回しながらコード書きたいですよね。

例えば、

変数名値リスト
sampleid数値
sex文字男性/女性
btype文字A型/B型/AB型/O型
age数値20-65
ques1数値1,3,5,99


みたいなデータ定義書があって、これに沿ったデータが100件ほしければ

proc plan seed=1234;
factors sampleid = 100 ordered
sex      = 1 of 2;
treatments btype = 4
age   = 46
ques1 = 4;
output out= Q1
sampleid
sex   cvals =('男性' '女性')
btype cvals =('A型' 'B型' 'AB型' 'O型')
age   nvals =(20 to 65)
ques1 nvals =(1,3,5,99);
run;
quit;

とすれば






























の通りです。

ちなみに各値の出現頻度は
























のようカテゴリ数で大体等分されます。サンプル数少ないからちょっと綺麗になってませんが。
(発現割合をいじったりはこのやり方ではできないはず…)

もともと実験計画とか割付用の特殊なプロシジャを無理やりテストデータ作りに
使っているのでステートメントに違和感がありますが、要はfactorのところで
サンプルID的な変数を指定しときます。sexはキーじゃないのですが、factorステートメントは
2変数以上指定しないと実行できないので、とりあえず放り込んでおきます。

後はtreatmentsで各変数のカテゴリ数、output=データセット名以下で
文字数字を決めて、その発現リストを指定します。

上記の例は、1サンプル1オブザベーションのデータですが、例えば
企業の売り上げデータが月ごとに積みあがっている以下のような場

変数名値リスト
sampleid数値
month数値1-12
uriage数値0-9999


であれば

proc plan seed=1234;
factors sampleid = 100 ordered
month    = 12 ordered;
treatments uriage = 1001;
output out= Q2
sampleid
month  nvals= (1 to 12)
uriage nvals=(0 to 9999)
;
run;
quit;






























と先ほどsex      = 1 of 2としていたところをmonth    = 12というように
1 of を抜いてやればOKです。

あと、僕がよくやるのは、実際データって欠損が混じりますよね。ここはシステムで制御してるから
絶対入りませんと言われていたところが何故か本番で欠損だったこともあるので、基本そういうのは
信用せずにID以外は全部ブランクが入る可能性があると考えてコード書くようにしてます。

なので

data _Q1;
 set Q1;
 call streaminit(1234);

 array NV _numeric_;
 do over NV;
  if rand('uniform') <0.1 & vname(NV) NOTIN ('sampleid') then NV =.; 
 end;
 array CV _character_;
 do over CV;
  if rand('uniform') <0.1 & vname(CV) NOTIN ('sampleid') then CV =''; 
 end;
run;





として、ここが欠損なら話になんねぇってところ以外は、ランダムに穴ぼこにしてからテスト実行してます。


0 件のコメント:

コメントを投稿