自然科学のデータを表示するときに数値を有効数字で丸めて表示することがよくあります。しかしExcelはもちろんSASに有効数字を出力する関数はありません。(個人的には科学計算を実施するうえでよく使うものなのになんで関数を用意しないのか疑問ですが・・・)
よく使うのでFCMPプロシジャを使って数値を有効数字で出力する関数を自作しました。
有効数字とは
有効数字は、その値がどれだけ信用できるかを示すもので,桁数の多いものほど精度が高い測定値であることを意味します。測定値を報告書に載せるときは有効数字をそろえて値を表示することはよくあります。
例えば12.3という測定値は有効数字3桁であり、少数第二位の数値は不正確です。
それに対し12.30という測定値は有効数字4桁であり、少数第二位が確定しています。こちらのほうが前者より精度が高く、少数第二位の値も精度よく取得できていることになります。
詳細はwikipedia が詳しいです。
SASヘルプで紹介されているけど・・・
有効数字で出力する方法はSASの公式でも紹介されています。
この方法自体は問題ないのですが、数値型として出力されるのは微妙です。
末尾のゼロが反映されませんので、この数値をそのままレポートに載せられません。有効数字の話がでてくるのは必要な計算が終わって値を表示するときなので、これ以上計算をしない以上数値型で取り扱う必要がないはずです。
それに数値がゼロだとエラーで止まりますよね・・・もうちょっと実用的なコードを紹介してほしいのですが。
ないものは作るしかありません。ユーザー定義関数を定義できるFCMPプロシジャで有効数字を出力する関数を作成しました。
有効数字関数
proc fcmp outlib=work.func.user ;
function sig(num, digit)$20;
length fmt $20;
if num=0 then do;
fmt=cats("20.", put(digit-1,8.0), "-L");
rnd_txt=putn(0,fmt);
end;
else do;
ndigit=floorz(log10(abs(num)));
rnd=round(num, 10**(ndigit-digit+1));
if int(log10(rnd))>= digit then fmt="20.0-L";
else fmt=cats("20.",put(abs(ndigit-digit+1),8.0), "-L");
rnd_txt=putn(rnd,fmt);
end;
return (rnd_txt);
endsub;
quit;
試しに実行してみましょう。
option cmplib=work.func;
/* num=丸める前の数値 digit=有効桁 snum=丸めた後 */
data test;
length num digit 8 snum $20;
input num digit;
snum=sig(num,digit);
cards;
1234.5678 1
1234.5678 2
1234.5678 3
1234.5678 4
1234.5678 5
1234.5678 6
0.12345 3
0.24 4
-9.435 5
-123.4 2
-1.25 4
;
run;
num | digit | snum |
---|---|---|
1234.5678 | 1 | 1000 |
1234.5678 | 2 | 1200 |
1234.5678 | 3 | 1230 |
1234.5678 | 4 | 1235 |
1234.5678 | 5 | 1234.6 |
1234.5678 | 6 | 1234.57 |
0.12345 | 3 | 0.123 |
0.24 | 4 | 0.2400 |
-9.435 | 5 | -9.4350 |
-123.4 | 2 | -120 |
-1.25 | 4 | -1.250 |
しっかり末尾のゼロもついていますね。これ絶対便利でしょ。
単純に四捨五入する場合は以下の記事に紹介しています。