公告

[公告]
2014/01/17
由於已經是faculty的關係,不太有足夠時間寫部落格。因此更新的速度會相當緩慢。再加上近幾年來SAS GLOBAL FORUM沒有出現讓我覺得驚艷的技術文件,所以能分享的文章相對也減少許多。若有人推薦值得分享的SAS技術文件,請利用『問題討論區』告知。

2013/07/19
臉書留言板的功能因為有不明原因故障,因此特此移除。而intensedebate的留言板因管理不易,也一併移除。目前已經開啟內建的 G+ 留言系統,所以請有需要留言的朋友,可直接至『問題討論區』裡面留言。


2010年8月2日 星期一

Automatically Run Fisher's Exact Test When the Chi-square Test Might Not Be Valid

Link: http://support.sas.com/resources/papers/proceedings10/096-2010.pdf

在使用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
CODE { display: block; /* fixes a strange ie margin bug */ font-family: Courier New; font-size: 8pt; overflow:auto; background: #f0f0f0 url(http://klcintw.images.googlepages.com/Code_BG.gif) left top repeat-y; border: 1px solid #ccc; padding: 10px 10px 10px 21px; max-height:200px; height:200px; // for IE6 line-height: 1.2em; }