2018年2月6日火曜日

PROC FORMAT入門2 : INVALUEステートメント




今回は「INVALUEステートメント」について。
データを読み込む際、以下の変換をする「インフォーマット」と呼ばれるものを定義するステートメントです。

  • 文字値から数値(例:男→1→2
  • 文字値から文字値(例:Y→YES、N→NO


※ INVALUEステートメントの重要な性質(落とし穴)についても、解説記事のリンクを最後の方に載せてるので、そちらも要確認!



実際、例を見た方が分かり易いです。まずは変換を行うインフォーマットの定義から。



インフォーマットを定義する例

proc format;

   invalue TEST1_
      "MALE"     = 1
      "FEMALE" = 2
   ;
   invalue $TEST2_
      "Y"    = "YES"
      "N"    = "NO"
   ;
run;

  • 「TEST1_」というインフォーマットを定義し、「"MALE"→1、"FEMALE"→2」 という変換を定義(数値に変換するインフォーマットを「数値インフォーマット」という)

  • 「TEST2_」というインフォーマットを定義し、「"Y"→"YES"、"N"→"NO"」 という変換を定義(文字値に変換するインフォーマットを「文字インフォーマット」という)



構文
PROC FORMAT;

      INVALUE インフォーマット名
         値  =  変換後の値
         値  =  変換後の値
         ・・・
     ;
RUN;


ポイント
  • インフォーマット名の最後は数字じゃダメ(例えば「TEST1」など)
  • 「"Y"→"YES"」のような文字から文字への変換を行うインフォーマットは、インフォーマット名の先頭に「$」をつける(例えば「$TEST」など)



では、先程つくったインフォーマットを使ってみましょう。


インフォーマットを使う例①

data DT1;
   length SEX 8. YN $3.;
   input SEX YN;
   informat SEX TEST1_. YN $TEST2_.;
cards;
MALE Y
FEMALE N
;
 SEX  YN 
  1  YES 
  2  NO


CARDSで読み込むデータに対して「INFORMATステートメント」で以下を行なっています。

  • インフォーマット「TEST1_」を使い「"MALE"→1、"FEMALE"→2」に変換した値を変数 SEX に格納
  • インフォーマット「TEST2_」を使い「"Y"→"YES"、"N"→"NO"」に変換した値を変数 YN に格納



構文
INFORMAT  変数名  インフォーマット名. ;


ポイント
  • テキストファイル や CARDS で読み込むデータに対して、インフォーマット変換した値を変数に格納する。
  • インフォーマット名の後ろにドット「.」を入れる必要があります。




インフォーマットを使う例②

* Sample data ;
data DT1;
   length SEX $6. YN $1.;
   SEX="MALE"; YN="Y"; output;
   SEX="FEMALE"; YN="N"; output;
run;

SEX  YN 
 MALE  Y
 FEMALE  N


* 変数値をインフォーマットで変換する ;
data DT3;
   set DT1;
   length SEX2 8. YN2 $3.;
   SEX2 = input( SEX, TEST1_.);
   YN2  = input( YN , $TEST2_.);
run;

SEX 
 YN 
 SEX2 
 YN2 
 MALE
 Y 
  1
 YES 
 FEMALE  
 N
 
 NO



上の例では「INPUT関数」を使って以下を行なっています。
  • 変数 SEX の値を インフォーマット「TEST1_」を使って変換し、変数 SEX2 に格納。
  • 変数 YN の値を インフォーマット「TEST2_」を使って変換し、変数 YN2 に格納。



構文
新規変数名 = INPUT(  変数名 ,  インフォーマット名.  );


ポイント
  • 文字変数に対して、インフォーマットを使って数値または文字に変換します。
  • インフォーマット名の後ろにドット「.」を入れる必要があります。




注意が必要なインフォーマットの細かい挙動

proc format;

   * (1) 数値インフォーマット1 ;
   invalue X1_ (default=20)
      "1" = 111
      other = 999
   ;
   * (2) 数値インフォーマット2 ;
   invalue X2_ (default=20)
      1 = 111
      other = 999
   ;
   * (3) 文字インフォーマット1 ;
   invalue $X3_ (default=20)
      "1" = "111"
      other = "999"
   ;
   * (4) 文字インフォーマット2 ;
   invalue $X4_ (default=20)
      1 = "111"
      other = "999"
   ;
run;

* インフォーマットで変換 ;
data DT4;
   length X $20. X1 X2 8. X3 X4 $20.;
   X = "+1.0";
   X1 = input(X,X1_.);
   X2 = input(X,X2_.);
   X3 = input(X,$X3_.);
   X4 = input(X,$X4_.);
run;

X 
 X1 
 X2 
 X3 
 X4 
 +1.0 
 999  111  999  999 


上で作成した (2) のインフォーマットだけ、変換した結果が異なります。
これは以下のような文字値から数値に変換する「数値インフォーマット」かつ青文字部分の定義で「左側に指定した数値をクォーテーションで囲っていない」場合、、

proc format;
 invalue X2_ (default=20)
  1 = 111
  other = 999
 ;
run;

数値としてマッチした値に対して変換することが出来ます。
例えば、文字変数Xの値「+1.0」を数値化すると「+1.0」→「1」なので、上の青文字部分の定義とマッチするので変換が行われます。

その他の (1) (3) (4) で作成したインフォーマットでは、左側に指定した数値をクォーテーションで囲う・囲わない関係なく、文字値としてマッチした値のみ変換します。

(ちなみに、上の例で「default=オプション」を指定しているのは、以下の注意事項の2個目で解説しているデフォルト長による落とし穴予防のためです)




注意事項・落とし穴

  • インフォーマットで「文字値の欠損値」を表す場合「" " = "欠損値"」のような指定になります(「""」ではなく「" "」というように間に半角スペースを入れないと欠損値の意味にならない)
  • INFORMATの落とし穴【デフォルト長】




PROC FORMAT入門 : 記事一覧

2. INVALUEステートメント
3. 範囲の指定

0 件のコメント:

コメントを投稿