/**
@file ms_envelope.sas
@brief This macro uses data from the SDD to recode non-inpatient encounters to inpatient if they were determined to have occurred during an inpatient stay.
@details
- Extract IP encounters (occuring after &mindate. when specified)
- Remove encounter ids to delete if required
- Collapse IP encounters into IP episodes to reduce number of observations involved in joining datasets.
- For each record in INFILE within an inpatient stay, recode encounter type as inpatient if not already coded as such.
@par Program inputs
- &ENCOUNTERINFILE. (Dataset with encounter data.)
- &INFILE. (Dataset with diagnosis/procedure claims data.)
@par Program outputs
- &OUTFILE. (Dataset with reclassified claims.)
* **Usage**
%ms_envelope(INFILE=worktemp.meds,
ENCOUNTERINFILE=indata.&ENCTABLE.,
MINDATE=&studystartdate,
OUTFILE=worktemp.meds);
@param [in] INFILE Name of SAS dataset with diagnosis and/or procedure claims data.
@param [in] ENCOUNTERINFILE Name of SAS dataset with encounter data.
@param [in] MINDATE Extract all claims occuring on or after this date.
@param [out] OUTFILE Name of output file with reclassified claims.
SAS Macros Dependencies
@li ms_delencounterids.sas
@note This operation is done without using the ENCOUNTERID variable, as this variable can be inconsistent across data partner datasets.
@author Sentinel Coordinating Center (info@sentinelsystem.org)
**/
%macro MS_ENVELOPE(INFILE=,ENCOUNTERINFILE=,MINDATE=,OUTFILE=);
%put =====> MACRO CALLED: ms_envelope;
*Reclassification as inpatient all selected claims within admission and discharge dates of an inpatient stay;
*Get Unique ADate-Ddate combinations;
proc sort nodupkey data=&ENCOUNTERINFILE.(keep=PatId Adate Ddate EncType %if %str(&ENCIDTOEXCLUDE.) ne %str() %then %do; encounterid %end;
where=(EncType='IP' %if %str("&mindate") ne %str("") %then %do; and max(Adate, Ddate) >= &mindate. %end;))
out=_IPdates(keep=PatId Adate Ddate %if %str(&ENCIDTOEXCLUDE.) ne %str() %then %do; encounterid %end;);
by PatId Adate Ddate;
run;
*Delete data for encounterids in DPs &ENCIDTOEXCLUDE. files;
%ms_delencounterids(datafile=_IPdates,
EncIdsfile=&ENCIDTOEXCLUDE.,
Outfile=_IPdates);
%if &run_envelope. = 0 %then %do;
%let sign = %str(<=);
* Many consecutive single day encounters can be present for a patient in _IPDates. For efficiency purposes,
collapse IP encounters into IP episodes considering a 0 day gap to reduce the number of observations before joining with &INFILE.;
data _IPdates;
set _IPdates %if %str(&ENCIDTOEXCLUDE.) ne %str() %then %do; (drop=encounterid) %end;;
by PatId Adate;
length IP_episode 3;
if Adate - max(lag(Adate),lag(Ddate))-1 > 0 then IP_episode=IP_episode+1;
if first.Patid then IP_episode=1;
if missing(Ddate) then Ddate=Adate;
retain IP_episode;
run;
proc sql noprint undo_policy=none;
create table _IPdates as
select PatId,
min(adate) as IP_Adate format=mmddyy10. length=4,
max(ddate) as IP_Ddate format=mmddyy10. length=4
from _IPdates
group by Patid, IP_episode;
quit;
%end;
%else %do;
%let sign = %str(<);
proc datasets nowarn nolist lib=work;
modify _IPdates;
rename adate = IP_Adate;
rename ddate = IP_Ddate;
quit;
%end;
*For each record in &INFILE within an inpatient stay, recode encounter type as inpatient if not already coded as such;
data &OUTFILE.;
if 0 then set _IPdates(keep=PatId IP_Adate IP_DDate);
declare hash h(dataset:"_IPdates",HASHEXP:16, multidata:"Y");
h.definekey('PatId');
h.definedata('IP_Adate', 'IP_DDate');
h.definedone();
do until (eof);
set &INFILE. end=eof;
drop IP_:;
if h.num_items>0 then do;
rc = h.find();
do while (rc = 0);
if EncType ne 'IP' and IP_ADate &sign. ADate <= max(IP_ADate,IP_DDate) then do;
pdx='X';
EncType='IP';
end;
rc = h.find_next();
end;
drop rc;
end;
output;
end;
run;
proc datasets library = work nolist nowarn nodetails;
delete _IPDates;
quit;
%put NOTE: ******** END OF MACRO: ms_envelope ********;
%mend MS_ENVELOPE;