DATA Step, Macro, Functions and more

Array

Reply
Occasional Contributor
Posts: 17

Array

Patient IDAdmit dateDischarge Datestatus
128jan1101feb11keep
116feb1126feb11delete
112mar1122mar11keep
127mar1101apr11delete
112apr1113apr11delete
122may1124may11

keep

106jun1109jun11delete

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

Respected Advisor
Posts: 3,156

Re: Array

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=_Smiley Happy;

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;

Occasional Contributor
Posts: 17

Re: Array

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?

Respected Advisor
Posts: 4,927

Re: Array

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

PG
Respected Advisor
Posts: 3,156

Re: Array

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=_Smiley Happy;

retain _date;

  set have;

  by patientid;   

  if (first.patientid or not (admitdate-_date < 30)) then _date=dischargedate;

    else delete;

run;

Good Luck,

Haikuo

Frequent Contributor
Posts: 101

Re: Array

data want (drop=_Smiley Happy;

retain _lastdischdt;

set have;

by patientid;

if not ( first.patientid or (admitdate-_lastdischdt >= 30) ) then delete;

_lastdischdt = dischargedate;

run;

Ask a Question
Discussion stats
  • 5 replies
  • 322 views
  • 0 likes
  • 4 in conversation