2018年2月20日火曜日

PROC FORMAT入門4 : PICTUREステートメント




今回は「PICTUREステートメント」について。

例えば「1→001、12→012」とか、「1234→12-34、5678→56-78」のように数値を特定の書式に読み替え・変換したい場合に使います。





構文


   PROC FORMAT;

      PICTURE フォーマット名
          値  =  '書式の定義'  (オプション)
          値  =  '書式の定義'  (オプション)
          ・・・
      ;
   RUN;


※ フォーマット名の末尾は数字NG(例えば「TEST1」など)




* PICTUREフォーマットの定義 ;
proc format;
   picture NINE
       low - high = "99-99"
   ;
   picture ZERO
       low - high = "00-00"
   ;
run;


・フォーマット「NINE」を定義して、出力する値の書式を '99-99' としています。9の意味は「先頭の数値がないところを0で埋める」という意味で、今回の場合は「123→"01-23"」や「1→"00-01"」のような変換がされる。

・フォーマット「ZERO」を定義して、出力する値の書式を '00-00' としています。0の意味は「先頭の数値がないところを空白で埋める」という意味で、今回の場合は「123→" 1-23"」や「1→"    1"」のような変換がされる。


この書式設定に使う 0 や 9 を「数字セレクタ」といいます。
(1 ~ 8 も 9 と同じ意味を持つ数字セレクタです)



ではこのフォーマットを使ってみます。

* Sample Data ;
data DT1;
input X;
cards;
.
1
12
123
1234
12345
;

* フォーマット変換してみる ;
data DT2;
   set DT1;
   length NINE ZERO $10.;
   NINE = put(X,NINE.);
   ZERO = put(X,ZERO.);
run;
 X  NINE  ZERO 
    . 
  
    1 
 00-01     1
   12 
 00-12   12
  123 
 01-23 1-23
  1234 
 12-3412-34
  12345 
 23-4523-45

結果を見ると性質を理解しやすいです。
気をつけたいのが、今回「数字セレクタ」の部分を「00-00」のように4桁しか定義してないから、最後のオブザベーションの結果が「12345→23-45」って感じで桁が足りなくて「1」が切れちゃってるとこですかね。




では続いて、PICTUREフォーマットで用意されているオプションも見ていきましょう。


PICTUREフォーマットのオプション

  オプション内容  プログラム例
フォーマット変換後に空白となった部分を指定文字で埋める 

 ( FILL = '文字' )

  proc format;
    picture test1_
      low - high = '00-00' (fill='*');
  run;

  フォーマット変換の例
 「123」→「*1-23」
 「1」    →「****1」

0~9を数字セレクタではなく、文字として扱う

 ( NOEDIT )

  proc format;
    picture test2_
      low - high = '00-00' (noedit);
  run;

  フォーマット変換の例
 「123」→「00-00」
 「1」    →「00-00」

フォーマット変換した値の先頭に表示する文字の指定


 ( PREFIX = '文字' )

  proc format;
    picture test3_ (default=5)
      low - high = '0000' (prefix='-');
  run;

  フォーマット変換の例
 「123」→「 -123」
 「1」    →「   -1」

フォーマット変換前に変数値に掛ける数値を指定

 MULTIPLIER = 数値 )


※ただし以下リンクの通り、かなり取扱い注意なオプション
(http://sas-boubi.blogspot.jp/2018/03/proc-formatpicture.html)


  proc format;
    picture test4_
      low - high = "0000" (multiplier=10);
  run;

  フォーマット変換の例
 「123」→「1230」
 「1」    →「  10」





一応、PREFIXオプションだけ詳細説明しときます。
たとえば以下にマイナスの値を含むデータがあります。

* Sample Data ;
data dt1;
input x;
cards;
-12
12
;
 X 
 -12 
   12 


このデータに以下のフォーマットを割り当てると、、

* Mistake (間違っている例) ;
proc format;
   picture test1_ (default=5)
     low - high = '00'
   ;
run;

data dt2;
   set dt1;
   format x test1_.;
run;
 X 
 12 
   12 

数値部分だけになり、マイナス記号が消えてしまいます。


それならば、という事で以下のように '-00' という書式を用意してみますが、、

* Mistake (間違っている例) ;
proc format;
   picture test1_ (default=3)
     low -< 0 = '-00'
     0 - high = '00'
   ;
run;

data dt2;
   set dt1;
   format x test1_.;
run;
 X 
 12 
   12 

やっぱりマイナス記号消えちゃいます。
PICTUREフォーマットは、'-00' みたいに「書式の先頭に文字を入れてもその文字は無視される」という仕様になっています。


なぜそんな仕様なのかよく分かりません。
てことで、先頭に文字を入れたい場合は、prefixオプションを使います。

* 正しい例 ;
proc format;
   picture test1_ (default=3)
     low -< 0 = '00' (prefix="-")
     0 - high = '00'
   ;
run;

data dt2;
   set dt1;
   format x test1_.;
run;
 X 
 -12 
   12 


ちなみに「picture test1_ (default=3)」って感じで、defaultオプションというのを指定していますが、これをつけないと文字切れしちゃうケースがあるのでご注意を!
(理由は以下で紹介している落とし穴と同じ。)

INFORMATの落とし穴【デフォルト長】






PROC FORMAT入門 : 記事一覧

2. 範囲の指定
3. INVALUEステートメント
4. PICTUREステートメント1
10. その他の小ネタ

0 件のコメント:

コメントを投稿