ラベル choosen の投稿を表示しています。 すべての投稿を表示
ラベル choosen の投稿を表示しています。 すべての投稿を表示

CHOOSEN(C)関数とCALL SORTN(C)ルーチンで、横に可変的に増える変数をソートして指定した順番にくる変数を取得する

固定されたデータが手元に完全にある状態で、プログラムを書けることは幸せです。
実際のデータをみて取りうる範囲から固定した処理がかけるからです。

しかし往々にして、手元にこないと実際どんなデータかわからない、あるいは見てはいけない、という状況で、どんなデータが来ても可変的に対応できるプログラムを書くこともあると思います。



data Q1;
X_1='か';X_2='あ';X_3='さ';X_4='た';output;
X_1='B';X_2='C';X_3='A';X_4='Z';output;
run;






こんなデータがあったとします。

そして非常識なことに、なぜか、このデータは横にも増える可能性があるとします。
今プログラムを組んでも、次に実行する時のデータにはX_5やX_6があるかもしれません。

そして、求められている処理は、1行ごとに、横に辞書的に並び替えて、一番後ろから2番目に並ぶ
値を特定するという、これまたよくわからない処理だとします。

縦に増えていくデータは余裕ですが、横に変数が増えていくデータはやっかいです。
ありえないと思っていても、なぜか現実にそういうデータに当たることもあるものです。

転置して縦にしてから、降順ソートして、2番をとるような処理でもいいですが、できれば構造を
変えず単純にできないかと考え、以下のコードを考えました。


data A1;
set Q1;
call sortc(of X_:);
A=choosec(-2,of X_:);
run;






一行目は「さ」がお尻から2番目の文字で、2行目はCです。

横にいくら変数が追加されてもX_という接頭語が崩れない限りはX_100までいこうが動きます。
仮に変数がX_1の一つだけでもAがnullになるだけで、エラーにはなりません。

call sortcルーチンで変数間で値をソート順に交換させて、からchoosec関数で、指定した順番にいる変数を取得します。-2とすることで、右端から2個目(つまりソートされた最大の値の一つ前)をとることができます。

たった4行で書けたので自分的には大満足です。

もし対象が数値型なら

call sortcはcall sortn
choosec はchoosenに変えてください。


/*追記*/
てか、数値型なら、そもそも smallest関数とlargest関数で、何番目の最小値、最大値とれるからソートの必要ないですね、すみません。