マクロ %if とデータステップ if ステートメントで、●● < ▲▲ < ★★ の動作が異なる

SASのデータステップでは、if の条件分岐にて、if ●● < ▲▲ < ★★ ; という書き方をすることができます。 どのように動作するかというと、以下のように動きます。

  1. まず、●● < ▲▲ が評価されます。
  2. つぎに、▲▲ < ★★ が評価されます。

書いている通り、数学で出てくる条件文みたいな動作をしてくれます。他の言語だとあまり見ない動きです。


では、データステップ以外の条件分岐、マクロの %if でも同じ動作をしてくれるかというと、そんなことはない、というのが今回のお話です。

マクロ %if にて、同じように %if ●● < ▲▲ < ★★ ~ と記載すると、どんな動きをするのか。

  1. まず、●● < ▲▲ が評価されます。(ここは同じ)
  2. つぎに、直前の評価結果(falseなら 0 , trueなら 1) < ★★ が評価されます。

こちらの動きの方が他の言語でよく見る論理式の動きではないでしょうか。 2つ目の処理の仕方が違うので、一見して同じような書き方でも、データステップとは処理結果が異なることになります。


この動きの違いがどんなことを起こすのか。試しに、データステップ、マクロのサンプルコードを作ってみましょう。

 62         /* データステップの例 */
 63         data _null_ ;
 64           if 10 < 20 < 30 then putlog "TRUE" ; else putlog "FALSE" ;
 65           if 10 < 20 < 10 then putlog "TRUE" ; else putlog "FALSE" ;
 66           if 10 < 20 = 1  then putlog "TRUE" ; else putlog "FALSE" ;
 67           if 20 < 10 = 0  then putlog "TRUE" ; else putlog "FALSE" ;
 68           if 1  < 2  = 2  then putlog "TRUE" ; else putlog "FALSE" ;
 69         run ;
 
 TRUE
 FALSE
 FALSE
 FALSE
 TRUE
 NOTE: DATAステートメント処理(合計処理時間):
       処理時間           0.00 秒
       ユーザーCPU時間    0.00 秒
       システムCPU時間    0.00 秒
       メモリ             779.96k
       OSメモリ           25504.00k
       タイムスタンプ     2017/07/13 午後02:29:27
       ステップ数                        54  スイッチ数  52
       ページフォルト回数                0
       ページリクレーム回数              316
       ページスワップ回数                0
       自発的コンテキストスイッチ回数    152
       非自発的コンテキストスイッチ回数  0
       ブロック入力操作回数              0
       ブロック出力操作回数              0
       
 
 70         
 71         
 72         /* マクロ %if の例 */
 73         %macro TEST ;
 74           %if 10 < 20 < 30 %then %do ;
 75             %put ;
 76           %end ;
 77         
 78           %if 10 < 20 < 10 %then %do ;
 79             %put ;
 80           %end ;
 81         
 82           %if 10 < 20 = 1 %then %do ;
 83             %put ;
 84           %end ;
 85         
 86           %if 20 < 10 = 0 %then %do ;
 87             %put ;
 88           %end ;
 89         
 90           %if 1 < 2 = 2 %then %do ;
 91             %put ;
 92           %end ;
 93         %mend TEST ;
 94         
 95         options mlogic ;
 96         %TEST ;
 MLOGIC(TEST):  実行を開始します。
 MLOGIC(TEST):  %IF 条件 10 < 20 < 30 は TRUE です。
 MLOGIC(TEST):  %PUT 
 
 MLOGIC(TEST):  %IF 条件 10 < 20 < 10 は TRUE です。
 MLOGIC(TEST):  %PUT 
 
 MLOGIC(TEST):  %IF 条件 10 < 20 = 1 は TRUE です。
 MLOGIC(TEST):  %PUT 
 
 MLOGIC(TEST):  %IF 条件 20 < 10 = 0 は TRUE です。
 MLOGIC(TEST):  %PUT 
 
 MLOGIC(TEST):  %IF 条件 1 < 2 = 2 は FALSE です。
 MLOGIC(TEST):  実行を終了します。
 97         

結果を表にまとめると、以下のようになります。

条件 データステップ マクロ %if
10 < 20 < 30 TRUE TRUE
10 < 20 < 10 FALSE TRUE
10 < 20 = 1 FALSE TRUE
20 < 10 = 0 FALSE TRUE
1 < 2 = 2 TRUE FALSE

上記のように、最終結果が異なることが起きてしまいます。 ●● < ▲▲ < ★★ は、データステップとマクロで動き方が異なるので、きちんと理解していないと痛い目を見ることになるかもしれません。

では、どのように条件を記載するのがよいのか。 ●● < ▲▲ < ★★ と書くのではなく、●● < ▲▲ and ▲▲ < ★★ というように、and を使ってあげれば、データステップでも、マクロでも同じ動きをしてくれます。

コメント

このブログの人気の投稿

日付フォーマットでない文字項目をSAS日付に変換するときにログ出力されるメッセージを抑制したい - SAS

データセット(.sas7bdatファイル)の文字コードを取得したい - SAS

Linuxコマンド: date で◯か月前 / ◯か月後を取得するときの注意