2014年3月9日日曜日

分析の本番環境

意外とアクセス数があったので、記事を加筆、修正します。

分析とかリスク計算に携わるお客様からよく相談されるのがテスト環境、本番環境のことです。システム部門からすると、本番環境だけしかないのは信じがたく、分析者から見るとなんで本番環境を構えるかわからないことがままあります。


そのギャップを理解しないまま、システム統制に従うと色々苦労が絶えません。設計書ありません、テストケースありませんというのは、アドホックな分析を生業としている人には普通のことです。未知なる数値、ロジックを追い求めるときに設計書作ってレビューなんてしません。

大概、システム統制をかけようとしてユーザから情報システム部へ引き渡すときに問題が生じます。プログラムやデータ資産の範囲が不明確、計算のパラメータはテストすることなく都度修正、計算結果は回してみないと業務で使えるかどうかわからない、テストケースが無い等々、情報システム部にとっては腹の立つことばかりです。


システムとして統制効かせたり、定型化して業務とリンクさせるときには、環境を分けて実装しなおすのが良いです。この設計を起こして、実装をやり直すというのが、あまり理解されていないと感じます。分析環境で書かれたドキュメントのないコードを、そのまま本番環境に放り込んでというのは、最初の1年ぐらいは持つかもしれません。

数年たって立ち往生しそうなシステムの手当てを、SAS Log Utilityを使って何回か引受けています。

2014年3月1日土曜日

マクロ %varlist

変数の値をカンマでつないだリストを作りマクロ変数にセットします。よく使う割りに忘れます。変数が数値でも文字型でも動くように修正しました。

/*
*++
* データセット(dsn)の変数(keep)をリストにして、マクロ変数(macvar)にセット
*--
*/
%macro varlist(dsn=, keep=, macvar=);
 %global &macvar;
 %local i dsid n type rc;
 %let i=;
 %let dsid=%sysfunc(open(&dsn,i));
 %let n=%sysfunc(varnum(&dsid,&keep));
 %let type=%sysfunc(vartype(&dsid,&n));
 %let rc=%sysfunc(close(&dsid));
 %let &macvar=;

 %if &type=C %then
  %do;
   /* 変数が文字型 */
   data _null_;
    set &dsn(keep=&keep) end=eod;
    length list $1024;
    retain list;

    if _n_ eq 1 then
     do;
      list = '"' || compress(&keep) || '"';
     end;
    else
     do;
      list = trim(list) || ',"' || compress(&keep) || '"';
     end;

    if eod eq 1 then
     do;
      call symput("&macvar", compress(list));
     end;
   run;

  %end;
 %else
  %do;
   /* 変数が数値型 */
   data _null_;
    set &dsn(keep=&keep) end=eod;
    length list $1024;
    retain list;

    if _n_ eq 1 then
     do;
      list = put(&keep, best.);
     end;
    else
     do;
      list = trim(list) || ',' || put(&keep, best.);
     end;

    if eod eq 1 then
     do;
      call symput("&macvar", compress(list));
     end;
   run;

  %end;
%mend;

%varlist(dsn=sashelp.class, keep=name, macvar=test);
%put test=&test;


マクロ %nobs

データステップを使わないで、OBS数を得るマクロです。よく使う割りに忘れます。

/*
*++
* データセットのOBS数を返す
*--
*/

%macro nobs(ds);
 %local dsid rc;
 %let dsid=%sysfunc(open(&ds));
 %if &dsid %then %do;
  %sysfunc(attrn(&dsid,NOBS));
  %let rc=%sysfunc(close(&dsid));
 %end;
 %else %do;
  -1
 %end;
%mend nobs;

%put nobs=%nobs(sashelp.class);