以下のプログラムと結果をご覧ください。結果は想定通りでしょうか?
proc format;
value $FMT
"a" = "x"
"abc" = "y"
;
run;
data DT1;
format VAR1 $FMT.;
VAR1 = "abc";
run;
|
変数VAR1は "abc" なのでフォーマット$FMTを貼りつけると "y" と表示されるはずが、 "x" が表示されてしまいました。
原因
これは「デフォルト長 (Default Length)」というものが関係してます。
例えば、今回の例で
proc format;
value $FMT
"a" = "x"
"abc" = "y"
;
run;
右側に定義した値 ("x" と "y") の文字の長さは1バイトです。
この長さが、そのフォーマットの「デフォルト長」というものになります。
(定義した値が複数ある場合は、右側の文字の長さが最も大きいものがそのフォーマットの「デフォルト長」になる)
そしてこのフォーマット$FMTは、以降のFORMATステートメントでデフォルト長となった1バイトしか視界に入らなくなります。
どういう事かというと、、
data DT1;
format VAR1 $FMT.;
VAR1 = "abc";
run;
変数VAR1 の値 "abc" から先頭の1バイトの値 "a" だけを見て対応するフォーマット値を表示しようとします。
ちょうど PROC FORMAT で "a" = "x" と定義してたので、この値が表示されちゃったというわけですね。
proc format;
value $FMT
"a" = "x"
"abc" = "y"
;
run;
解決策
変数VAR1 の値 "abc" の文字の長さは3バイトなので、3バイト全部読み込んで表示する必要があります。
解決策としては以下の2つの方法があります。
解決策①
proc format;
value $FMT (default=10)
"a" = "x"
"abc" = "y"
;
run;
data DT1;
format VAR1 $FMT.;
VAR1 = "abc";
run;
|
「DEFAULT=オプション」によってこのフォーマットのデフォルト長を 10 に広げています。
解決策②
proc format;
value $FMT
"a" = "x"
"abc" = "y"
;
run;
data DT1;
format VAR1 $FMT 10.;
VAR1 = "abc";
run;
|
FORMATステートメントで、フォーマット名の後ろに幅を指定することも出来ます。
See also
インフォーマットでも同様の落とし穴があります。
INFORMATの落とし穴【デフォルト長】
ポイント
・文字値から数値に変換するインフォーマットの場合、「左側」に定義した文字の長さ
がデフォルト長になる。
・フォーマットの場合、「右側」に定義した文字の長さ
がデフォルト長になる。