數據分析少不了和數據中的異常值打交道,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/IML程序,可以參考附件資料。