我輩はブロガーではない。ネタもまだない

SASとかDelphiあたりの人様の役に立たないネタを提供します

0オブザベーションのデータセット

仕事柄か、0オブザベーションのデータセットを作成することがよくあります。
今まではdataステップでdeleteステートメントを利用していたのですが、
Base Certificateのトレーニングテキストを読んで、obsデータセットオプションに
切り替えた方が早そうだ、けど、他に方法があるかも、と調べたのでまとめてみました。



調べれば手法自体はたくさん出てくるのですが、処理時間とログの観点からみていきます。
www.sas.com
sas-boubi.blogspot.com

私が思いついた&使っていたのは「obsデータセットオプション」と上記にはない「deleteステートメント」を利用する方法で、それ以外は皆さんよく思いつくなぁ、といったところ。

用意したのはSAS忘備録でまとめられている6パターンに自分が使っていたdeleteステートメントを加えた以下の7パターン。

・パターン1

data test1;
  set sashelp.bweight;
  stop;
run;

・パターン2

data test2;
  set sashelp.bweight(obs=0);
run;

・パターン3

data test3;
  if 0 then set sashelp.bweight;
run;

・パターン4

data test4;
  set sashelp.bweight;
  set _null_;
run;

・パターン5

data test5;
  set sashelp.bweight;
  where 0;
run;

・パターン6

proc sql;
  create table test6 like sashelp.bweight;
quit;

・パターン7

data test7;
  set sashelp.bweight;
  delete;
run;

実行ログは以下の通りです。
f:id:japelin:20200130193527p:plain

パターン3の「if 0 then」を使用すると。「ループが発生したため」なんて出てくるのであんまり使いたくないです。
また、パターン5の「where 0」では「明らかにFALSEなWHERE句です。」というログが出力されており、これは通常のログでもチェックしているケースがあると思いますのでこれも避けたい。

その他はエラーっぽくないので、どれでもよさげ。
よく見てみると、パターン1,4では1オブザベーションを読み込んでおり、パターン2では0オブザベーション
を読み込んでいますが、実行時間に差はあるのでしょうか。


それぞれ1000回実行した結果は以下のようになりました。
f:id:japelin:20200130193913p:plain


読み込むのが0オブザベーションか1オブザベーションかは差としては検出できませんでした。
パターン1~5の違いは誤差レベルと言っていいでしょう。変数が数千とか数万とかだと変わってくるかもしれませんが。

結論として、ログと処理時間から1, 2, 4あたりを利用するのがよさそうです。

私は既存のコードが

data hoge;
  set hage;
  delete;
run;

としているので、deleteをstopに書き換えようと思います。ソースコード管理的にわかりやすいですし。