以前、「ODS OUTPUTからデータセットを作る場合に複数変数を指定したプロシジャ出力の場合に(MATCH_ALL)で変数ごとにデータセットを自動連番で分けてもらう」という記事で
http://sas-tumesas.blogspot.jp/2014/02/ods-outputmatchall.html
ods outputの出力データセットを複数にわけるという話をしましたが、それに補足です。
data Q1;
X=1;Y=3;output;
X=4;Y=3;output;
X=6;Y=5;output;
run;
ods listing close;
ods output basicmeasures(match_all=MA)=AA;
proc univariate data=Q1;
var X Y;
run;
ods output close;
ods listing;
とmatch_allの後に=で任意の名前を指定すると、作成されたデータセット名がマクロ変数に格納されます。
実行後、
%put 作成されたのは &MA;
とすると
となります。
data OUTPUT;
set &MA;
run;
とすると、作成されたデータセットが対象となって縦連結されます。
じゃあなんでmatch_allつけて分けたの?って感じですが。
前回の記事では複数変数を指定したらという話でしたが
例えば
proc sort data=Q1;
by X;
run;
ods listing close;
ods output basicmeasures(match_all=MB)=BB;
proc univariate data=Q1;
var Y;
by X;
run;
ods output close;
ods listing;
のようにby変数ごとに結果のデータセットを作成した場合でも
%put 作成されたのは &MB;
とすると
となります。
作成されたデータセットに、マクロループなんかで同一の処理をかけたい場合に
役立ちます。
まあ今まで一度もそんな状況はなかったけど。
univariateプロシジャのヒストグラムに要約統計量のテーブルを突っ込む話
univariateプロシジャは多機能の極みなので、できることを1つずつ紹介してたら、本できちゃいそうなので、結構基本的で結構使えるのに知らない人が多いと、僕が勝手に思ったものを適当に紹介します。
データはなんでもいいです。
data Q1;
call streaminit(1234);
do i=1 to 100;
X=rand('uniform')*10;output;
end;
drop i;
run;
で
ods graphics on;
proc univariate data=Q1 noprint;
histogram X;
run;
とすれば
こんな感じのヒストグラムができると思います。
histogramには、盛りだくさんのオプションが用意されていて、見栄えや幅や密度曲線はめたり、もうやりたい放題なので、詳しくはヘルプを見て下さい。
で、今回紹介したいのは上のグラフに、要約統計量の情報を突っ込むinsetです。
なにも難しいことはなくて、以下で終わりです。
proc univariate data=Q1 noprint;
histogram X;
inset n="N" (8.0)
mean="平均" (8.2)
std="標準偏差" (8.3)
/ header='要約統計量' pos=NE;
run;
なんか右上にでてる!って感じでOKです。
inset 以下、出力したいキーワード='ラベル名'(フォーマット指定)で基本OKです。
スラッシュ以下にレイアウト絡みのオプションが、これまたいっぱいあります。
header=はそのテーブルのヘッダー、
そしてpos=はposition、つまり表示場所なのですが、これが凄い独特で、何故か
方位磁石方式なんですね。
つまり、いまpos=NEとしている NEとはNorthEast、つまり北東、すなわち右上に表示しろいう命令なんです。
なのでpos=SWとすれば、南西、つまり左下に表示されます。
なんじゃそりゃ。
データはなんでもいいです。
data Q1;
call streaminit(1234);
do i=1 to 100;
X=rand('uniform')*10;output;
end;
drop i;
run;
で
ods graphics on;
proc univariate data=Q1 noprint;
histogram X;
run;
とすれば
こんな感じのヒストグラムができると思います。
histogramには、盛りだくさんのオプションが用意されていて、見栄えや幅や密度曲線はめたり、もうやりたい放題なので、詳しくはヘルプを見て下さい。
で、今回紹介したいのは上のグラフに、要約統計量の情報を突っ込むinsetです。
なにも難しいことはなくて、以下で終わりです。
proc univariate data=Q1 noprint;
histogram X;
inset n="N" (8.0)
mean="平均" (8.2)
std="標準偏差" (8.3)
/ header='要約統計量' pos=NE;
run;
なんか右上にでてる!って感じでOKです。
inset 以下、出力したいキーワード='ラベル名'(フォーマット指定)で基本OKです。
スラッシュ以下にレイアウト絡みのオプションが、これまたいっぱいあります。
header=はそのテーブルのヘッダー、
そしてpos=はposition、つまり表示場所なのですが、これが凄い独特で、何故か
方位磁石方式なんですね。
つまり、いまpos=NEとしている NEとはNorthEast、つまり北東、すなわち右上に表示しろいう命令なんです。
なのでpos=SWとすれば、南西、つまり左下に表示されます。
なんじゃそりゃ。
詰めSAS7回目_n番目に大きい値を取得する
最小、最大をとる処理に比べて、n番目に大きい(小さい)値を取得する処理を書くことは少ないと思います。
そういった処理を書けといわれると、とりあえず、対象となる降順(昇順)sortして、次のデータステップにbyをつけて、連番を付与したのち、その連番がnであるオブザベーションをとるという手順が最初に思い浮かぶ方も多いと思います。
それでまったく間違いではないのですが、ここではそれ以外の方法を紹介します。
【問題】
data Q_1;
input X;
cards;
1
5
6
3
2
4
;
run;
ranks RANK;
run;
var X;
run;
data A_3;
set Q_1_;
RANK=2;
X=LARGEST(RANK,of VAL_:);
keep RANK X;
run;
そういった処理を書けといわれると、とりあえず、対象となる降順(昇順)sortして、次のデータステップにbyをつけて、連番を付与したのち、その連番がnであるオブザベーションをとるという手順が最初に思い浮かぶ方も多いと思います。
それでまったく間違いではないのですが、ここではそれ以外の方法を紹介します。
【問題】
data Q_1;
input X;
cards;
1
5
6
3
2
4
;
run;
上記のデータセットから2番目に大きいXの値(5)を取得して

上記のようなデータセットを作ります。
【解法1】
proc rank data=Q_1 out=A_1(where=(RANK=2)) descending;
var X;ranks RANK;
run;
rankプロシジャは指定した変数の値を比較して順位をつけてくれるプロシジャです。
ranksステートメントを指定しないとvarで指定した変数が順位データに上書きされるので
元の値と順位両方をだしたい場合は指定します。
descendingをつけないと昇順に順位付けします。
【解法2】
ods output extremeobs=A_2(keep=HIGH HIGHOBS rename=(HIGH=X HIGHOBS=RANK) where=(RANK=2));
proc univariate data=Q_1;var X;
run;
univariateプロシジャでも同じようなことができます。
univariateを実行するとアウトプットに
極値という項目がでて、最小最大ともにデフォルトでTOP5のデータがでるので
これをODSでとってしまえばよいのです。
n番目に値以外にunivariateで出すものがある場合はRANKプロシジャなんかを使うより
UNIVARIATEついでにこっちのやり方でやればいいですね。
【解法3】
proc transpose data=Q_1 out=Q_1_ prefix=VAL_;
run;data A_3;
set Q_1_;
RANK=2;
X=LARGEST(RANK,of VAL_:);
keep RANK X;
run;
わかりやすいように転置でtransposeプロシジャを使用して1ステップ使っており、2ステップになっています。(transposeプロシジャを使わない転置は別頁参照)
ようはSASのLARGEST関数を紹介したかったのです。これはlargest(n,x,y,z....)でn番目に大きい値をx,y,z・・・からとる変数です。小さい値はSMALLEST関数です。
SQLでもとれますが少しめんどうなので割愛します
登録:
コメント (Atom)

