公告

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

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


2007年2月23日 星期五

A SAS Macro to Count Consecutive Days

原文載點:http://www2.sas.com/proceedings/sugi29/069-29.pdf

本篇是由 Pingping Zhang 於2004年的 SUGI 29 發表出來。篇幅很短,只有三頁。目標也很簡單,就是提供一個 macro 程式來計算某些具有連續日期的資料,如:



那個 macro 程式是這樣寫的:

%macro CONSECUTIVEDAYS ( indata=, /* name of inputting data set */
subject=, /* id variable, such as patid, patno, patient */
chkdate=, /* date variable that we will count the number of consecutive days, need to be numerical SAS date */
numconday=, /* at least how many consecutive days required to output */
outdata= /* name of outputting data set */
);

%*****sorting data by subject and date *****;
proc sort data=&indata nodupkeys;
by &subject &chkdate;
run;
%*****flagging the same number when date is consecutive to the previous date *****;
data one;
set &indata;
by &subject &chkdate;
tempdate=lag(&chkdate);
if first.&subject then tempdate=.;
retain cflag;
if first.&subject then cflag=1;
if &chkdate ne tempdate+1 then cflag=cflag+1;
run;
%*****counting the number of same flags *****;
data two(keep= &subject cflag consecutive);
set one;
by &subject cflag;
retain consecutive;
if first.cflag then consecutive=0;
consecutive=consecutive+1;
if last.cflag and consecutive>=&numconday;
run;
%***** merging two (counts) with one (original) *****;
data three;
merge one two(in=a);
by &subject cflag;
if a;
run;
SUGI 29 Coders' Corner
4
%***** getting one observation per subject when it has at least required consecutive day ***;
proc sort data=three;
by &subject cflag &chkdate;
run;
data four;
set three;
by &subject cflag &chkdate;
retain firstdate;
if first.cflag then firstdate=&chkdate;
lastdate=&chkdate;
format lastdate firstdate date9.;
if last.cflag;
run;
proc sort data=four(drop=cflag &chkdate tempdate) out=&outdata;
by &subject firstdate;
run;
%mend CONSECUTIVEDAYS;


參數說明:

indata = 原始資料檔名
subject = ID變數名稱
chkdate = 日期變數名稱
numconday = 連續天數
outdata = 輸出結果的資料檔名

範例一:
%CONSECUTIVEDAYS ( indata=Diary,
subject=SUBID,
chkdate=PATDYDT,
numconday=4,
outdata=out1);


輸出結果:


說明:從Diary檔裡面找出有連續四天以上的觀測值,並且列出第一天和最後一天的日期。

範例二:
%CONSECUTIVEDAYS ( indata=Diary,
subject=SUBID,
chkdate=PATDYDT,
numconday=3,
outdata=out1);


輸出結果:


說明:從Diary檔裡面找出有連續三天以上的觀測值,並且列出第一天和最後一天的日期。

因此,如果要計算所有觀測值的連續觀測天數的話,只要把 numconday 的參數設定成 1 即可。

CONTACT INFORMATION
Your comments and questions are valued and encouraged. Contact the author at:
Pingping Zhang
Kendle International Inc.
1200 Carew Tower 441 Vine Street
Cincinnati, OH 45202
Work Phone: 513-345-1526
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; }