2014年1月24日金曜日

条件式(IF/WHERE)のちょっと効率的な書き方。


IF/WHEREステートメントには以下の真偽ルールが存在する。

変数値または式の結果が

 ・ 0、NULLの場合 ・・・ 「0.false
 ・ 上記以外 ・・・ 「1.true

として評価される。




解説

これはどういう事なのか、以下のサンプルプログラムを実行してみると分かる。

*** サンプルデータ作成 ***********;
data TEST1 ;
  input V1 @@;
cards ;
1 3
;








*** サンプルプログラム ***********;
data TEST2;
  set TEST1;
  if  V1  then  V2=1;
run;



真偽ルールに従い、変数「V1」が「true」となったものに対して、「V2=1」となっている事が分かる。



活用例①

*** サンプルデータ作成 ******;
data DT1;
  do A=1 to 5 ;
     output ;
  end ;
run ;

data DT2 ;
  do A=2 to 4 ;
     output ;
  end ;
run ;

data DT3 ;
  do A=1 to 3 ;
     output ;
  end ;
run ;

DT1

DT2
 
DT3


上記3データセットを変数「A」をキーにマージしたいとする。
その後たとえば、、
「A」の値が、「DT2」にあって「DT3」にないものを抽出したい場合、
IN=オプションを使って、通常以下のように書く。

data OUT1;
  merge DT1
            DT2 (in=INDT2)
            DT3 (in=INDT3)
  ;
  by A;
  if  INDT2=1 and INDT3=0 ;
run;




これは真偽ルールを元に書き直すと、
 if  INDT2  and  ^INDT3 ;
となる。


「^」は「NOT」の略で、真偽ルールが逆になる。つまり、、
  ・0、NULLの場合 ・・・ 「1.true
  ・上記以外 ・・・ 「0.false
となる。

この真偽ルールと論理演算子「^」の組み合わせは便利で、
使用する場合は以下記事を参照下さい。
論理演算子「^」「^^」によるフラグ変数の作成


活用例②

*** サンプルデータ作成 ******;
data DT4 ;
  input B$ ;
cards;
ABCD
EFGH
;
run;



上記データセットに対して、
変数「B」に"C"という文字が含まれているレコードを抽出したい場合、
INDEX関数を使って、通常以下のように書く。

data OUT2 ;
  set DT4 ;
  if index(B, "C") > 0 ;
run ;



これを真偽ルールに従って書き直すと、
 if index(B, "C") ;
と書くだけでよい。


まとめ

「0/1」や「NULL/1」と入ってる有無変数やフラグ変数に対して有効的に働き、
論理演算子「^」と組み合わせることでスマートに書けるので便利です。

0 件のコメント:

コメントを投稿