フォーマットを使うと結構便利です。MULTILABEL FORMATを使えば、値の区間が重複している場合も別途に集計できて、気持ちいいです。
今、以下のように
data Q1;
call streaminit(2014131);
do i=1 to 1000;
X=rand('uniform');
output;
end;
drop i;
run;
0から1の間に分布する1000個の値について
0.2未満
0.2以上0.6未満
0.6以上
0.5未満
0.5以上
のカテゴリで区切って数を数えてと言われた場合
if X<0.2 then CATE=1; などなどデータステップで集計変数を定義してからプロシジャにかけてもいいですが、面倒です。
しかも区切る範囲がかぶっている(0.1という値は0.2未満で集計され、かつ0.5未満でも集計されなければならない)ので変数を分ける必要があります。
そんな時なら、例えば
proc format;
value FREQF (multilabel)
low-<0.2='0.2未満'
0.2-<0.6='0.2以上0.6未満'
0.6-high='0.6以上'
low-<0.5='0.5未満'
0.5-high='0.5以上';
quit;
のように区切る範囲をフォーマットで定義します。 (multilabel) を打てば値が重複していても
定義できます。
その上で
proc means data=Q1 MIN MAX ;
class X /mlf;
var X;
format X FREQF.;
run;
としてやれば
のように一気に集計できます。最小最大値は確認用にだしているだけです。
formatで指定することと、classステートメントに/mlfをつけることを忘れずに。
このコメントは投稿者によって削除されました。
返信削除/* フォーマットを使って集計 */
返信削除data Q1;
call streaminit(20160114);
do i = 1 to 1000;
X = rand('uniform');
output;
end;
drop i;
run;
proc format;
value FREQF
low -< 0.2 = '0.2未満'
0.2 -< 0.4 = '0.2以上0.4未満'
0.4 -< 0.6 = '0.4以上0.6未満'
0.6 -< 0.8 = '0.6以上0.8未満'
0.8 - high = '0.8以上'
;
quit;
ods output Summary = Summary1;
proc means data = Q1 N;
class X;
var X;
format X FREQF.;
run;
を実行した後、データセットSummary1から'0.6以上0.8未満'のオブザベーションを抽出するにはどうしたよいのでしょうか?
コメント有難うございます。
返信削除このやり方だと、outputされたデータセットのXはフォーマットがかかっているものの実値はシステムが適当に振った値なので、その後の複雑な加工には向かないかもしれません
が、ご質問のように単純に絞るだけなら
ods output Summary = Summary1(where=(put(X,FREQF.)='0.8以上'));
proc means data = Q1 N;
class X;
var X;
format X FREQF.;
run;
上記で大丈夫です。
あるいは初めから興味のあるレンジが限られているならwhereの方が効率よい書き方だと思います
ods output Summary = Summary1;
proc means data = Q1 N;
where put(X,FREQF.)='0.6以上0.8未満';
class X;
var X;
format X FREQF.;
run;
こんな感じでいかがでしょうか?