指定した変数を除いて、それ以外の全ての変数を関数の対象にするマクロ
少し早いですが、PC内のファイルの年末大掃除をしていた際に
まだSASを覚えてそんなにたっていない頃に作ったマクロがでてきて、
僕自身、存在すら完全に忘れてたのですが
これが結構面白い発想のものだったので、自画自賛ながら紹介します。
例えば以下のように変数の多い、横長なデータセットがあった場合を考えます
data Q1;
A=1;B=2;C=5;D='あ';E=8;F=4;G='い';H='A';I=9;output;
A=4;B=3;C=2;D='い';E=6;F=2;G='ろ';H='A';I=5;output;
run;
AとBの合計を出してとかだったら sum(A,B)で余裕ですし、
AとB以外の合計を出してと言われたらsum(of C-numeric-I);でいけますよね。
(※変数名--変数名は変数の格納位置を指定する方法です。
間にnumericやcharacterを挟むことで、数値型か文字型で絞れます)
でも、きっついのが、変数の格納順が定まってなかったり、横に変数が増えていくような
ことが想定される、つまりケツにくる変数名が不明、特定できない場合に
sum(of C-numeric-I);の方法は使えません。
さらに痛いのがEとI以外の合計を出してみたいなケースで、
sum(A,B,C,F);みたいに全部列記して書くか、、それでも変数が可変的に追加される状況では
決め打ち対応できません。
そういった時に昔の僕が捻くり出したのが以下のマクロです。
%macro noarray(INDS,OUTDS,EXLIST,FUNC);
data &OUTDS;
informat &EXLIST DUMMYST;
set &INDS;
DUMMYST=.;
DUMMYEND=.;
RESULT=&FUNC(of DUMMYST-numeric-DUMMYEND);
drop DUMMYST DUMMYEND;
run;
%mend noarray;
INDSに流し込むデータセット名
OUTDSに作成するデータセット名
EXLISTに関数の対象から除外する変数リスト
FUNCにはSUMやMEANやMAXなど数値対象の関数を指定します。
=======================
以下、実行例
=======================
%noarray(Q1,A1,A B,sum)
これはAとB以外をsumしています 結果は
%noarray(Q1,A2,E I,sum)
これはEとI以外をsumしています 結果は
%noarray(Q1,A3,C I D,mean)
これはCとIとD以外をmeanしています 結果は
なかなか面白いのが、関数の指定に変数順を使用して、
対象除外の変数を一番先頭にして、その後ダミーのスタート地点と
ダミーのゴールとなる変数を定義しているところですね。
numericのところを消せば、文字数値共通で引数にとれる関数に使えますし
characterにすれば文字型変数版マクロに早変わりですね。
てか、ここ自体、マクロパラメータにしちゃえばいいですね。
で、思い出深いのが、noarrayというマクロ名です。
array、配列がどうしてもわからなくて、使うのが凄い苦手だったんです。
で、マクロも苦手だったので、変数名をマクロにいれるとか、配列をつかうとかいう発想が
でなかったんです。それでこういう名前にしたんですね。
登録:
コメント (Atom)