在使用PROC FREQ執行卡方檢定時,如果看到列聯表下面出現warning的訊息,就表示這個列聯表有50%以上的期望值小於五,因此程式會建議使用Fisher's exact test。然後使用者必須回到程式裡面,在tables statement後面加上一個exact的選項,再重跑一次PROC FREQ才能得到Fisher's exact test的結果。Wei Xu於SAS GLOBAL FORUM 2010發表了一個macro程式,讓電腦自動幫使用者判斷要不要進行Fisher's exact test,若需要的話會順便把Fisher's exact test的結果跑出來,使用者不需再去重新執行PROC FREQ一次。
這個macro名叫%RUN_FISHERS,裡面只有四個參數須要設定:
- Data= 要進行卡方檢定的資料名稱
- Row= 放在行的變數名稱
- Col= 放在列的變數名稱
- Count= 如果資料是已經整理好的列聯資料,則會多一個計數變數來表示某一欄位的個數,此時需要把這個變數定義在這個參數裡面。如果不是列聯資料的話,可在此留空白。
data test;
input r c ct;
datalines;
1 1 12
1 2 5
1 3 6
2 1 13
2 2 2
2 3 4
;
run;
%run_fishers(data=test, row=r, col=c, count=ct);
由於此資料會出現warning訊息,所以Fisher's exact test的結果就會直接顯示在報表最下方。如果今天資料變成:data test;
input r c ct;
datalines;
1 1 12
1 2 50
1 3 60
2 1 13
2 2 20
2 3 40
;
run;
%run_fishers(data=test, row=r, col=c, count=ct);
報表最下方就不會出現Fisher's exact test的結果。最後是這個macro的原始碼:
%macro run_fishers (version, data=, row=, col=, count=);
%let _version=1.0;
%if &version ne %then %put RUN_FISHERS macro Version &_version;
%let opts = %sysfunc(getoption(notes))
_last_=%sysfunc(getoption(_last_));
%if &version ne debug %then %str(options nonotes;);
/* Check for newer version */
%if %sysevalf(&sysver >= 8.2) %then %do;
%let _notfound=0;
filename ver url 'http://ftp.sas.com/techsup/download/stat/versions.dat' termstr=crlf;
data _null_;
infile ver end=_eof;
input name:$15. ver;
if upcase(name)="&sysmacroname" then do;
call symput("_newver",ver); stop;
end;
if _eof then call symput("_notfound",1);
run;
%if &syserr ne 0 or &_notfound=1 %then
%put &sysmacroname: Unable to check for newer version;
%else %if %sysevalf(&_newver > &_version) %then %do;
%put &sysmacroname: A newer version of the &sysmacroname macro is available.;
%put %str( ) You can get the newer version at this location:;
%put %str( ) http://support.sas.com/ctx/samples/index.jsp;
%end;
%end;
proc freq data=&data noprint;
%if &count ne %then %str(weight &count / zeros;);
tables &row*&col / sparse outexpect out=_out1;
run;
proc means data=_out1 noprint;
var count;
output out=_out2;
run;
data _null_;
set _out1;
if expected<=5 then warn+1;
if _n_=1 then set _out2;
pct_lt5=warn/_freq_;
if _freq_=_n_;
warning=(pct_lt5>=.2);
call symput('warning',warning);
run;
options &opts;
proc freq data=_out1;
weight count / zeros;
tables &row*&col / chisq;
%if &warning=1 %then %do;
exact fisher;
%end;
run;
%mend;
CONTACT INFORMATION
Wei Xu
Boston Scientific
100 Boston Scientific Way
Marlborough, MA 01752-1234
(508) 683-4264
wei.xu@bsci.com
沒有留言:
張貼留言
要問問題的人請在文章下方的intensedebate欄位留言,請勿使用blogger預設的意見表單。今後用blogger意見表單留言的人我就不回應了。