2017年9月13日水曜日

ODS OUTPUT の落とし穴 (1)



まず以下うまくいく例をご覧ください。

うまくいく例
ods output OneWayFreqs=OUT1;

   proc freq data=SASHELP.CLASS;
      tables SEX AGE;
   run;

ods output close;



次にうまくいかない例。

うまくいかない例
ods output OneWayFreqs=OUT1 (where=(AGE=13));

   proc freq data=SASHELP.CLASS;
      tables SEX AGE;
   run;

ods output close;

ログ
ERROR: 変数AGEはファイルWORK.OUT1にありません。


WHERE=オプションを追加したらERRORが出ちゃいました。
構文的には問題ないのに何故でしょう?



原因


以下のように ODS TRACE で出力オブジェクト名をログに表示してみると、、

ods trace on;

proc freq data=SASHELP.CLASS;
   tables SEX AGE;
run;

ods trace off;

ログ
出力の追加 :
-------------
名前 :         OneWayFreqs
ラベル :       一元表
テンプレート : Base.Freq.OneWayFreqs
パス :         Freq.Table1.OneWayFreqs
-------------

出力の追加 :
-------------
名前 :         OneWayFreqs
ラベル :       一元表
テンプレート : Base.Freq.OneWayFreqs
パス :         Freq.Table2.OneWayFreqs

出力オブジェクト「OneWayFreqs」が2つ出てますね。

PROC FREQ の TABLESステートメントで「tables SEX AGE」と書いているため、
SEXとAGEそれぞれに出力オブジェクト「OneWayFreqs」が出来ている事を表しています。



そしてここから予想になるのであしからずという感じですが、

ods output OneWayFreqs=OUT1 (where=(AGE=13));

   proc freq data=SASHELP.CLASS;
      tables SEX AGE;
   run;

ods output close;

と書いたときの挙動として、

① 変数 SEX の集計結果をデータセット OUT1 に出力
② 変数 AGE の集計結果をデータセット OUT1 に出力

となりますが、どうやらWHERE=オプションは上記①②のそれぞれで実行されている気がします(色々実験した結果の予想)

つまり①の時点では出力データセットに 変数 AGE の集計結果が存在していないので、「where=(AGE=13)」は ”存在していない変数に対するWHERE条件” となりERRORが出てしまったというわけですかね。

PROC FREQに限らず、同じ名前の出力オブジェクトが複数出力されるようなケースでは同様に注意が必要です。



内部挙動は予想になってしまうので、
この辺ちゃんと説明しているサイトなどご存知の方いたら教えて下さい。


ちなみに、以下記事でその他の落とし穴も紹介しています。
「ODS OUTPUT」の落とし穴 (2)

0 件のコメント:

コメントを投稿