そういった処理を書けといわれると、とりあえず、対象となる降順(昇順)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でもとれますが少しめんどうなので割愛します
0 件のコメント:
コメントを投稿