2014年4月16日水曜日

1行プログラムその5:有無変数

有無変数を1行でつくる方法を紹介。

サンプルデータ作成

data DT1;
length NO $3. ALLERGY $20.;
input NO$ ALLERGY$;
cards;
001 花粉症
002 .
003 猫アレルギー
;
run;

データセットDT1
NO   ALLERGY
001    花粉症
002   
003    猫アレルギー


やりたい事

サンプルに対して、以下の有無変数を作成したい。
【アレルギー有無】
ALLEYN

【導出方法】
アレルギー(ALLERGY)に記載がある場合「2:有」、それ以外「1:無」とする。

欲しい結果
NO   ALLERGY       ALLEYN
001   花粉症               2
002                            1
003   猫アレルギー       2



1行プログラム

*** 有無変数を1行で作るいくつかの方法 ******************;
data DT2;
    set DT1;

    *** 通常のやり方 ;
    if  ALLERGY^="" then  ALLEYN = 2;
    else  ALEEYN = 1;

    *** 方法① 真偽値 ;
    ALLEYN1 = (ALLERGY^="") +1;

    *** 方法② WHICHN関数 ;
    ALLEYN2 = whichn(1,  ALLERGY="",  ALLERGY^="");

    *** 方法③ IFN関数 ;
    ALLEYN3 = ifn(ALLERGY^="",  2, 1);

run; 

解説
--- 方法① ------------
論理式の結果が「1:TRUE」か「0:FALSE」で返されるので、それに+1してやれば有無変数になります。

--- 方法② ------------
このやり方については「こちら」で解説してます。

--- 方法③ ------------
IFN関数の構文は「IFN(論理式,  論理式がTRUEの戻り値,   論理式がFALSEの戻り値)」でEXCELのIF関数に似てる。
ただし返す戻り値が数値の場合はIFN、文字の場合はIFCと使い分ける必要があります。


1行プログラム番外編

有無変数を「NO、YES」と文字で持たせたい場合は以下のようになります。

data DT2;
    set DT1;
 
    length ALLEYN4 ALLEYN5 $10.;

    *** 方法① IFC関数 ;
    ALLEYN4 = ifc(ALLERGY^="",  "YES",  "NO");

    *** 方法② CHOOSEC関数 ;
    ALLEYN5 = choosec((ALLERGY^="")+1,  "NO",  "YES");

run;

解説
--- 方法① ------------
前述したIFN関数を使うやり方と同様。

--- 方法② ------------
真偽値と「こちら」で紹介したやり方をミックスした方法です。


注意点

今回紹介した方法は、有無の条件が排反である場合に限ります。
(有無が「有」になる条件以外すべて「無」になるような裏と表の関係)



4 件のコメント:

  1. こんにちわ!
    目新しくないですが、有無変数の作成、僕は以下の書き方なんかもしたことあります。

    data DT2;
    set DT1;
    *** 方法④ CMISS ;
    ALLEYN4 = 2-cmiss(ALLERGY);
    run;

    返信削除
    返信
    1. こんにちは!
      おおっ、CMISS関数ですか!
      関数の結果を引き算に使う発想をあまりしてなかったので、面白いです。
      勉強になります!

      削除
  2. いろいろな方法があり勉強になります。本当にありがとうございます。

    ところで無/有変数に1/2が利用されているのには歴史的背景があります(と思っています)。
    というのは、当初はブランクで入力されたデータファイルをSAS等で読み取ると、ブランクは0となってしまっていたのです(今から30年くらい前でしょうか)。
    ブランクも0、”0”も0と変換されたものですから、無は1、有は2として入力されるようになりました。
    今では論理演算にもそのまま使えるので、無/有には0/1が多くなってきているし、私もそのようにしています。
    過去をそのまま継承している製薬会社も多いようですが、そのあたりどうなんでしょうね。
    個人的には、あまりよくない過去はどんどん捨て去るべきだと思うのです。

    返信削除
    返信
    1. コメントありがとうございます!

      私の周りでは割と1/2としてるのが多いです。

      昔、有無項目を0/1に設計したら、SAS歴の長い方から「1/2の方がいいなー」と言われたことがあったのですが、
      なるほど、そういった歴史があっての事だったのかもしれないですね。

      ありがとうございます。こちらこそ勉強になります。
      またscdenさんがご存じのSASの歴史やテクニックを教えていただきたいです。

      削除