BookmarkSubscribeRSS Feed
shellp55
Quartz | Level 8

Hello

I have base SAS and I'm using version 9.3.

I have patient visit data where one line of data is one visit.  There are 20 potential interventions coded though this varies per visit and in fact some patients will have zero interventions.  There is also the possibility that a patient can have interventions on different dates with each date being a separate episode.

The way the data is structured is that I have a procedure start date and procedure code for the 20 potential spots.  So px1-px20 and pxstartdt1-pxstartdt20.  The data is entered such that if there is a px2 and pxstartdt2 is null then px2 is still part of episode 1.  If pxstartdt2 <> pxstartdt1 then it's a new episode.  Adding another wrinkle is that pxstartdt2 could have a date that matches pxstartdt1 which means it is still part of episode 1.

What I'm trying to do is loop through all 20 intervention spots and indicate episode number and also intervention occurrence number.

Example:

px1=5MD60AA

pxstartdt1=Apr 1, 2012

px2=1RB89LA

pxstartdt2=

px3=1YM91LA

pxstartdt3=

px4=3OD70CA

pxstartdt4=April 5, 2012

In the example above px1 would be episode 1, occurrence 1; px2 would be episode 1, occurrence 2; px3 would be episode 1, occurrence 3; px4 would be episode 2, occurrence 1.

Can someone start me on what code I would use to accomplish this?  Thanks very much.

14 REPLIES 14
shellp55
Quartz | Level 8

Hi

I figured out that I really don't want to loop through but I want to keep checking one to the others to see what episode it is.  It's not bad for the first few but by procedure 20 I will have to singularly compare to all the other dates....or do I?

Below is the code I've got thus far (up to procedure 3) which works but I'm just trying to figure out if there is an easier/cleaner way to write it:

Reeza
Super User

The easiest method (to code and understand) is to transpose your data from wide to long and then use by processing and re-transpose again at the end.

OR you could use arrays to simplify the logic above.

Can you post some data in a data step?

shellp55
Quartz | Level 8

Hi Reeza

Thanks for responding....sorry but I'm unsure what you mean about posting data in a data step.  Please clarify and I'll do it.

Thanks.

Reeza
Super User

Like the first post in the thread here.

Basically, so I can cut and paste, run the code and have your sample data without trying to mimic it myself.

shellp55
Quartz | Level 8

Hi Reeza

data
test_grp;

input @1 regno $3.

        @4 PxStDate1 yymmdd8.

        @12 Px1 $7.

        @19 PxStDate2 yymmdd8.

       @27 Px2 $7.

       @34 PxStDate3 yymmdd8.

       @42 Px3 $7.

        @49 PxStDate4 yymmdd8.

       @57 Px4 $7.;

format PxStDate1-PxStDate4 yymmdd10.;

cards;

001201203291RB89LA        1RB87LA        2OT71LA

002201204171RM89LA        1RD89LA201204203OT20WE

003201204201VA53LA201204251VC55LA201204303OT20WE

004201205131RM89LA        1RD89LA        2OT71LA201205253OT20WE

005201206021VA53LA        1VC55LA        2OT20WE201206233OT20WE

006201203291RB89LA        1RB87LA        2OT71LA

run;

What should occur from above is:

regno 001 should have all 3 procedures as episode 1

regno 002 should have procedures 1 and 2 be episode 1 and procedure 3 is episode 2

regno 003 should have all 3 procedures be their own episode so episodes 1, 2 and 3

regno 004 should have procedures 1 and 2 be episode 1 and procedure 3 is episode 2

regno 005 should have procedures 1 and 2 be episode 1 and procedure 3 is episode 2

regno 006 should have all 3 procedures as episode 1

Thanks for your help, Reeza!

Reeza
Super User

regno 4/5 both have 4 procedures so assuming your logic holds, here some code that generates the episode/occurrence info.

If you need help flipping the data back to single row let me know.

data flipped;

    set test_grp;

    array pdates(4) pxstdate1-pxstdate4;

    array dx(4) px1-px4;

    do i=1 to 4;

        if i>1 and pdates(i)=. then pdates(i)=pdates(i-1); *Set it to the last date if missing and not the first of the record;

        px=dx(i);

        date=pdates(i);

        format date date9.;

        if dx(i) ne '' then output;

    end;

    drop pxstdate: px1-px4;

run;

*You may need to sort depending of what you're doing;

data flipped_mark;

    set flipped;

    by regno date px notsorted;

    retain episode occurrence;

    if first.regno then do;

        episode=1;

        occurrence=1;

    end;

    else if first.date then do;

        episode+1;

        occurrence+1;

    end;

    else if first.px then do;

        occurrence+1;

    end;

run;

Reeza
Super User

This might be the array solution but I can't seem to get the first one to work out properly.

Maybe you can debug it Smiley Happy

data test_grp2;

    set test_grp;

    array pdates(4) pxstdate1-pxstdate4;

    array dx(4) px1-px4;

    array episode(4);

    array occurrence(4);

    do i=1 to 4;

        if i=1 then do;

            episode(i)=1;

            occurrence(i)=1;

        end;

        else if (pdates(i)=. and not missing(dx(i)) ) or pdates(i)=pdates(i-1) then do;

            episode(i)=episode(i-1);

            occurrence(i)=occurrence(i-1)+1;

        end;

        else if not missing(dx(i)) then do;

            episode(i)=episode(i-1)+1;

            occurrence(i)=1;

        end;

        else if missing(dx(i)) then leave;

    end;

run;

shellp55
Quartz | Level 8

Thank you so much, Reeza.  I'll check this out and let you know how I do!

shellp55
Quartz | Level 8

Hi Reeza

Sorry but when I copied into the actual data, it's not working for cases where there is no procedure including for after there is data.  What I mean by that is if there are procedures in px1, px2 and px3, then the code will still insert an episode number in episode for px4 though it doesn't exist.

Are you able to help with that?  Thanks.

Reeza
Super User

What about this version?

data test_grp2;

    set test_grp;

    array pdates(4) pxstdate1-pxstdate4;

    array dx(4) px1-px4;

    array episode(4);

    array occurrence(4);

    do i=1 to 4;

        if i=1 then do;

            episode(i)=1;

            occurrence(i)=1;

        end;

        else if missing(dx(i)) then leave;

        else if pdates(i)=.  or pdates(i)=pdates(i-1) then do;

            episode(i)=episode(i-1);

            occurrence(i)=occurrence(i-1)+1;

        end;

        else if not missing(dx(i)) then do;

            episode(i)=episode(i-1)+1;

            occurrence(i)=1;

        end;

       

    end;

run;

shellp55
Quartz | Level 8

Hi Reeza

Thanks so much. This works
for the example provided but in mine I also added a 7th that doesn't have any
procedures at all and it still comes up with having episode 1 and occurrence 1.

So I changed the code to be
"if not missing(px1) then do i=1 to 4;" and that seems to
have fixed it. The logic is that if there isn't a px1 then there won't be any
procedures.

I'll apply this test to my "real" data and see what happens. Thanks so much for your help on
this Reeza!!

shellp55
Quartz | Level 8

Hi

I don't know if I should post a different thread but the final piece of this puzzle is that I need to now convert the episode and occurrence number into a text combination.

I tried by doing the following:

array px_epi(20) epi1-epi20;

array px_num(20) px_occur1-px_occur20;

array epi_occur(20);

if not missing(epi1) then do k=1 to 20;

epi_occur(k)=put(px_epi(k),2.)||"-"||put(px_num(k),2.);

end;

This isn't working and when I tried to just convert the episode, the field of epi_occur shows up but still as a number.  Why wouldn't this be working?  Thanks!

P.S.

Is there an easier way to copy code into this forum?  It seems I have to copy into Word first then copy and paste from there.

art297
Opal | Level 21

Question 1: declare the array epi_occur(20) as character.  I don't know how big your fields are, thus can't suggest the correct length, but something like:

array epi_occur(20) $30.;

Question 2: You are probably using IE.  With Google Chrome, the problem goes away.

shellp55
Quartz | Level 8

Of course!  Thanks so much, Arthur, it worked as I'm sure you knew it would!! 

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

New Learning Events in April

 

Join us for two new fee-based courses: Administrative Healthcare Data and SAS via Live Web Monday-Thursday, April 24-27 from 1:00 to 4:30 PM ET each day. And Administrative Healthcare Data and SAS: Hands-On Programming Workshop via Live Web on Friday, April 28 from 9:00 AM to 5:00 PM ET.

LEARN MORE

Discussion stats
  • 14 replies
  • 2159 views
  • 0 likes
  • 3 in conversation