2022年7月9日土曜日

【PROC FORMAT】CNTLIN=オプションの落とし穴



まず、前提知識として「PROC FORMAT入門9 : CNTLIN=オプション 」をご参照下さい。


そして、ここから本題。以下の例をご覧ください。


失敗例

①まず「データセット」から「フォーマット」を生成

data FMT;
input FMTNAME:$10. START:$10. LABEL:$20.;
cards;
$TEST_ OTHER その他
;


proc format cntlin=FMT;
run;


②実データに先ほどのフォーマットを当ててみる。

data TEST;
input X:$20.;
cards;
OTHER
.
;


data TEST2;
 set TEST;
 format X $TEST_.;
run;


あれ?!

フォーマット当てた結果、2行目の欠損値に「その他」が当てられてしまってる?!


解説

「CNTLIN=」に使用するフォーマット生成用のデータセットに注目


実は上の "OTHER" が、範囲指定としての「OTHER」として解釈されてしまってます(範囲指定?という方は「PROC FORMAT入門2 : 範囲の指定」を参照)

要は、以下のようにFORMATプロシジャで①みたいな定義をしたつもりが、②の定義をしてしまった、ということ。

proc format; /* ① */
 value $TEST_
 "OTHER" = "その他"
 ;
run;

proc format; /* ② */
 value $TEST_
 OTHER = "その他"
 ;
run;

余計なことをしてますね。。


ちなみに、"OTHER" 以外にも、FORMATプロシジャの予約語的なキーワードは気を付けた方が良いです(色々実験してみたところ、"LOW", "HIGH" なども同様に範囲指定の意味として解釈されてしまいました。たぶん他にもあると思います)



解決策

今回の例では "OTHER" を範囲指定の意味ではないと明示してあげる必要があります。
なので、以下のようにHLOという変数を作ってNullに設定しておけば良いはず。
(HLO?という方は「PROC FORMAT入門9 : CNTLIN=オプション」を参照)

data FMT;
input FMTNAME:$10. START:$10. LABEL:$20. HLO:$1.;
cards;
$TEST_ OTHER その他 .
;


proc format cntlin=FMT;
run;



上でフォーマットを作り直したので、再度このフォーマットをあてたデータセットを見てみましょう。

はい!さっきまで2行目の欠損値が「その他」になっちゃってましたが、今度は問題なさそうです。


最後に

私が把握しているのは "OTHER", "LOW", "HIGH" のみで、その他にFORMATプロシジャの予約語的なキーワードに引っかかるものがあるかもしれません。

今回の場合だと"OTHER"に対してHLOという変数を作ってNullに設定することで解決しましたが、その他の私が把握していないキーワードに対して、各自SASのリファレンスや「PROC FORMAT入門9 : CNTLIN=オプション」などを参考にして、他の必要な変数を設定してあげる必要があります。



0 件のコメント:

コメントを投稿