時々,すべての行(オブザベーション)に同じ値をもつ変数を追加したい場合があります.
たとえば,売り上げデータのデータセット全体の合計値を追加して,
各オブザベーションの売り上げの構成比を出したい場合,あらかじめ合計値がわかっていれば,
「total=12345;」などと割り当てステートメントを書いてしまえばいいのですが,
処理の中で求めた値はそういうわけにはいきません.
簡単な方法として,追加したい値が,1行(1obs)からなるデータセットに格納されている場合,
以下のように,ifステートメントとsetステートメントを使って,
その値を別のデータセットに貼り付けることができます.
data sample;
input item $ n;
cards;
apple 10
orange 20
banana 30
;
proc print;run;
/*
OBS item n
1 apple 10
2 orange 20
3 banana 30
*/
proc summary data=sample;
var n;
output out=total(drop=_:) sum(n)=total;
run;
proc print;run;
/*
OBS total
1 60
*/
data sample;set sample;
if _n_=1 then set total; /*totalの値をsmple全obsに貼り付ける*/
share=n/total;
run;
proc print;run;
/*
OBS item n total share
1 apple 10 60 0.16667
2 orange 20 60 0.33333
3 banana 30 60 0.50000
*/
これを応用すると,BYステートメントをうまく使えばグループが存在するときでも同様に処理できます.
data sample2;
input store item $ n;
cards;
1 apple 10
1 orange 20
1 banana 30
2 apple 15
2 orange 25
2 banana 25
3 apple 12
3 orange 21
3 banana 37
;
run;
proc summary data=sample2;
by store;
var n;
output out=total2(drop=_:) sum(n)=total;
run;
data sample2;
set sample2;
by store;
if first.store then set total2;
share=n/total;
run;
proc print data=sample2;
run;
/*
OBS store item n total share
1 1 apple 10 60 0.16667
2 1 orange 20 60 0.33333
3 1 banana 30 60 0.50000
4 2 apple 15 65 0.23077
5 2 orange 25 65 0.38462
6 2 banana 25 65 0.38462
7 3 apple 12 70 0.17143
8 3 orange 21 70 0.30000
9 3 banana 37 70 0.52857
*/
QA/COMMENT
- sample2について.へー知りませんでした.なるほどそうなるんですね.ちなみに,
data sample2; merge sample2 total2; by store; share=n/total; run;
とマージでやるのと全く同じなんでしょうか? -- 翔 2009-03-24 (火) 23:42:21