SASマクロ命令の使い方

org. SASマクロについて by K.Toyomura Ver.1.3 1998/02/15(日)20:40:48

同じような処理を繰り返す場合にマクロ命令が非常に効果的である。 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                            │
└─────────────────────────────┘

マクロのデバッグについて


1 マクロの中で文字列を表示できる。

┏━━━━━━━━┓
┃%PUT 文字列 ┃
┗━━━━━━━━┛
とする。

 SAMPLE
┌─────────┐
│%MACRO TEST6(D) ; │
│  PRINT DATA=&D ; │
│  %PUT DATA=&D;   │
│%MEND TEST6;      │
└─────────┘
2 OPTIONS MPRINT を指定する。
実際にマクロを展開して表示するので,警告その他発生場所を特定しやすい。

各特殊記号の意味

いくつかの特殊記号のマクロにおける意味を示す。

数式の取り扱い

・マクロはテキスト(文字列)を扱うので,数式は原則として扱えない。ただし,次の時に限り,数式を扱える。
・数式として扱いたい項目は%EVAL関数で囲む。
sample
┌──────────┐
│LET a=1;            │
│LET b=&a+2;         │
│LET c=%EVAL(&a+2);  │
└──────────┘
 を実行すると b は 1+2 に, Cは 3になる。
・マクロでは数式はすべて整数として評価される。
・%IFの条件式や反復%DOル−プのインデックス変数の扱いなどは数式として扱われる(暗黙に%EVAL関数が働く)。

◎引用符の取り扱い

引用符はマクロのとっても文字定数を囲むものとして扱われる。2つの引用符がペアとして扱われる。

戻る  進む  ホームページへ
mailto: toyomura@hokusei.ac.jp
home page: http://www.ipc.hokusei.ac.jp/~z00105/index.html