前回の記事でORDER=オプションを紹介しました。
http://sas-boubi.blogspot.jp/2017/03/order_28.html
このオプションで一番注意しなければならないのが、「ORDER=FORMATTED」を指定した場合です。
以下の例が想定通りの結果になるか各自確認してみてください。
「ORDER = FORMATTED」 の挙動確認
* サンプルデータ ;
data DT1;
input A @@;
cards;
1 1 1.5 1.5 2 2
;
* PROC FREQで「ORDER=FORMATTED」 ;
proc freq data=DT1 order=formatted;
tables A;
run;
|
あれ!?
特にフォーマットも割り当ててないし、「1→1.5→2」の順になるかと思ったら「1→2→1.5」になってる。。
原因
何故かというと、、
(ここから推測ですので間違ってるかもしれないのであしからず。)
以下のプログラムで変数Aに割り当てられているフォーマットをログに出力してみると、
data _null_;
set DT1;
x=vformat(A);
put x;
stop;
run;
ログ
BEST12.
|
数値変数の場合、フォーマットが割り当てられていないと、内部的にBEST12.があてられているっぽい?
では、PUT関数を使って、変数AをBEST12.で文字変換してみましょう。
data DT2;
set DT1;
length A2 $20.;
A2 = put(A,best12.);
run;
|
文字変換したA2を見ると、以下のように先頭に半角スペースが入ってしまいます。
1 → "
1"
1.5 → "
1.5"
2 → "
2"
この文字変換したA2でソートしてみると、、
proc sort data=DT2;
by A2;
run;
|
文字値によるソート&先頭の半角スペース込みのソートなので、本来の数値の順番にソートがされないって事ですね。
プロシジャ毎にORDER=オプションのデフォルト設定が違う
「ORDER=INTERNAL」がデフォルトになっているプロシジャが多い中、いくつか例外があります。
例えばPROC REPORTです。
SAS9.4 (2016/4/3現在) では、デフォルトが「ORDER=FORMATTED」に設定されています。
proc report data=DT1;
column A;
define A / group;
run;
proc report data=DT1;
column A;
define A / order;
run;
|
順番おかしいですね。フォーマットではなく変数値の順に並べ替えたい場合は、以下のように「ORDER=INTERNAL」を別途指定します。
proc report data=DT1;
column A;
define A / group order=internal;
run;
proc report data=DT1;
column A;
define A / order order=internal;
run;
|
SAS9.4のリファレンスには、PROC REPORTのORDER=は他のプロシジャと整合とるために今後のリリースでデフォルト設定を変えるかも、というような記述があるので、この点も要注意ですね。