あったらいい関数やルーチンがないから取り敢えずこう書いてますの話

今回は僕が日頃感じることの多いSAS関数とコールルーチンへの不満についてです。
といっても別にそんな大したことじゃなく
普通に提供されてそうな機能なのに、実際なくて困るからとりあえず僕はこう書いてるけど、
みなさん普段どうしてるんだろうってことを紹介する話です。

なので、え?それは○○関数でできるよ、とか9.3とか4で引数追加されてできるようになったたよとか
あれば是非、てめえは間違っているとご指摘ください。


まずはデータ

data Q1;
length A B C D $10.;
A='い';B='ろ';C='は';D='に';output;
A=''  ;B=''  ;C='は';D='に';output;
A=''  ;B=''  ;C=''  ;D=''  ;output;
A='い';B='ろ';C=''  ;D=''  ;output;
A='ろ';B='ろ';C='ろ';D='ろ';output;
run;












まず一番、よくあるのが、指定した複数の文字値の中で、欠損でないものの数をカウントしたいというケースです。
数値型であればn関数があります。欠損値であれば、数値文字両方対応のcmissがあります。
ただ、文字型の非欠損値のカウントがないんですよね。
で、SAS公式もそのことはわかっているので、以下のように案内してます。
http://support.sas.com/kb/46/235.html

でも、紹介されてる代替コードが(僕としては)微妙すぎ。
文字変数の数から欠損値の数ひけば、非欠損値の数でしょっていう、まあそりゃそうですけど
わざわざ複数ステップで書くの面倒だし、全文字変数が対象じゃなくて、一部の変数を対象にする場合
絞りをいれる必要のあるプログラムなので、ちょっとって感じです。
今後のバージョンでそういう関数を追加します的なことも書いてますが、今現在ないと思うので、いつになるやら。

なので、僕は以下のように書いてます。

data A1;
set Q1;
array AR $ B C D;
CN=0;
do over AR;
 CN + ^missing(AR);
end;
run;












本当はfcmpでそういう関数作りたかったんですが、現状のfcmpだと引数に
temporary配列しかとれないので、結構使い勝手が悪いんですよね。

リンクサイト kickstamp の
【SAS】PROC FCMPプロシージャーでの可変長引数の利用について

http://kickstamp.hatenablog.com/entry/2013/07/18/124954

で、紹介されているようにマクロ噛ませばできるんですが、たかが非欠損値数えるだけで
そこまでするのも何か負けた感じで嫌だな~って。

次に、これは文字型に限った話じゃないんですが、指定した複数の変数の中で条件に合致するものの数が欲しいというケースです。excelのcountif関数みたいなイメージです。
縦にそういうことしたい場合はsqlとかでいいんですが、横にだしたい時も多いので困ります。

ので僕は以下のようにしています

data A2;
set Q1;
array AR $ B C D;
CN=0;
do over AR;
 CN + AR in ('ろ');
end;
run;











最後に同じような内容ですが、以前掲示板にも書いたことがあるのですが
http://tumesas.progoo.com/bbs/tumesas_topic_pr_39.html

複数変数を対象に特定の値を他の値に変換したいという処理です。
とりあえず、今は以下のように書いてます。

data A3;
set Q1;
array AR $ B C D;
do over AR;
 AR = ifc(AR='ろ','は',AR);
end;
run;










つまり今は関数やルーチンがない場合、だいたい配列&ループ処理でまかなっているわけです。
ただ基本的に僕の考え方として、配列もマクロもハッシュオブジェクトも、或いはプロシジャによる処理も極力いれずに、ありものの関数やルーチンの
組み合わせで解決できることは、極力そうしたいと思ってます。(割に変なコードばっか書いてますが…)
まあ、あんまり関数のお化けみたいなコードになるぐらいなら、素直に配列書きますけど、用意された機能でシンプルにできるならそれに越したことはないと思ってます。

0 件のコメント:

コメントを投稿