2016年1月27日水曜日

IFN / IFC関数と謎の第4引数




IFN / IFC関数は、簡単に言うとIFステートメントの関数バージョンです。


構文

 IFN (  条件式  , 条件式が真(TRUE)の場合の戻り値 ,  条件式が偽(FALSE)の場合の戻り値 )

戻り値を数値で返したい場合はIFN関数を使い、文字値で返したい場合はIFC関数を使います。






*** サンプルデータ ;
data DT1;
    A=10 ; output;
    A=.  ;  output;
    A=20 ; output;
run;

*** IFC関数を使ってみる ;
data OUT1;
    set DT1;
    length B $30.;
    B = ifc( A<=10 , "10以下", "10より大きい" );
run;

 10  
 10以下  
  .  
 10以下 
 20
 10より大きい  


Aが欠損値の場合にも「10以下」ってなるのはおかしいよねって感じなので、
その場合、以下のようにIFN / IFC関数をネストさせる方法もありますが、、ネスト増やして見づらくなるんだったら、IFステートメント使った方が良いですね。。

B = ifc(A=. ,"未記載", ifc( A<=10 , "10以下", "10より大きい" ) );

 10  
 10以下  
  .  
 未記載
 20
 10より大きい 



謎の第4引数


実はこの関数、謎の第4引数が存在します。

  IFN( 条件式 , 条件式がTRUEの場合の戻り値 ,
                         条件式がFALSEの場合の戻り値 ,
                         条件式欠損値の場合の戻り値  )


ずっと疑問なんですが、この第4引数ってどういう時に使うんでしょうか?
というのも条件式の結果は、TRUE か FALSE しか返しません。

たとえば上の方のサンプルプログラムでIFC関数に書いた条件式 「A<=10」 に対する真偽は以下のようになります。

・ Aの値が10以下の場合        ・・・ TRUE
・ Aの値が10より大きい場合   ・・・ FALSE
・ Aの値が欠損値の場合        ・・・ TRUE (「10以下」と解釈。)


なんでこの関数だけ3値論理?
ということで、こういう時に使えそうねってアイディアがあれば教えてほしいです。



3 件のコメント:

  1. このコメントは投稿者によって削除されました。

    返信削除
  2. どうもです。

    それは僕も一時疑問で、3値論理起き得るの?と思ってましたが、条件式ではなく値そのものを評価するようなケース、実際以下のようなときに使いました。
    例えば、ひとつは「0」にコードとしての意味があり、「0以外の値」「0」「欠損」で処理したいという稀なケースです。
    たまたま、回答拒否の場合は0を入力というシステムがあって、記入ありとか拒否とか未回答をカテゴリ分けするときに

    data DT1;
    A=10 ; output;
    A=. ; output;
    A=0 ; output;
    run;

    data OUT1;
    set DT1;
    B = ifc( A,"記入あり", "記入拒否", '未記入' );
    run;

    とかって書きました。

    あと以下のように、欠損値を処理できないシステムとかにダミーコードで集計値を渡す場合などですが、値があれば演算するけど、引数が全て欠損のときは-9999とするみたいな場合

    data DT2;
    A=10 ;B=1;C=3; output;
    A=. ;B=.;C=.; output;
    A=0 ;B=-1;C=1; output;
    run;

    data OUT2;
    set DT2;
    Z = ifn(sum(of A B C),sum(of A B C),sum(of A B C),-9999 );
    run;
    とかってかきました。

    まあ、ぶっちゃけ、あえて4引数使わなくても、ifn関数を入れ子にするなり、後で欠損値処理すりゃいいだけですが。

    返信削除
    返信
    1. SASYAMAさんどうもです。

      なるほど~。これは使えそうですね。
      特に条件式に関数を入れ込めば応用範囲が広くなりそうですね。

      というかSASYAMAさん既に第4引数を活用してるんですね~流石です!

      ちょっと意識してみようと思います。
      勉強になりました!

      削除