マクロ内で「%IFステートメント」を使って、処理を条件によって分岐させる方法を紹介します。
%IF 条件式 %THEN %DO; 条件式がTRUEになった場合の処理 %END; %ELSE %DO; 条件式がFALSEになった場合の処理 %END;
|
- マクロ内でのみ利用可能でしたが、以下記事の通り、9.4M5からはマクロ外でも制限つきで利用可
- %IFの条件式の判定法に注意! 例えば、
- 「%IF 120>13」の条件は想定通り「TRUE」になりますが、
- 「%IF 120.0>13.0」の条件は想定に反し「FALSE」になります
- 理由は以下リンク記事で説明
- https://sas-boubi.blogspot.com/2018/10/if.html
- (SAS社の%IFのページにはこの事について触れていないので気づきにくい。。)
%macro TEST( FLG );
%if &FLG = Y %then %do; proc print data=SASHELP.CLASS; run; %end; %mend; %TEST(); %TEST(Y); |
マクロ変数FLG に 「Y」 と入っていたらPRINTプロシジャが実行されます。
気をつけたいのがデータステップと勝手が違い、「%if &FLG = "Y"」というようにダブルクォーテーションで囲う必要はありません。
%IFステートメントではクォーテーションもテキストとして解釈されます。つまり「Y」という文字ではなく「"Y"」という文字として解釈されてしまいます。
%macro TEST( FLG );
data DT1; VAL1 = 1; %if &FLG = Y %then %do; VAL2=1; %end; run; %mend; %TEST();
|
マクロ変数FLG に 「Y」 と入っていたら変数VAL2を作って「1」を代入するマクロです。
これ実はかなり便利です。なんでかというと、以下のように通常のIF文で同じようなことをやろうとすると、、
%let YN=;
data DT1; VAL1 = 1; if "&YN"="Y" then do; VAL2=1; end; run;
|
作りたくないVAL2が出来てしまいます。
これはたとえ実行されない文でもデータステップ内に書かれている変数はまず自動で変数の枠だけ作られてしまうという性質があるからです。
一方、%IFは通常のプログラムとは別のところで動くので、この動きを回避できちゃいます。
①「マクロ変数Xが欠損値だったら~」という%IFを書きたい場合
%if &X = %then %do; |
少し違和感ありますがこれでOK(未確認ですが、昔のバージョンだとこの書き方ではERRORが出たらしい?)
② %IFが誤作動する例
%if &x = eq %then %do; |
マクロ変数Xの値が「eq」かどうかを条件にしていますが、「eq」は「=」を意味しているので、演算子として解釈されて誤作動を起こして正しい結果が得られません。
他に誤作動を起こす文字は多数ありますが、それらは以下リンク記事で解説しているような「クォート処理」をする必要があります。
以下、適当にクォート処理を入れてみた例ですが、マクロ変数に格納される値によってはまだ誤作動を起こす危険があります。
%if %bquote(&x) = %str(eq) %then %do; |
状況にあわせてどのクォート関数を使うのか、どのタイミングでクォート処理をするのかを判断する必要があります!
- IFはデータステップ内で実行するステートメント
- %IFはデータステップ内とか外とかそういう概念がありません。
つまり%IFでは以下のようにデータセットの中にある変数の値を評価することは出来ません。
X 勘違い注意 X
%macro TEST;
data DT1; A=1; %if A=1 %then %do; B=1; %end; run; %mend; %TEST; |
%IFでは上記のプログラムを「A」という文字列と「1」という文字列がイコールかどうかを評価しちゃいます。
当然イコールじゃないので中の 「B=1;」 は実行されません。
2. マクロの登録と実行
3. 定位置パラメータ
4. キーワードパラメータ
5. クォート処理
6. クォート処理2
7. ループ処理
8. 条件分岐処理
9. ドット
10. &&
11. 演算評価
12. 補足
0 件のコメント:
コメントを投稿