ラベル ステートメント: QUIT の投稿を表示しています。 すべての投稿を表示
ラベル ステートメント: QUIT の投稿を表示しています。 すべての投稿を表示

2018年2月15日木曜日

ODS OUTPUT の落とし穴 (2)



以下記事の続き。
ODS OUTPUT の落とし穴 (1)



以下のプログラム、WARNINGが出ちゃいますが、どこがおかしいか分かりますか?

proc glm data=sashelp.class;
   class sex;
   model height = sex;
run;

ods output Summary=OUT1;
proc means data=sashelp.class;
   var height;
run;
ods output close;


ログ
WARNING: 出力'Summary'は作成されていません。出力オブジェクト名、ラベル、パスが正しく記述されているかを確認してください。また、要求した出力オブジェクトを作成するために、
         適切なプロシジャオプションが使われているかも確認してください。たとえば、NOPRINTオプションが使われていないことを確認してください。
WARNING: プロシジャステートメントの終わりを検出したので、現在のODS SELECT/EXCLUDE/OUTPUTステートメントをクリアしました。
         対話型プロシジャ(終了するにはquit;をタイプします)が終了していないかもしれません。



この落とし穴にはまってる人たまに見かけます。


これは対話型プロシジャを使う場合に起こる落とし穴です。
(対話型プロシジャについては、「RUNとQUITの違い」をご覧ください。)


今回の例で使用しているGLMプロシジャは対話型プロシジャです。
「QUIT」と書くか、別のDATAステップ・PROCステップが現れるまで、GLMプロシジャは起動したままになります。
なので、以下の青文字部分がGLMプロシジャに対する処理だと判断されてしまいます。


proc glm data=sashelp.class;
   class sex;
   model height = sex;
run;

ods output Summary=OUT1;
proc means data=sashelp.class;
   var height;
run;
ods output close;



解決方法はご存じの通り、「quit;」を入れるだけです。

proc glm data=sashelp.class;
   class sex;
   model height = sex;
run;
quit;

ods output Summary=OUT1;
proc means data=sashelp.class;
   var height;
run;
ods output close;




そもそもSASのマニュアルにも対話型プロシジャにQUITを入れていない例があるので、
この問題に気づかなくても無理はないっちゃないんですが。。


ちなみに、今回紹介した落とし穴は「ods output」だけでなく、「ods select」「ods exclude」とかでも同様に起こる問題です。

2018年1月25日木曜日

RUNとQUITの違い【対話型プロシジャ】





プロシジャには「RUN」で終わらせるものと、「QUIT」で終わらせるものがあります。



RUNで終わる例
proc print data=SASHELP.CLASS;
run;

proc means data=SASHELP.CLASS;
   var HEIGHT;
run;


QUITで終わる例
proc datasets nolist;
  copy in=SASHELP out=WORK;
  select CLASS;
run;
quit;


proc sql;
  select *
  from SASHELP.CLASS;
quit;




「RUN」と「QUIT」どちらで終わるのかは、プロシジャが対話型かどうかで決まります。
対話型について、以下SAS社FAQを見ると分かり易いと思います。

「対話型プロシジャの終了方法」
https://www.sas.com/offices/asiapacific/japan/service/technical/faq/list/body/ba022.html


つまり、
通常は「RUN」でプロシジャを終了させることが出来ますが、対話型プロシジャの場合は「RUN」で実行されるものの、プロシジャは終了しません。
「QUIT」と書くか、別のDATAステップ・PROCステップが現れるまで、プロシジャは起動したままになります。



対話型プロシジャの例



・DATASETSプロシジャの場合

以下を実行したとします。
proc datasets nolist;
  copy in=SASHELP out=WORK;
  select CLASS;
  run;


確かに「RUN」のタイミングで実行はされるんですが、「QUIT」がないのでプロシジャは開いたままです。なので以下のように続けて書くことが出来ます。

  copy in=SASHELP out=WORK;
  select BASEBALL;
  run;
quit;




・SQLプロシジャの場合

以下を実行したとします。
proc sql;
  select * from SASHELP.CLASS;


「QUIT」でプロシジャを終了させていないので、以下のように続けて書くことが出来ます。

  select * from SASHELP.CLASS where AGE = 13;
quit;


(※SQLプロシジャの場合は「RUN」ではなく「;」で実行されるので、他の対話型プロシジャとはちょっと異なる)


SQLプロシジャの対話型機能をつかった書き方については、以前ちょっと紹介してます。
複数のSQL文は、ひとつのPROC SQLにまとめて書くことが出来る




対話型プロシジャかどうかの見分け方


私の場合、
「RUN」の実行後に以下のようなLogメッセージが出ない場合は、プロシジャの処理が完了していないという事になるので、「対話型」として考えてます。

NOTE: PROCEDURE ●●処理(合計処理時間):
      処理時間           X.XX 秒
      CPU時間            X.XX 秒




注意


環境や設定によって挙動が異なります。
例えば、SAS Ondemand for Academicsについては、私の環境下では対話型モードがONになっていないので、

以下のプログラムを実行すると、、まずは、ちゃんと実行されます。

proc sql;
  select * from SASHELP.CLASS;


次に以下を実行すると、対話型モードになっていないため、ERRORになります。

  select * from SASHELP.CLASS where AGE = 13;
quit;

ログ
ERROR 180-322: ステートメントが有効でないか、適切な順序で使用されていません。


ただ、上の青文字と赤文字のプログラムをいっぺんに実行した場合、構文としてはおかしくないので、ちゃんと実行はできます。
(ちなみに、SAS Ondemand for Academicsの場合、対話型モードをONにすると、他の機能の挙動が変わってしまって面倒なので、あまりデフォルトの設定をいじらない方がよいかも。。)