2016年3月29日火曜日

オブザベーション数を取得してマクロ変数に格納する方法 【まとめ】


ぱっと思いつく限りあげてみました。他に面白い方法があれば教えてほしいです。


*** サンプルデータ ;
data DT1;
  do i=1 to 100;
    output;
  end;
run;


① SQL INTO
proc sql noprint;
  select count(*) into :OBS1 trimmed
  from DT1;
quit;

%put &OBS1;


② NOBS
data _NULL_;
  if 0 then set DT1(drop=_ALL_)  nobs=NOBS;
  call symputx("OBS2", NOBS);
  stop;
run;

%put &OBS2;

参照…http://sas-boubi.blogspot.jp/2015/06/blog-post_26.html(過去記事)
※ 注意事項があるので過去記事参照


③ SQL DICTIONARY
proc sql noprint;
  select NLOBS into :OBS3
  from DICTIONARY.TABLES
  /* ライブラリ名とデータセット名を大文字で指定する */
  where LIBNAME="WORK" and MEMNAME="DT1";
quit;

%put &OBS3;

参照…http://sas-boubi.blogspot.jp/2015/08/dictionary.html(過去記事)


④ OPEN, ATTRN関数
data _NULL_;
  DSID = open("DT1");
  OBS  = attrn(DSID, "NLOBSF");
  call symputx("OBS4",OBS);
run;

%put &OBS4;

まず、OPEN関数でデータセットを開く(戻り値としてデータセット識別子というIDが返される)
次に、ATTRN( データセット識別子, "NLOBSF" ) でオブザベーション数を取得しています。


⑤ HASH
data _NULL_;
  if 0 then set DT1;
  dcl hash hs(dataset :"DT1", multidata:"y");
  hs.definekey("i");
  hs.definedone();
  call symputx("OBS5", hs.num_items);
  stop;
run;

%put &OBS5;

参照…http://sas-tumesas.blogspot.jp/2014/07/clearnumitemsdeleteremove.html(データステップ100万回)

ポイント
multidata:"y" で重複キーも保持するようにしています(ハッシュオブジェクトはデフォルトだと、キーが重複するレコードに対して、最初のレコードしか保持しないので)


⑥ SYSNOBS
参照…http://sas-boubi.blogspot.jp/2014/01/blog-post_8902.html(過去記事)


⑦ SQLOBS
参照…http://sas-boubi.blogspot.jp/2014/09/blog-post_8.html(過去記事)

2 件のコメント:

  1. どうもです。
    たいしたことじゃないんですが

    SQLでの書き方について、たまたま外人が以下のように
    書いているのを見つけて、count(*)と比較してみると処理時間が
    ずいぶん短いようでした。
    こっちの方が効率いいのかもです。

    proc sql noprint;
    select max(monotonic()) into :OBS1
    from DT1;
    quit;

    適当な条件でテストしたんで、常にかどうかはわからないですが

    返信削除
  2. ありがとうございます。なるほど、これは面白い書き方ですね!

    さっそく私の方でもsashelp.heartを2000万obsくらいに増やしてテストしてみたんですが、count(*)が1秒、max(monotonic())が4秒という結果になっちゃいました。
    なんか変数の数とかlengthとかによって影響するんですかね?

    返信削除