數據分析少不了和數據中的異常值打交道,Winsorize處理在SAS中經常使用。
Winsorize即極值處理,原理是將數據中的異常值修建,使之與正常分布的最大值與最小值相同。例如,你的數據整體位于[70,90]這個區間,而分析的數據中有些值特別大或者特別小,比如出現了60、65、95與125這種數值,這時Winsorize處理就能夠將這些特別大或者特別小的值進行調整,讓這些異常值變成你自己定義的一個合理范圍中。對于上限,如果定義比90高出10%記為異常值,那么95這個值就會被SAS處理,放在Winsorize處理后的數據集里,而125將被看做異常值,不會放入Winsorize處理后的數據集里;同理,對于下限也是如此。
數據中含有缺失值和重復值時,進行Winsorize處理稍微會復雜一些。可以先對數據排序,但是缺失值首先會對計算造成不小的影響,所以Winsorize處理很方便解決這些常見難題。
SAS?Winsorize?處理過程:
%let?DSName?=sashelp.heart;
proc?iml;
/*?SAS/IML?moduleto?Winsorize?each?column?of?a?matrix.
Input?proportion?of?observations?toWinsorize:?prop?<?0.5.
Ex:?y=?Winsorize(x,?0.1)?computes?the?two-side?10%?Winsorized?data?*/
start?Winsorize(x,prop);
p?=?ncol(x);?/*?number?of?columns?*/
w?=?x;?/*?copy?of?x?*/
do?i?=?1?to?p;
z?=?x[,i];?/*?copy?i_th?column?*/
n?=?countn(z);?/*?count?nonmissing?values?*/
k?=?ceil(prop*n);?/*?number?of?obs?to?trim?from?each?tail?*/
r?=?rank(z);?/*?rank?values?in?i_th?column?*/
/*?find?target?values?and?obs?with?smaller/largervalues?*/
lowIdx?=?loc(r<=k?&?r^=.);
lowVal?=?z[loc(r=k+1)];
highIdx?=?loc(r>=n-k+1);
highVal?=?z[loc(r=n-k)];
/*?Winsorize?(replace)?k?smallest?and?klargest?values?*/
w[lowIdx,i]?=?lowVal;
w[highIdx,i]?=?highVal;
end;
return(w);
finish;
/*?test?thealgorithm?on?numerical?vars?in?a?data?set?*/
use?&DSName;
read?all?var?_NUM_into?X[colname=varNames];
close;
winX?=?Winsorize(X,0.1);
代碼中,矩陣winX包含經過Winsorize處理過的數據,如果你想輸出SASWinsorize處理后的數據,數據集屬于小數據集,可以使用代碼:%letDSName?=?sashelp.class;?進行實現。
大批量數據處理之前,想驗證SAS?Winsorize過程是否正確,可以借助SAS/IML計算出來的縮尾均值(?Winsorized?means),與SAS?PROC?UNIVARIATE?計算出來的縮尾均值進行比較。
/*?Compute?Winsorized?mean,?which?is?mean?of?the?Winsorized?data?*/
winMean?=?mean(winX);
print?winMean[c=varNames?f=8.4];
/*?Validation:?compute?Winsorized?means?byusing?UNIVARIATE?*/
ods?exclude?all;
proc?univariate?data=&dsname?winsorized=0.1;
ods?output?WinsorizedMeans=winMeans;
run;
ods?exclude?none;
proc?print?data=winMeans;
var?VarName?Mean;
run;
——SAS中文論壇
]]>