
去年年底,俺好友「Dr. 史考特。哈蘇」(見上圖) 從密爾瓦基打電話給我,問我有沒有「狗屎」...啊不對,是「Gauss」啦~
我跟他講這套軟體基本上從俺離開清大統研所後就再也沒有見到有人在用了。
如何在SAS中進行Bera-Jarque-Lee test in probit model

去年年底,俺好友「Dr. 史考特。哈蘇」(見上圖) 從密爾瓦基打電話給我,問我有沒有「狗屎」...啊不對,是「Gauss」啦~
我跟他講這套軟體基本上從俺離開清大統研所後就再也沒有見到有人在用了。
如何計算Mixed model with repeated measurement的樣本數
餓死抬頭,這些年來很多人一直找我做過許多power analysis來求power或樣本數,而SAS內建的PROC POWER和PROC GLMPOWER這兩個程序已經能夠把最基本的各種假設檢定、ANOVA和GLM下的power analysis給搞定,順便還可以畫出相當精美的圖形。
[密技] 如何在 Ubuntu 上安裝 R
[密技] 如何在 Vista 安裝SAS(二)
將近一年前分享了這篇文章:
[密技] 如何在 Vista 安裝SAS
成為本部落格最熱門的文章。這必須要"洩洩" Vista 的高度不相容性以及 SAS 公司遲遲沒有釋出更新檔。不過這一年來,還是陸續看到一些朋友們按照文內的步驟安裝但仍舊安裝失敗的情況。於是我又回原來發佈這個方法的部落格瀏覽一下,發現有人在回文內分享了另種解決方案。
SAS ODS 無法顯示繪圖的解決方案
昨天在幫一個博士班學生處理 mixed model 的 model diagnostics 問題時,使用 PROC MIXED 程序並配合 ODS GRAPHICS 來產生圖形時,發現 log 裡面出現這一行錯誤訊息:
Java class generated an exception
由於兩年前我在考資格考時還有用過這道指令,記得當時可以順利生出 model diagnostics 的圖形,不過這兩年一直都沒再使用這個功能,所以完全搞不清楚這個錯誤訊息是怎麼跑出來的,因此只好去 SAS 官網上面找看看。果真看到 SAS support 網頁下有說明這個錯誤訊息的源由:
[密技] 如何在 Vista 安裝SAS
How to count frequencies in different combinations of symptoms
之前在幫長庚護理系的葉昭幸教授作一些資料分析時,曾經寫了一個 macro 以便於將 PROC FREQ 的結果拿來製造 82 個資料集。因此這個 macro 就跑了 82 次。今天我把這個程式拿來看一看,覺得有點 stupid。心想如果有更方便的方法來讓 macro 可以自動重複的把 PROC procedure 跑完的話,那就更完美了。
因此,上網路稍微搜尋一下,馬上找到答案。原始的 stupid 程式如下:
%macro variable(var,outdata);
proc freq data=symptom.msas noprint;
tables &var /out=&outdata;
run;
data &outdata;
set &outdata;
drop &var percent;
rename count=&var;
run;
%mend;
/*Distress*/
%variable(distress1, symptom.distress1);
...
...
...(省略)
%variable(distress30, symptom.distress30);
/*Severity*/
%variable(severity1, symptom.severity1);
...
...
...(省略)
%variable(severity30, symptom.severity30);
/*Freq*/
%variable(freq1, symptom.freq1);
...
...
...(省略)
%variable(freq22, symptom.freq22);
後來改成這樣:
%macro variable(var,num);
%do i = 1 %to #
proc freq data=symptom.msas noprint;
tables &var&i /out=&var&i;
run;
data &var&i;
set &var&i;
drop &var&i percent;
rename count=&var&i;
run;
%end;
%mend;
%variable(distress,30);
%variable(severity,30);
%variable(freq,22);
主要修改的地方有兩個:
一、把原本要存入symptom這個library的檔案全部改存到work裡面去,這樣這些暫存的檔案在經過下一步驟的合併之後並離開SAS後就會消失,不會佔用硬碟空間。
二、在 PROC FREQ 和 data step 外面加上一個 do loop,然後把要執行的圈數設成一個新的 macro 參數叫做 num,這樣就能拿來控制要重複執行的次數。
我在二月八日發表了一篇關於如何大量重新命名新變數的文章(How to concatenate two variables with array)。當時寫完覺得自己很屌,但今天看到一篇文章後頓時覺得自己很遜。原先的設計是要將上千個變數切成兩半,前半段包含舊變數的第一個字母,並且重新命名為「舊變數a」,後半段包含舊變數的最後一個字母,並且重新命名為「舊變數b」。
原始的程式主要是將變數名稱另存一個新檔,針對那個檔來做重新命名的工作,然後再把新變數名稱存出來貼到另一個程式去做切割舊變數的動作。但有個神人寫了一個可以自動重新命名的 macro,讓上述動作在數行程式碼之間迅速完成!!
這篇文章可至 SUGI 的官方網站下載,但我已經大部分的文件弄成一個簡單的中文說明放在我的 SUGI CLUB 裡面。有興趣的人可以去看一看。
舊的程式碼我就不列了,可以到之前的文章看。新的程式碼如下:
%include <把add_string macro的路徑放入>;
%let old_vars=<裡面把所有舊變數名稱全部放入>;
%let N=<放入變數總數>;
data newset;
set oldset;
array old[*] &old_vars;
array recode1[*] %add_string(&old_vars, a);
array recode2[*] %add_string(&old_vars, b);
do i = 1 to &N;
recode1[i]=substr(old[i],1,1);
recode2[i]=substr(old[i],3,1);
end;
run;
裡面的 %add_string 就可以將所有 old_vars 裡面的舊變數後面多加一個 a 或 b。然後這新的變數放進兩個不同的陣列,再用 substr 指令去割舊變數就完成了。
我偶爾會去逛一個叫做「統計生活館」的網站。這個大概是我覺得國內最完整的一個在介紹統計學的網站。裡面有一個討論區,經常有人會上去問些問題。如果我知道答案,也會在那邊幫點小忙。
前幾日有位仁兄問了一個問題。他用亂數生成的方法模擬了一個資料庫包含1068筆資料,然後用 SAS 的 PROC CLUSTER 做 Cluster analysis,最後再把樹狀圖畫出來。這個流程其實是很簡單的,但是他要重複上述的動作 10000 次。他問程式該怎樣寫。
我本來想說用個 Macro 來搞定,但是卡在怎樣在亂數模擬變數那一階段請 SAS 生出 10000 個資料庫,因為 Do loop 不能掛在 Data procedure 的外面。後來想到一個簡單的方法,不用 Macro 就可以搞定。
原始程式如下:
data simulation;
do no=0001 to 1068;
array Q[*] Q01-Q25;
do j=1 to 25;
k=rand('uniform');
Q(j)=ranbin(1,1,k );
end;
output ;
end;
proc distance data=simulation method=djaccard absent=0 out=distjacc;
var anominal(Q01-Q25);
run;
proc cluster data=distjacc method=ward rsq rmsstd pseudo outtree=tree;
var _numeric_;
run;
proc tree data=tree out=out;
run;
data simulation;
do index=1 to 10000;
do no=0001 to 1068;
array Q[*] Q01-Q25;
do j=1 to 25;
k=rand('uniform');
Q(j)=ranbin(1,1,k );
end;
output ;
end;
end;
run;
proc distance data=simulation method=djaccard absent=0 out=distjacc;
by index;
var anominal(Q01-Q25);
run;
proc cluster data=distjacc method=ward rsq rmsstd pseudo outtree=tree;
by index;
var Dist1-Dist1068;
run;
proc tree data=tree;
by index;
run;