這是 William C. Murphy 於2005年的 SUGI 30 發表的一篇關於如何在 SAS 底下進行資料切割和合併的文章。由於 SAS 讀取資料是一欄一欄(column)地讀取,所以的操作也是以欄位為優先,因此當要切割或合併對象是行位(row)時,有時在沒有特定條件下來設定的話就很難用直覺的方式去處理。Howard M. Proskin 提出了幾個方法讓這類的資料處理更方便。
一般來說 SAS 是用這種方式讀取已經存在的資料:
data Out;
set Source;
run;
如果想要從某一個觀測值開始讀取的話,可用「firstobs=n」:
data Out;
set Source (firstobs=3);
run;
上述程式表示從資料 Source 的 第三筆開始讀取。
當然,想要叫他讀到某個觀測值停止的話,就用「obs=n」來界定停止點:
data Out;
set Source(firstobs=3 obs=10);
run;
THE POINT= OPTION
如果只想讀「一筆」資料,可以將 firstobs 和 obs 的參數設定成同樣的數值,不過有另外一個比較彈性的寫法,那就是使用「point」語法:
data Out;
Slice=17;
set Source point=Slice;
output;
stop;
run;
這個程式先設定一個暫時的變數叫做「Slice」,並且給定一個數值「17」給他,然後再把 Slice 給定到 point 語法。output 和 stop 這兩個語法一定要加上,因為 output 可以輸出最後的結果,而 stop 是強制結束這個程式繼續去讀下面的資料。
如果想一次讀進不連續的多筆資料,可以配合 do loop 來讀取:
data Out;
do Slice=17, 1, 23, 17, 5, 6;
set Source point=Slice;
output;
end;
stop;
run;
SAMPLING DATA SETS
想要隨機從一個很大的資料裡面抽出一些樣本的話,可以用下面這個程式:
data Sample;
do i=1 to 1000;
Slice=int(nObs*ranuni(123456789));
set BigDataSet point=Slice nobs=nObs;
output;
end;
stop;
run;
ranuni 語法可以從後面的 seed(123456789)中以均勻分配的方式生出亂數出來。
COMBINING DATA SETS
如果有兩個資料想要合併,通常會用 merge 語法:
data Medical;
merge Physical Drugs;
by Patient;
run;
但如果你某筆資料要以「一對多」的方式合併,打個比方說,假設某個資料有病人的資料,但每個病人可能會服用多種藥物,藥物資料卻是放在另一個資料裡面,此時要合併的話,光用 merge 的話 SAS 只會給你一個大大的 error。不過只要使用下面這個程式就可以輕鬆完成這種特殊情況的資料合併。
data Medical;
set Physical (rename=(Patient=tmpPatient));
do i=1 to nObs;
set Drugs nobs=nObs point=i;
if Patient=tmpPatient then output;
end;
run;
最後 William 有提供一個可以很奇怪的 macro,有興趣的人可以自己去看看。
Your comments and questions are values and encouraged. Contact the author at
William C. Murphy
Howard M. Proskin & Associates, Inc.
300 Red Creek Dr., Suite 330
Rochester, NY 14623
Phone 585-359-2420
FAX 585-359-0465
Email wmurphy@hmproskin.com or wcmurphy@usa.net
Web www.hmproskin.com
沒有留言:
張貼留言
要問問題的人請在文章下方的intensedebate欄位留言,請勿使用blogger預設的意見表單。今後用blogger意見表單留言的人我就不回應了。