熱線電話:13121318867

登錄
首頁精彩閱讀SAS應用:都是小數點惹的禍
SAS應用:都是小數點惹的禍
2015-12-21
收藏

SAS應用:都是小數點惹的禍

今天有人用了兩種方法通過分組求平均數問題,發現結果不一樣。為了說明問題,我自己簡單地造了些數據,如下:

data dup;
input  id  date  field  value ;
cards;
1  2  0.0001  10
1  2  0.0001  10
1  2  0.00001  10
1  2  0.00001000001  10
1  3  0.00001  10
1  3  0.00001  10
1  3  0.00003  10
1  3  0.00003  10
1  3  0.00003  10
;
run;
proc sql;

create table NoDup1 as
select unique id, date, field, avg(value) as value from Dup group by id, date, field;
quit;   ;
*method 2;
proc means data = Dup nway ;
class  id date field;
var value;
output out = NoDup2(drop = _type_ _freq_) mean = value;
run;
初一看來,好像代碼沒什么問題,應該結果一致,然而結果運行后,用sql得到的結果與proc步不一樣,這是為什么? 似乎這是SAS的錯誤,哈哈這個多么偉大的一個發現啊!  SAS可以說是總多行業里面的標準,竟然也會錯。   其實這不是第一次發現這類問題。 以前也遇到過同樣的一個問題,就是:

data ex;
do i= 0.05 to 0.15 by 0.01;
if i=0.1 then output;
end;
run;

這個代碼運行后,ex數據集是空的,是不是SAS出錯了。后來發現這是由于計算機存儲小數的浮點問題,循環5次后,i應該等于0.1,實際上非常接近0.1,是個近似值,并不是等于0.1,因此并無數據輸出到ex里面。

那么回到上面的那個問題,根本原因是proc sql和proc mean步對數的小數點處理不同,proc mean考慮到小數點多于sql, 因此會導致nodup1比nodup2少一條觀察。下面我提供第三種解決此類問題的代碼,data步,也是商業大型數據的常用方法:

data nodup3;
set dup;
by id date field;
if  first.field then  do; num=0;mean=0;end;
num+1; mean+value;
if last.field then do;  value=mean/num; drop num mean; output; end;
run;

這個也是和proc mean步結果是一樣的。

有時候也許不需要考慮沒必要的小數位,可以用函數round,int,ceil等,還有一種方法就是把需要分組和比較大小的非整數用format格式化一下。

一般來說,我如果發現SAS運行結果和我想的不一樣,可以歸結于兩點:1,自己的代碼有問題;2,小數點問題。

數據分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數據分析師資訊
更多

OK
客服在線
立即咨詢
日韩人妻系列无码专区视频,先锋高清无码,无码免费视欧非,国精产品一区一区三区无码
客服在線
立即咨詢