2018年7月19日木曜日

PROC FORMAT入門9 : CNTLIN=オプション



(落とし穴もあるので記事を最後までご覧ください。落とし穴を解説した記事のリンクを貼ってます)


CNTLIN=オプションを使うと、「データセット」から「フォーマット」を生成する事ができます。(つまり前回紹介した「CNTLOUT=オプション」の逆が出来る)




まずは簡単な例から。



例1

たとえば、FORMATを定義したいとき以下のように書きますが、、

proc format;
   value TEST1_
       1 = "MALE"
       2 = "FEMALE"
   ;
   value $TEST2_
       "Y" = "YES"
       "N" = "NO"
   ;
run;



別のアプローチ「CNTLIN=オプション」を使って、同様のFORMATを定義できます。
記事の最後に、この方法の落とし穴についてのリンク記事をのせているので必ず参照下さい

*** 定義したいFORMATの内容をデータセットで持たせておく ;

data FMT;
input FMTNAME:$7. START:$1. LABEL:$6.;
cards;
TEST1_ 1 MALE
TEST1_ 2 FEMALE
$TEST2_ N NO
$TEST2_ Y YES
;









*** 先ほどのデータセットをCNTLIN=オプションに指定してFORMATに変換する ;

proc format lib=work cntlin=FMT;
run;


ログ
NOTE: 出力形式TEST1_を作成しました。
NOTE: 出力形式$TEST2_を作成しました。


ログを見ると分かる通り、見事データセットからフォーマット「TEST1_」と「TEST2_」を生成する事が出来ました。



構文

PROC FORMAT LIBRARY=ライブラリ.カタログ名  CNTLIN=FORMAT変換用のデータセット;
RUN;

  • LIBRARY=ライブラリ名」というようにカタログ名を省略した場合、ライブラリ内の「FORMATS」という名前のカタログがデフォルトで選択されます。
  • FORMAT変換用のデータセットには少なくとも「FMTNAME」「START」「LABEL」という変数が必要です。

あとは以下の中から、定義したいFORMATにあわせて、必要な変数を選択してデータセットに含めます。



CNTLIN = データセットの各変数の説明

 変数名 型 内容 
 FMTNAME  文字   フォーマット名
 START 文字 開始値
 END 文字 終了値
 LABEL 文字 出力値
 MIN 数値 MIN=オプション値 
 MAX 数値 MAX=オプション値
 DEFAULT
 数値 DEFAULT=オプション値 
 LENGTH  数値 LENGTH=オプション値
 FUZZ   数値 FUZZ=オプション値
 PREFIX   文字 PICTUREフォーマットのPREFIX=オプション値 
 MULT 

 数値

 MULTIPLIER=オプション値
 (PICTUREフォーマットの場合、指定してなくても勝手に入る)
 FILL  文字 PICTUREフォーマットのFILL=オプション値
 NOEDIT   数値 PICTUREフォーマットのNOEDITオプションが有効かどうか
 (1=有効 0=無効)
 TYPE 

 文字

 フォーマットの種類
  N = 数値フォーマット
  C = 文字フォーマット
  I = 数値インフォーマット
  J = 文字インフォーマット
  P = PICTUREフォーマット

 SEXCL

 文字

 開始値の取扱い
 ("Y"=開始値超 "N"=開始値以上)

 EEXCL  

 文字

 終了値の取扱い
 ("Y"=終了値未満 "N"=終了値以下)

 HLO

 文字

 開始値・終了値の追加情報
  O = OTHER
  L = LOW
  H = HIGH
  R =「round=オプション」を有効に
  ...等 

 (組み合わせて使用する事も可能 例:Low-High…LH)

 DECSEP  文字 DECSEP=オプション値
 DIG3SEP 文字 DIG3SEP=オプション値
 DATATYPE  文字 PICTUREフォーマットのDATETYPE=オプション値
 LANGUAGE 文字 LAUNGUAGE=オプション値

これ見て頂くと分かる通り、前回紹介したCNTLOUT=で出来るデータセットと同じ構造です。



ここまで特に難しいことはないんですが、、ただですね、、
CNTLIN=オプションは先の例のような簡単なFORMATを定義する分にはいいけど、複雑なFORMATを定義したい場合、それなりの知識が必要になります。


例えば、以下のPICTUREフォーマットをご覧ください。



例2

proc format;
   picture TEST7_ (round)
      low - high = '009.00%'
   ;
run;

ここで問題です。
上のと同様のフォーマットをCNTLIN=で作るには、どんなプログラムを書けばよいでしょうか?




以下が正解の一例。

data FMT2;
length FMTNAME START END LABEL $10. MULT 8. TYPE HLO $10.;

FMTNAME = 'TEST7_';
START   = 'LOW';
END     = 'HIGH';
LABEL   = '009.00%';
MULT    = 100;
TYPE    = 'P';
HLO     = 'LHR';
run;





proc format lib=WORK cntlin=FMT2;
run;

パッとこれが思い浮かべばいいですが、詳しくないと中々難しいと思います。

私の知る限り、実務ではこの記事の最初の方に載せた「例1」程度の簡単なフォーマットを作るのにCNTLIN=オプションを使っているのはよく見かけますね。



最後に、割と問題ありな落とし穴もあります。以下記事をご覧ください。

6 件のコメント:

  1. いつも参考にさせて頂いています。ラベルに誤字ありますのでご報告まで。
    誤:▼ FOMRATプロシジャ入門
    正:▼ FORMATプロシジャ入門

    返信削除
    返信
    1. ご指摘有難う御座います、修正させていただきました!

      削除
  2. いつも勉強させて頂いております!
    CNTLINでフォーマットカタログを作成しましたが、LABELの内容(男)から「1」等の値を充てることはできますでしょうか?

    返信削除
    返信
    1. コメントありがとうございます。
      文字変数にFORMATを割りあてて、数値変数のように見せたいということでしょうか。
      たしか「数値変数のように見せる」というのは出来なかったと思います。。

      削除
  3. 立て続けに申し訳ございません。追加で、「0101」等を読み込ませた際にあたまのゼロが落ちてしまう対策ができないか、ご教示頂きたいです。

    返信削除
    返信
    1. すみません。。ちょっとお困りの状況が分からなかったのですが、
      どういった状況か、適当なサンプルプログラム、もしくはお困りの詳細な状況を記載いただく事は可能でしょうか。

      削除