以下のプログラムと結果をご覧ください。結果は想定通りでしょうか?
proc format;
invalue MYFMT "abc" = 1 ; run; data DT1; X = "abcdefg"; Y = input( X , MYFMT. ); run;
|
変数Y が 1 という結果はおかしいですよね。これって
・INFORMATの値 … "abc"
・変数X の値 … "abcdefg"
これは、INFORMATの「デフォルト長 (Default Length)」というものが関係してます。
例えば、今回の例では、、
proc format;
invalue MYFMT
"abc" = 1
;
run;
左側に定義した値 "abc" の文字の長さは3バイトです。
文字値から数値に変換するINFORMATの場合、この長さがそのINFORMATの「デフォルト長」というものになります。
(定義した値が複数ある場合は、文字の長さが最も大きいものがそのINFORMATの「デフォルト長」になる)
そしてこのINFORMATは、以降の処理でデフォルト長となった3バイトしか視界に入らなくなります。
どういう事かというと、、
data DT1;
X = "abcdefg";
Y = input( X , MYFMT. );
run;
変数X の値 "abcdefg" から先頭の3バイトの値 "abc" だけを見てINFORMATによる変換が行われるという事です。
ちょうど PROC FORMAT で"abc" を定義してたので、変換しちゃったってわけですね。
proc format;
invalue MYFMT
"abc" = 1
;
run;
変数X の値 "abcdefg" の文字の長さは7バイトなので、7バイト全部読み込んで変換する必要があります。
解決策としては以下の2つの方法があります。
解決策①
proc format;
invalue MYFMT (default=20)
"abc" = 1
;
run;
data DT1;
X = "abcdefg";
Y = input( X, MYFMT. );
run;
|
「DEFAULT=オプション」によってこのINFORMATのデフォルト長を 20 に広げています。
proc format;
invalue MYFMT
"abc" = 1
;
run;
data DT1;
X = "abcdefg";
Y = input( X, MYFMT20. );
run;
|
INPUT関数による変換時に、INFORMAT名の後ろに読み込む幅を指定することも出来ます。
フォーマットでも同様の落とし穴があります。
FORMATの落とし穴【デフォルト長】
ポイント
・文字値から数値に変換するインフォーマットの場合、「左側」に定義した文字の長さがデフォルト長になる。
・フォーマットの場合、「右側」に定義した文字の長さがデフォルト長になる。
0 件のコメント:
コメントを投稿