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.
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:
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?
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.
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!
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;
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
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;
Thank you so much, Reeza. I'll check this out and let you know how I do!
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.
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;
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!!
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.
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.
Of course! Thanks so much, Arthur, it worked as I'm sure you knew it would!!
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 16. Read more here about why you should contribute and what is in it for you!
Need courses to help you with SAS Life Sciences Analytics Framework, SAS Health Cohort Builder, or other topics? Check out the Health and Life Sciences learning path for all of the offerings.