同じような処理を繰り返す場合にマクロ命令が非常に効果的である。 SASでいうマクロは,SASのプログラムについて,文字列を追加したり,置き換えたりするものと考えてよい。
マクロは, ┏━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃%MACRO マクロ名[(パラメータリスト)];┃ ┃ マクロ定義内容の記述 ┃ ┃%MEND [マクロ名]; ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━┛ のように記述し,それを呼出す場合は, ┏━━━━━┓ ┃%マクロ名┃ ┗━━━━━┛ とする。 SAMPLE(2回繰り返す) ┌──────────────┐ │%MACRO test1; │ │ PROC PRINT DATA=d1 ;RUN ; │ │%MEND test1; │ │ │ │%test1 │ │%test1 │ └──────────────┘ 完全に繰り返し部分が同じでない場合は ┏━━━━━━━━━━━━━━━━━━━━━┓ ┃%LET マクロ変数名=[任意のテキスト] ┃ ┗━━━━━━━━━━━━━━━━━━━━━┛ が使える。 SAMPLE (q1 と q2 の変数を年代別に出力する) ┌───────────────────┐ │%MACRO test2; │ │ DATA d1; │ │ SET d2; │ │ IF &cond; │ │ RUN ; │ │ TITLE "DATA SET=d2 条件=&COND"; │ │ PROC PRINT DATA=d1; │ │ VAR q1 q2; │ │ RUN; │ │%MEND test2; │ │ │ │%LET cond=age<10 ; │ │%test2 │ │ │ │%LET cond=10<= age <20 ; │ │%test2 │ │... │ └───────────────────┘
実はこれよりも,パラメータを使用した方がスマートである。上の例では,変数 q1,q2 が固定であったが,それも自由に指定したいなど,マクロ変数を2つ以上使用したいこともあるから。
SAMPLE (q1 と q2 の変数を年代別に出力する) ┌─────────────────┐ │%MACRO test3(cond,varlist) ; │ │ DATA d1; │ │ SET d2; │ │ IF &cond; │ │ RUN ; │ │ TITLE "DATA SET=d2条件=&COND"; │ │ PROC PRINT DATA=d1; │ │ VAR &varlist; │ │ RUN; │ │%MEND test2; │ │ │ │%test3(age<10,q1 q2) │ │%test3(10<=age<20,q1 q2) │ │... │ └─────────────────┘
もっと実用的な方法もある。上記の方法では引き渡すパラメータの順序を覚えていなくてはならないが, 一般には順序より名前のほうが覚えやすい。そこで以下のようにする。
SAMPLE (幾つかの変数について年代別に出力する) ┌─────────────────┐ │%MACRO test3(cond=,varlist=q1) ; │ │ DATA d1; │ │ SET d2; │ │ IF &cond; │ │ RUN ; │ │ TITLE "DATA SET=d2条件=&COND"; │ │ PROC PRINT DATA=d1; │ │ VAR &varlist; │ │ RUN; │ │%MEND test2; │ │ │ │%test3(cond=age<10,varlist=q2 q3) │ │%test3(cond=10<=age<20) │ │... │ └─────────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃%IF 条件式 %THEN ┃ ┃ テキストまたはマクロ・プログラミングステートメント; ┃ ┃[%ELSE テキストまたはマクロ・プログラミングステートメント;]┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃%DO; ┃ ┃ テキストまたはマクロ・プログラミングステートメント; ┃ ┃%END; ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ を使用する。 SAMPLE (健常児は男女別,知能障害児は男女込みに分析する) ┌─────────────────────────┐ │%MACRO TEST4(subset,varlist) ; │ │ %IF &subset=nor %THEN %DO ; │ │ DATA nor_m ; │ │ SET soturon ; │ │ IF his=1 AND sex=1 ; │ │ RUN; │ │ DATA nor_f ; │ │ SET soturon ; │ │ IF his=1 AND sex=2 ; │ │ RUN; │ │ TITLE "SUBJECT=&SUBSET"; │ │ PROC MEANS DATA=nor_m; VAR &varlist; RUN; │ │ PROC MEANS DATA=nor_f; VAR &varlist; RUN; │ │ %END; │ │ %ELSE %DO ; │ │ DATA mr ; │ │ SET soturon ; │ │ IF his=2 ; │ │ RUN; │ │ PROC MEANS DATA= │ │ TITLE "SUBJECT=&SUBSET"; │ │ PROC MEANS DATA=mr ; VAR &varlist; RUN; │ │ %END; │ │%MEND TEST4; │ │ │ │%TEST4(NOR,q1 q2); │ │%TEST4(MR,q1-q22); │ │... │ └─────────────────────────┘
マクロからマクロを呼出すことができる(マクロはネスティング可能である)。 ┌──────────────────────┐ │%MACRO ssort(dname,svar); │ │ PROC SORT DATA=&dname; BY &svar; RUN; │ │%MEND ssort; │ │ │ │%MACRO test5(dname,varlist) ; │ │ DATA &dname; │ │ SET D2; │ │ RUN; │ │ %SSORT(dname,sex) │ │ PROC PRINT; RUN; │ │%MEND TEST5; │ │ │ │%TEST5(D1,ID sex q1-q22) │ └──────────────────────┘ 反復生成もできる。 ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃%DO インデックス変数=初値 %TO 終値 [%BY 増分];┃ ┃ テキストまたはマクロ・プログラミングステートメント; ┃ ┃%END; ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ SAMPLE ┌─────────────────────────────┐ │TITLE 'DATA SET : D1'; │ │%MACRO SAM; │ │ PROC PRINT DATA=D1 ; RUN; │ │ %DO I=1 TO %TO 3; │ │ TITLE "DATA SET : D&1"; │ │ TITLE 'DATA SET : D2';=PROC PRINT DATA=D&1; RUN; │ │ PROC PRINT DATA=D2 ; RUN; │ │ %END; │ │%MEND SAM; │ │TITLE 'DATA SET : D3'; │ │PROC PRINT DATA=D3 ; RUN; %SAM │ └─────────────────────────────┘
┏━━━━━━━━┓ ┃%PUT 文字列 ┃ ┗━━━━━━━━┛ とする。 SAMPLE ┌─────────┐ │%MACRO TEST6(D) ; │ │ PRINT DATA=&D ; │ │ %PUT DATA=&D; │ │%MEND TEST6; │ └─────────┘2 OPTIONS MPRINT を指定する。
sample ┌──────────┐ │LET a=1; │ │LET b=&a+2; │ │LET c=%EVAL(&a+2); │ └──────────┘ を実行すると b は 1+2 に, Cは 3になる。・マクロでは数式はすべて整数として評価される。