divide関数で0除算によるログが汚れるのを防ぐ

ゼロ除算、つまり、値を0で割り算するのは少なくともプログラムの世界では有名なタブーです。
数学的な議論、説明付けはゼロ除算で検索していただくとして、

まあ他の言語はさておき、SASは0で割ったとして、いきなり強制終了したり。無限ループに陥ったりはしないので、普段そこまで強く意識しないことが多いのではないでしょうか?

以下のデータセットがあるとします

data Q1;
X=2;Y=1;output;
X=1;Y=0;output;
X=0;Y=0;output;
X=-1;Y=0;output;
run;








これに対して

data E1;
 set Q1;
  Z=X/Y;
run;

とするとログは












とまあ、うるさい感じになってしまいます。
結果は省略しますが、2obs以降のZは全て欠損値です。


data A0;
 set Q1;
 if Y^=0 then Z=X/Y;
run;

とすれば、回避ですが、その他にdivide関数をというやつを使えます。

data A1;
 set Q1;
 Z=divide(X,Y);
run;












となってログは綺麗です。

で肝心の中身をみると








え、I ? M ? なにそれ??

SASのdivide関数のヘルプみていただければいいんですが
これはspecial missing values、特殊欠損値で
Iは無限大インフィニティのI、Mはマイナス無限大を示します。
こうみえて数値型です。

正の値を0でわると無限大、負の値だとマイナス無限大になってるよということを
教えてくれます。

data A1_;
 set A1;
 where Z=.I;
run;

たとえば、このようにすれば、0除算が発生し、なおかつ正の値/0のみを選択的に抽出できます。
どういった時にそういった状況になるかはしりません。

data A1;
 set Q1;
  Z=coalesce(divide(X,Y),.);
run;

欠損値に値を充てるcoalesce関数に欠損値を指定するという珍妙なコードをかけば
みなれたいつもの「.」欠損値に戻せます。










0 件のコメント:

コメントを投稿