ラベル ORDER= の投稿を表示しています。 すべての投稿を表示
ラベル ORDER= の投稿を表示しています。 すべての投稿を表示

2019年7月5日金曜日

「ORDER=DATA」「ORDER=FREQ」の落とし穴




以前「ORDER=オプション」を紹介しました。

このオプションの「ORDER=DATA」と「ORDER=FREQ」には注意が必要です。
以下の例が想定通りの結果になるか各自確認してみてください。



「ORDER=DATA」の挙動確認

* サンプルデータ ;
data test;
input x y:$1.;
cards;
1 b
1 a
2 c
2 a
2 b
;

* PROC REPORTで「ORDER=DATA」 ;
proc report data=test;
   define x / order order=data;
   define y / order order=data;
run;

「x=2の時の順番が「c → a → b」から「b → a → c」になってしまった?」と疑問に思った方は要注意!


解説

「ORDER=DATA」は「データセットに格納されてるままの順番」に出力されると思いがちですが、
「登場した値の順に並び替える」というのが正確ですね。今回の例では、

  • x=1 の時「b → a」の順に値が登場します。
  • x=2 の時「c → a → b」の順に値が登場していますが、上で既に「b → a」の順で登場しているので、「b → a → c」の順に並び替えられます。



「ORDER=FREQ」の挙動確認

* サンプルデータ ;
data test2;
input x y:$1.;
cards;
1 a
1 a
1 b
2 a
2 b
2 b
2 b
2 c
2 c
;


* PROC SUMMARYで「ORDER=FREQ」 ;
proc summary data=test2 print order=freq;
   class x y;
run;


「ORDER=FREQ」は度数が「多い」または「小さい」順に出力されます。
プロシジャごとに「多い順」か「小さい順」の設定が異なっており、

PROC FREQの場合、明示的に指定していない場合、「多い順」に並ぶ.....はずだけど、
「全然、多い順に並んでない?」と疑問に思った方は要注意!


解説

まずCLASS変数 x, y について、別々に度数を計算します。

  • x=1 の度数: 3
  • x=2 の度数: 6
    • x の度数順は「x = 2 → 1」

  • y=a の度数: 3
  • y=b の度数: 4
  • y=c の度数: 2
    • y の度数順は「y = b → a → c」

てことで、x =「2 → 1」、y = 「b → a → c」の順番で並び替えられます。



2017年4月3日月曜日

「ORDER=FORMATTED」の落とし穴




前回の記事で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=は他のプロシジャと整合とるために今後のリリースでデフォルト設定を変えるかも、というような記述があるので、この点も要注意ですね。



2017年3月28日火曜日

一部の集計系プロシジャで使える 「ORDER=オプション」で分類変数の値の出力順をカスタマイズする。




一部の集計系プロシジャ(PROC FREQ, MEANS, REPORTなど)では「ORDER=オプション」をサポートしています。

例えば性別の頻度集計で「男→女」や「女→男」の順で出すなど、出力順をカスタマイズできます。


今回はPROC FREQでの使用例を見ていきましょう。



サンプルデータ

data DT1;
input A @@;
cards;
2 1 1 3 3 3
;




ORDER=オプションの指定例


📝 注意
-----------------------------------------------------------------------
他のオプションとの組み合わせで、ORDER=オプションが機能しなかったり、出力順が変わることがあります。詳細はリファレンスを確認下さい。
(例えば、PROC MEANS等で「PRELOADFMT」や「CLASSDATA=」オプションを使う場合など)
-----------------------------------------------------------------------


  • ORDER = INTERNAL … 変数値を昇順に並び替えて出力
proc freq data=DT1  order=internal;
  tables A;
run;



PROC FREQのデフォルトはORDER=INTERNALです。


  • ORDER = DATA … データセットに格納されている値の順に出力
proc freq data=DT1  order=data;
  tables A;
run;

注意点:「ORDER=DATA」の落とし穴


  • ORDER = FREQ … 度数が「多い」または「小さい」順に出力
  • プロシジャごとに「多い順」か「小さい順」の設定が異なる
proc freq data=DT1  order=freq;
  tables A;
run;



  • ORDER = FORMATTED … 変数に割り当てたフォーマットに変換させた時の値順。
proc format;
value SEX
1="MALE"
2="FEMALE"
3="UNANSWERED"
;
run;
proc freq data=DT1  order=formatted;
  tables A;
  format A SEX.;
run;




ORDER=オプションの指定場所

指定場所は以下のように様々です。詳細が知りたい方は別途リファレンスをご覧ください。

* PROC MEANS : CLASS変数全体にORDER=オプションを適用 ;
proc means data=xx order=internal;
 var xx;
 class yy;
run;

* PROC MEANS : CLASS変数YYにORDER=オプションを適用 ;
proc means data=xx ;
 var xx;
 class yy / order=internal;
 class zz ;
run;

* PROC REPORT : 出力変数XXにORDER=オプションを適用 ;
proc report data=xx;
  column xx yy;
  define xx / order order=internal;
  define yy / display;
run;



Tips

今回紹介したオプションの他に、よく使用されるMISSINGオプションも参考に。