2018年8月30日木曜日

【効率を意識したプログラム】KEEPやDROPの利用




DROPとKEEPを活用しようっていう話です。



Sample data
data test;
   length col1-col200 $200.;
   array ar(*) col:;
   do i=1 to dim(ar);
       ar(i) = "abcdefg";
   end;
   do i=1 to 50000;
      output;
   end;
run;


上記、変数を沢山持つ50000obsのデータセットを作りました。



このデータセットを以下のようにSETした時の処理時間とCPU時間を見てみます。

data out1;
   set test;
run;

ログ
       処理時間           1.95 秒
       ユーザーCPU時間    0.32 秒
       システムCPU時間    1.64 秒



ここで例えば変数col1~col10だけが必要な変数だったとしたら、、

data out1;
   set test (keep=col1-col10);
run;

ログ
       処理時間           0.85 秒
       ユーザーCPU時間    0.03 秒
       システムCPU時間    0.83 秒


SETする時にKEEPやDROPで読み込む変数を絞っておくと、処理時間などが少し短くなります。





また、データステップ中に作成した一時変数や、使わなくなった変数は出力データセットから除いておくと、、

data out1;
   set test ;
   drop col1-col10;
run;


または

data out1 (drop=col1-col10);
   set test ;
run;

サイズが軽量化されて、その後このデータセットを読み込む時の処理時間なども短くなる事が期待できますよね。




このように効率を意識しながら、KEEP・DROPを指定する場所を使い分ける事がポイントです。

まぁ軽いデータだったり、実行に時間がかからないプログラムだったら、ここまで意識してKEEP・DROPを使わなくてもいいと思います。(多用しまくるとプログラムがごちゃっとした見た目になりがちだし)



【DROP・KEEPステートメント】データセットから特定の変数を削除または残す



2018年8月27日月曜日

【効率を意識したプログラム】FULLSTIMERオプション





プログラムをちょっと工夫して、実行時間を少しでも短縮しようっていうシリーズ記事です。



まずは「FULLSTIMERシステムオプション」について。

このオプションを指定すると、データステップやプロシジャを実行した時の処理時間やメモリなどの詳細なパフォーマンスがログに表示されるようになります。




以下は「SAS OnDemand for Academics」での実行結果です。

 options fullstimer;

 proc means data=sashelp.class;
    var height;
 run;


ログ
 NOTE: データセットSASHELP.CLASSから19オブザベーションを読み込みました。
 NOTE: PROCEDURE MEANS処理(合計処理時間):
       処理時間           0.02 秒
       ユーザーCPU時間    0.02 秒
       システムCPU時間    0.00 秒
       メモリ             8707.03k
       OSメモリ           36040.00k
       タイムスタンプ     2018/08/27 午後12:25:17
       ステップ数                        26  スイッチ数  0
       ページフォルト回数                0
       ページリクレーム回数              1973
       ページスワップ回数                0
       自発的コンテキストスイッチ回数    14
       非自発的コンテキストスイッチ回数  0
       ブロック入力操作回数              0
       ブロック出力操作回数              8


うるさいくらい表示されますね。(ていうかSAS OnDemandだとFULLSTIMERがデフォルト設定になってます)
ただ、Windows環境で実行すると表示されるのは8つくらいなので、そんなに多くはないです。



「NOFULLSTIMER」でオフにできます。

 options nofullstimer;




プログラムの書き方によってどのくらいパフォーマンスが変わるんだろうって調べる事があるんで、結構使うオプションです。


2018年8月17日金曜日

「%IF-%THEN / %ELSE」がマクロの外でも使えるようになってる!



「The SAS Dummy」さんの書かれた記事みて、テンション上がりました。
https://blogs.sas.com/content/sasdummy/2018/07/05/if-then-else-sas-programs/



「SAS9.4メンテナンスリリース5」から%IFがマクロの外でも使えるようになってます!

 %let x=1;

 %if &x=1 %then %do;
       %put NOTE: マクロ変数xの値は1です;
 %end;

ログ
 NOTE: マクロ変数xの値は1です

動いたーー!!


今まで%IFはマクロ内でしか使えなくて「%MACRO」と「%MEND」で囲ってましたが、プログラムがちょっと長くなって、いつもテンション下がってたんですよね。




制限事項

現状の「メンテナンスリリース5」では、マクロ外の%IFに2つ制限があるみたいです。


① %THENと%ELSEの後は、「%DO」と「%END」で囲まないとダメ。

例)
%if 条件 %then
   %do;
          実行したい文
   %end;
%else
   %do;
          実行したい文
   %end;



② %IF文はネストして書くことはできない。

例)NGの書き方
%if 条件 %then %do;
     %if 条件 %then %do;
              実行したい文
     %end;
%end;




この制限も次期バージョンとかで改善されてるといいですね。
あとは、%DOもマクロ外で使えるようにしてほしいなぁ


2018年8月15日水曜日

【サブセット化IF】条件に一致するオブザベーションのみ処理を継続する。





今回は頻繁に使われる「サブセット化IF」というステートメントについて解説。



構文

IF  条件式  ;

  • データステップ内で使用します。
  • 条件式が成立しない場合、そのオブザベーションに対する残りのプログラムを中止します(そのオブザベーションはデータセットに出力されません)そして即座に次の反復(次のオブザベーションの読み込み)に移行します。
  • 条件式が成立する場合、そのオブザベーションに対する残りのプログラムが実行されます。





* Sample data ;
data dt1;
input a b;
cards;
1 5
2 6
3 7
4 8
;

例①
data out1;
  set dt1;
  if a = 2;
  c = a + b;
run;




やってる事
  • a = 2 のオブザベーションであれば、以降の処理(変数cを導出)して、out1に出力
  • それ以外はそのオブザベーションに対する処理を中止して、out1に出力しない



例②
data out2;
  set dt1;
  c = a + b;
  if c >= 10;
run;


やってる事
    • データステップ内で変数cを導出
    • c >= 10 のオブザベーションをout2に出力
    • それ以外はそのオブザベーションに対する処理を中止して、out2に出力しない


    データステップ内で導出した変数をサブセット化IFに使用できるのがポイント





    その他サブセット化IFの記事





    2018年8月13日月曜日

    SASユーザー総会2018に行ってきました。




    東京大学伊藤国際学術研究センターで開催されたSASユーザー総会2018に行ってきました。



    台風直撃するかもっていう予報が出てたんで諦めてましたが、なんとか逸れてくれました。



    今年は「SAS Programming Tips: CDISC編」というタイトルでポスター発表してきました。
    ポスターツアーで2~3分ほど概要発表しましたが、見に来ていただいた方、本当に有難う御座いました!
    また挨拶させて頂いた方も有難う御座いました。楽しい2日間でした!




    それと、毎年恒例のアンケート答えてもらえるSASグッズを楽しみにしていたんですが、、
    今年は「SAS」と書かれた扇子がもらえたようなんですが、私が行ったときは品切れだったらしく、、

    代わりに20枚くらい入ったびみょーーーな付箋が貰えました。ここ最近で一番のショックかもしれません。。ショックすぎて逆さまに写真撮っちゃってますね。




    まぁ、いいや、来年はもっと早く貰いに行こう。。。

    それはそうと、来年は皆さんも何か発表してみませんか?
    わたしの一発ギャグみたいな内容の発表でもいいので。むしろ一発ギャグみたいな発表がたくさんみたいです。

    もっともっとSASを盛り上げていきましょう。

    2018年8月1日水曜日

    【DLGCDIR関数】SASのカレントディレクトリを変更する




    DLGCDIR関数で、SASのカレントディレクトリを変更する事が出来ます。

    ちなみに、
    ・SAS9.4メンテナンスリリース5からの機能です
    ・WindowsとUNIX環境で動作します



    まず以下のように引数を指定しないで実行すると、ログにカレントディレクトリのパスが表示されます。

      data _null_;
          rc = dlgcdir();
      run;

      ログ
      NOTE: 現在の作業ディレクトリは"ここにパスが表示される"です。





    パスを指定すると、そこがカレントディレクトリになります。

      data _null_;
          rc = dlgcdir( "パスを指定" );
      run;

      ログ
      NOTE: 現在の作業ディレクトリは"ここに変更後のパスが表示される"です。




    これちょっと便利ですね!