Patient ID | Admit date | Discharge Date | status |
---|---|---|---|
1 | 28jan11 | 01feb11 | keep |
1 | 16feb11 | 26feb11 | delete |
1 | 12mar11 | 22mar11 | keep |
1 | 27mar11 | 01apr11 | delete |
1 | 12apr11 | 13apr11 | delete |
1 | 22may11 | 24may11 | keep |
1 | 06jun11 | 09jun11 | delete |
I am trying to create a file of 'index' records only. Index being defined as 'the beginning of a new 30-day window.
The table above has multiple admits for a single patient. I added the 'Status' column for this discussion.
It doesn't exist in the data but represents the result I would like to get. I am comparing admits dates with
previous discharge dates.
The 2nd obs is within 30 days of the 1st obs so I want to get rid of the 2nd record. The 3rd obs is >30 days from
the 1st obs so I want to keep that record as a new index record. The 4th and 5th obs are both within 30 days of
the new index so I want to get rid of those. The 6th is a new index case and the 7th needs to be deleted.
I think this can probably be done in an array but not sure how to construct it.
Thanks
I am sure there will be slicker approaches, but for now, you could try this:
data have;
input PatientID$ (Admitdate DischargeDate) (:date9.) status$;
format Admitdate DischargeDate date9.;
cards;
1 28jan11 01feb11 keep
1 16feb11 26feb11 delete
1 12mar11 22mar11 keep
1 27mar11 01apr11 delete
1 12apr11 13apr11 delete
1 22may11 24may11 keep
1 06jun11 09jun11 delete
;
data want (drop=_:);
retain _date;
set have;
by patientid;
if first.patientid then _date=dischargedate;
if 0<= admitdate-_date < 30 then delete;
else _date=dischargedate;
run;
proc print;run;
Haikuo
Update: if you want to get a little bit fancier and avoid using 'retain', here is an array approach:
data want ;
array d(1) _temporary_;
set have;
by patientid;
if first.patientid then d(1)=dischargedate;
if 0<= admitdate-d(1) < 30 then delete;
else d(1)=dischargedate;
run;
I found that the above code did not work in a case such as below.
Admit 07OCT10 | Discharge 07OCT10 | |
07OCT10 | 11OCT10 | |
---|---|---|
11OCT10 | 23NOV10 |
The above data are for a single patient ID. It looks like cases where the admit
date is the same as the previous discharge date are being excluded . Any suggestions?
This will work:
data have;
input PatientID$ (Admitdate DischargeDate) (:date9.) status$;
format Admitdate DischargeDate date9.;
cards;
1 28jan11 01feb11 keep
1 16feb11 26feb11 delete
1 12mar11 22mar11 keep
1 27mar11 01apr11 delete
1 12apr11 13apr11 delete
1 22may11 24may11 keep
1 06jun11 09jun11 delete
1 07oct11 07oct11 keep
1 07oct11 11oct11 delete
1 11oct11 23oct11 delete
;
proc sql nowarnrecurs;
delete from have as B
where exists(select * from have as A where A.patientId=B.patientId and
intck("DAY", A.DischargeDate, B.AdmitDate, "CONTINUOUS") between 0 and 30);
quit;
PG
This will fix that.
data have;
input PatientID$ (Admitdate DischargeDate) (:date9.) status$;
format Admitdate DischargeDate date9.;
cards;
1 07OCT10 07OCT10 keep
1 07OCT10 11OCT10 delete
1 1OCT10 23NOV10 delete
1 28jan11 01feb11 keep
1 16feb11 26feb11 delete
1 12mar11 22mar11 keep
1 27mar11 01apr11 delete
1 12apr11 13apr11 delete
1 22may11 24may11 keep
1 06jun11 09jun11 delete
;
data want (drop=_:);
retain _date;
set have;
by patientid;
if (first.patientid or not (admitdate-_date < 30)) then _date=dischargedate;
else delete;
run;
Good Luck,
Haikuo
data want (drop=_:);
retain _lastdischdt;
set have;
by patientid;
if not ( first.patientid or (admitdate-_lastdischdt >= 30) ) then delete;
_lastdischdt = dischargedate;
run;
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.