公告

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

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


2008年4月30日 星期三

Adding One Value to All Observations

原文載點:http://www.nesug.info/Proceedings/nesug07/cc/cc45.pdf

這篇文件主要是在教如何將一個單一的值放進每一個觀測值裡面。文中一共使用四種方法,各種優缺點也一併討論。

首先整篇文章都是用下面這個資料 temp 當作範例。

[範例一]
如果要計算 EARNHR 的平均數,並順便把結果放在變成第四個變數 AVGEARNHR,則可以用下面這個程式完成:
proc sql ;
create table temp1 as
select *,
mean(EARNHR) as AVGEARNHR format = 8.2
from temp ;
quit;


這段 PROC SQL 首先是建立一個新的資料名為 temp1,並用 select * 選取 temp 裡面所有變數,之後馬上加上 mean(EARNHR) 來計算該變數的平均數,並把結果存在 AVGEARNHR 這個新變數裡面,其格式為數值 8.2。

列印 temp1 後的結果如下:


好處:簡單使用。
壞處:PROC SQL 所提供的函示很少,所以如果是要算一些奇怪的統計量而 PROC SQL 沒有內建的函示的話,這個方法就不適用了。

[範例二]
如果要讓程式在計算出 EARNHR 的平均數後做資料篩選,把 0<=EARNHR <= AVGEARNHR 的觀測值保留下來,則可以使用下面這個程式:
proc sql ;
select
mean(EARNHR) as AVGEARNHR format = 8.2 into :MEANEARNHR
from temp ;
quit;

data temp2 ;
set temp ;
where EARNHR ge 0 and EARNHR lt &MEANEARNHR ;
run ;


第一段 PROC SQL 只是單純地做計算平均數的動作,並把 AVGEARNHR 存成一個 macro 變數 MEANEARNHR,使其能夠直接使用於第二段的 data step 中。

列印 temp2 的結果如下:


好處:比使用 PROC MEANS 來算平均數然後再代入原始資料要來的快。
壞處:同範例一的壞處。

[範例三]
如果遇到 PROC SQL 函式庫裡所沒有的函式(如中位數),則需改用下面 PROC MEANS 來輔助。如下所示:
proc means data = temp noprint ;
var EARNHR ;
output out = add (drop = _TYPE_ _FREQ_) median(EARNHR) = MEDIANEARNHR;
run ;

data temp3 ;
if _N_ = 1 then set add ;
set temp ;
run ;


第一段的 PROC MEANS 就是拿來算 PROC SQL 所無法計算的中位數 MEDIANEARNHR,並另存於新的資料 add 裡面。然後在第二段的 data step 裡面用 if _N_=1 then set 的方法把 add 加入到 temp 裡面並另存新檔。

最後新資料 temp3 的結果變成:


好處:可解決 PROC SQL 無法提供特地函式的問題。
壞處:撰寫過程沒有如同 PROC SQL 那樣直覺。若不知 if _N_ = 1 then set 這個技巧的人就沒有辦法把算出來的值加進原始資料裡面。

[範例四]
此範例其實是結合範例二和範例三。程式如下:
proc means data = temp noprint ;
var EARNHR ;
output out = add2 (drop=_TYPE_ _FREQ_) median(EARNHR) = MEDIANEARNHR;
run ;

data _null_ ;
set add2 ;
call symputx ('MDNEARNHR', MEDIANEARNHR) ;
run ;

data temp4 ;
set temp ;
where EARNHR ge 0 and EARNHR lt &MDNEARNHR ;
run ;


第一段仍是用 PROC MEANS 來計算中位數。第二段則是用一個虛擬的資料 _null_(該資料不會出現在任何 library 裡面)把剛剛算出來的中位數用 Call SYMPUTX 存成一個 macro 變數 MEDIANEARNHR。最後第三段就可以直接使用這個 macro 變數去篩選資料。

結果如下:


好處:Call SYMPUTX 可以把任何要加入的數值變成 macro 變數,讓他能夠無論在任何階段都能使用。
壞處:同樣是不夠直覺。
補充:Call SYMPUTX 和 Call SYMPUT 的不同之處在於 Call SYMPUTX 可以直接把要轉成 macro 變數的原始變數內可能含有的空格完全刪除。

CONTACT INFORMATION
Your comments and questions are valued and encouraged. Contact the author at:
Anne W. Warren
MDRC
16 East 34th Street, 19th floor
New York, NY 10016
Work Phone: 212.340.8661
Fax: 212.684.0832
Email: anne.warren@mdrc.org
Web: www.mdrc.org
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; }