ラベル [▼ 1行プログラミング の投稿を表示しています。 すべての投稿を表示
ラベル [▼ 1行プログラミング の投稿を表示しています。 すべての投稿を表示

2014年5月23日金曜日

1行プログラミング6:TRUE/FALSEを計算に利用する。




たとえばですが、
ある薬を投与してから、とあるイベントが発生するまでの日数を求めたいとします。

ロジックは

日数 = イベント発生日 - 投与開始日 + 1

ただし投与前に起きたイベントは、「イベント発生日 - 投与開始日」 とする。
(投与前日のイベントだったら、+1すると日数=0となって変なので。。)



これをプログラムで書くと、通常は以下のような感じですが、、

DAY = EVENT - START +1;
if  EVENT < START  then  DAY = EVENT - START ;



真偽値(True/False)を使うと1行でスッキリ書けちゃいます。

DAY = EVENT-START + (EVENT >= START) ;



解説

式の中の(EVENT >= START)がポイントで、この条件が成り立つと「1:True」、成り立たないと「0:False」が返されるのを利用して、1を足すかどうかを判断させてます。



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関数を使うやり方と同様。

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


注意点

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



2014年3月28日金曜日

1行プログラムその4:カテゴリ変数の作成



今回は1行でカテゴリ変数 (数値) に置き換える方法。

[年齢]
20歳未満               → 1
20歳以上30歳未満 → 2
30歳以上               → 3


サンプルデータ

data DT1;
input AGE;
cards;
17
23
19
37
27
;

データセットDT1
AGE
17
23
19
37
27

求めたい結果
AGE  AGEGRP
17       1
23       2
19       1
37       3
27       2




1行で書く方法。

普通に書くとこんな感じですが、
data DT2;
   set DT1;
   if  0   <   AGE <20      then  AGEGRP = 1 ;
   if  20 <= AGE <30      then  AGEGRP = 2 ;
   if  30 <= AGE            then  AGEGRP = 3 ;
run;


WHICHN関数で1行でいける。
data DT2;
  set DT1;
  if AGE^=. then AGEGRP = whichn(1, 0<AGE<20, 20<=AGE<30, 30<=AGE);
run;


  • WHICHN関数の構文は「whichn(Y, X1,X2…)」で、Yと同じ数値がXの何番目に初登場するか返してくれます。
  • Yと同じ数値がどのXにもない場合「0」が返されます。
  • Yが欠損値の場合、欠損値が返される。
  • リンクさせて頂いてる「データステップ100万回」の「whichn関数はwhereステートメントでも使える話とその応用をだらだら」で最後に提案されてるアイディアに再インスパイアされて今回の問題に当てはめて利用させて頂きました。


今回の使用法の注意点

・カテゴリ値が1~5くらいまでならいいけど、「年齢=NULL → 100」とか飛び離れたカテゴリ値を設定したい場合、関数の引数を100個指定しなきゃいけなくなるので実用的じゃなくなる → whichn(Y, X1,X2…X100)


2014年3月25日火曜日

1行プログラムその3:数値を任意の文字に置き換える。

その2」の続き、、というかやってる事は同じ。
今回は「1→なし」「2→あり」「3→不明」と文字に置き換えたい場合、CHOOSEC関数を使うと1文でいけます。

1 → なし
2 → あり
3 → 不明

サンプルデータ

data DT1;
input V1;
cards;
1
3
2
;
run;

データセットDT1
V1
 1
 3
 2

求めたい結果
V1  V2
 1    なし
 3    不明
 2    あり



1行で書く方法。

まじめに書くとこんな感じですが、
data DT2;
   length V2  $6.;
   set DT1;
   if V1 = 1 then V2="なし";
   if V1 = 2 then V2="あり";
   if V1 = 3 then V2="不明";
run;


CHOOSEC関数の場合。
data DT2;
   length V2  $6.;
   set DT1;
   if V1^=. then V2=choosec(V1, "なし","あり","不明");
run;

CHOOSEC関数の構文は「choosec(N, X1,X2…)」でN番目のXの値を取得することが出来ます。
Xは文字型の変数または値である必要があります。


今回の使用法の注意点

前回と注意点は同じで、
V1に入る値は1~10くらいまでならいいけど、100とか飛び離れた値があると関数の引数を100個指定しなきゃいけなくなるので実用的じゃなくなる → choosec(N, X1,X2…X100)

1行プログラムその2:数値を任意の数値に置き換える。

その1」の続きです。
前回は1行のプログラムで「1→2」「2→1」と置き換えたけど、「1→10」「2→15」のように任意の値に置き換えたい場合どうすればいいでしょうか?

1 → 10
2 → 15
3 → 100

サンプルデータ

data DT1;
input V1;
cards;
1
3
2
;
run;

データセットDT1
V1
 1
 3
 2

求めたい結果
V1  V2
 1    10
 3    100
 2    15



1行で書く方法。

まじめに書くとこんな感じですが、
data DT2;
   set DT1;
   if V1 = 1 then V2=10;
   if V1 = 2 then V2=15;
   if V1 = 3 then V2=100;
run;


CHOOSEN関数を使うと1文でいけます。
data DT2;
   set DT1;
   if V1^=. then V2=choosen(V1, 10,15,100);
run;

CHOOSEN関数の構文は「choosen(N, X1,X2…)」でN番目のXの値を取得することが出来ます。
Xは数値型の変数または値である必要があります。

最近までこの関数なめてたけど、考えてみると色々使い道があっておもしろいです。


今回の使用法の注意点

V1に入る値は1~10くらいまでならいいけど、100とか飛び離れた値があると関数の引数を100個指定しなきゃいけなくなるので実用的じゃなくなる → choosen(N, X1,X2…X100)

2014年3月13日木曜日

1行プログラムその1:「1→2」「2→1」のような値変換


数行を要するようなプログラムを1行におさめる事を意識した小技や基本技を紹介したいと思います。

まずは初歩的なものから。
コードやスコアなどの値を以下のように逆転させたいことがあります。
1 → 3
2 → 2
3 → 1

サンプルデータ

data DT1;
input V1;
cards;
1
3
2
;
run;

データセットDT1
V1
 1
 3
 2

求めたい結果
V1  V2
 1    3
 3    1
 2    2



1行で書く方法。

まじめに書くとこんな感じですが、
data DT2;
   set DT1;
   if  V1 = 1 then  V2 = 3 ;
   if  V1 = 2 then  V2 = 2 ;
   if  V1 = 3 then  V2 = 1 ;
run;


以下の式を当てはめて書くと1文でいけます。
(開始値 + 終了値) - 変数値

サンプルの場合、「1~3」の範囲の値なので、当てはめると「(1 + 3) - V1」となります。
data DT2;
   set DT1;
   V2 = 4 - V1 ;
run;