**************************************************************************************************** * PROGRAM OVERVIEW **************************************************************************************************** * * PROGRAM: ms_surveillance.sas * * Created (mm/dd/yyyy): 04/23/2015 * Last modified: 04/24/2015 * Version: 1.0 * *-------------------------------------------------------------------------------------------------- * PURPOSE: * This macro will check for MSDD changes in prior monitoring looking periods. * * Program inputs: * * * Program outputs: * * * PARAMETERS: * * Programming Notes: * * * *-------------------------------------------------------------------------------------------------- * CONTACT INFO: * Mini-Sentinel Coordinating Center * info@mini-sentinel.org * *-------------------------------------------------------------------------------------------------- * CHANGE LOG: * * Version Date Initials Comment (reference external documentation when available) * ------- -------- -------- --------------------------------------------------------------- * mm/dd/yy * ***************************************************************************************************; %macro ms_surveillance(); *obtain Patid Lengths; data _null_; set DPLPRIOR.&RUNID._mstr(obs=1); call symputx("PatidLengthPrior",vlength(PatId)); run; data _null_; set Indata.&demtable.(obs=1); call symputx("PatidLengthCurrent",vlength(PatId)); run; %if %eval(&PatidLengthPrior. ne &PatidLengthCurrent.) %then %do; %put WARNING: Current PatId length (&PatidLengthCurrent.) is different than the prior Patid length (&PatidLengthPrior.); %end; %put =====> MACRO CALLED: ms_surveillance v1.0; data _null_; set looks; where look=&PERIODIDSTART.-1; call symputx("PriorEndDt",LookEnd); run; *Add look variable to both mstr files for this group; proc sql noprint; create table current as select dat.*, look.* from _PtsMasterList as dat, looks as look where look.LookStart<=dat.indexdt<=look.LookEnd order by Patid,look,Indexdt,EpisodeEndDt; quit; *Get prior data from members identified in prior looks; proc sql noprint; create table PriorRunLegacy as select dat.*, look.*, dat.FEventDt as PriorEventDt, /*look.LookEnd*/ &PriorEndDt. as PriorEndDt format date9. from DPLPRIOR.&RUNID._mstr as dat, looks as look where look.LookStart<=dat.indexdt<=look.LookEnd and dat.group="&ITGROUP." and look.look < &PERIODIDSTART. order by Patid,look,Indexdt,EpisodeEndDt; quit; * Restrict to Patients identified in prior looks, but keeping their current data; data PriorRunCurrent; set current; where look < &PERIODIDSTART.; *keeping only the forward looking variables; keep group Patid Indexdt look enr_end EpisodeEndDt NumEvents FEventDt tte NumDisp TotRxSup TotRxAmt LastLookFollowed: EndFollowUpType; run; *delete from PriorRunCurrent those patients that should not be followed anymore.; %VAREXIST(PriorRunLegacy,LastLookFollowed); %if %eval(&VAREXIST.=1) %then %do; %put LastLookFollowed variable exists.; proc sort nodupkey data=PriorRunLegacy out=ptsNoFollow(keep=Patid); by Patid; where LastLookFollowed > 0; run; *remove updated data for those already LastLookFollowed; data PriorRunCurrent; merge PriorRunCurrent(in=a) ptsNoFollow(in=b); by Patid; if a; if a and b then delete; run; %end; *for patients identified in prior looks, compare new and older data and identify changes; data Changes; merge PriorRunLegacy(in=a rename=EpisodeEndDt=PriorEpisodeEndDt) PriorRunCurrent(in=b); by Patid look Indexdt; format EndFollowUpType $20.; if a; *to always keep all patients from prior looks.; *index date doesnt match anymore (index date changed, patid changed, INCL/EXCL changed, incidence changed); if not b and LastLookFollowed=0 then do; *prior look member/indexdt lost; LastLookFollowed=&PERIODIDSTART.-1; EndFollowUpType="IndexDateChange"; LastLookFollowedDt = PriorEndDt; output; end; else if "&SURVEILLANCEMODE."="f" and LastLookFollowed=0 then do; *Event date has changed in the prior look timeframe; if FEventDt ne PriorEventDt and min(FEventDt,PriorEventDt) <= PriorEndDt then do; LastLookFollowed = &PERIODIDSTART.-1; LastLookFollowedDt = PriorEndDt; EndFollowUpType="EventDateChange"; output; end; *Episode capped at prior end date has changed; else if EpisodeEndDt ne PriorEpisodeEndDt and min(PriorEpisodeEndDt,EpisodeEndDt) < PriorEndDt then do; LastLookFollowed = &PERIODIDSTART.-1; LastLookFollowedDt = PriorEndDt; EndFollowUpType="EndDateChange"; output; end; end; keep Patid LastLookFollowed LastLookFollowedDt EndFollowUpType; *keeping only the flags; run; *delete records for patients that are newly lost to followup (changes were identified during this look); proc sort nodupkey data=Changes; by Patid; run; *Remove updated data for those newly LastLookFollowed; data PriorRunCurrent; merge PriorRunCurrent(in=a) Changes(in=b); by Patid; if a; if a and b then delete; run; *at this point, PriorRunCurrent ony has updated data for those still being followed.; data PriorRunsUpdated; merge PriorRunLegacy(in=a) PriorRunCurrent(in=b); by Patid look Indexdt; format EndFollowUpType $20.; if a; *to always keep all patients from prior looks and the right merge will update their forward looking variables.; run; *add reason for LastLookFollowed back; data PriorRunsUpdated; merge PriorRunsUpdated Changes; by Patid; run; *Delete patients with an index date in the prior look(s) that could have been shifted to this look.; proc sort nodupkey data = PriorRunLegacy out=PriorPatidList(keep=Patid); by Patid; run; data current; merge current(in=a) PriorPatidList(in=b); by Patid; if a and b then delete; * drop blackoutper; run; *Reconstruct mstr with updated prior Runs and current run; data _PtsMasterList; set PriorRunsUpdated /*The updated records*/ current(in=a where=(&PERIODIDSTART.<=look<=&PERIODIDEND.)); by Patid look Indexdt; if missing(LastLookFollowed) then LastLookFollowed=0; IndexLook=look; drop look: PriorEventDt PriorEndDt; run; %if ("&SURVEILLANCEMODE."="f") %then %do; data _PtsMasterList; set _PtsMasterList; if indexlook<=&PERIODIDSTART. and LastLookFollowed=0 then do; if min(Feventdt,EpisodeEndDt) < &enddate. then do; LastLookFollowedDt = &enddate.; LastLookFollowed = &PERIODIDSTART.; EndFollowUpType="EpisodeEndBFEnddate"; end; else if Feventdt = &enddate. then do; LastLookFollowedDt = &enddate.; LastLookFollowed = &PERIODIDSTART.; EndFollowUpType="EventOnEnddate"; end; end; run; %end; *clean up; proc datasets library=work nolist nowarn; delete current: prior: Changes ptsNoFollow; quit; %put NOTE: ******** END OF MACRO: ms_surveillance v1.0 ********; %mend;