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

指定した変数を除いて、それ以外の全ての変数を関数の対象にするマクロ


少し早いですが、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、配列がどうしてもわからなくて、使うのが凄い苦手だったんです。
で、マクロも苦手だったので、変数名をマクロにいれるとか、配列をつかうとかいう発想が
でなかったんです。それでこういう名前にしたんですね。