Where I work, a person might stay for a month, and do a few items within that month. I am trying to figure out only the first and last date of the stay. As an example,
Member 1 has the following cases...
Case 1 Started 01/01/2019, ended 01/31/2019
Case 2 Started 01/03/2019, ended 01/04/2019
Case 3 Started 01/14/2019, ended 01/18/2019
Case 4 Started 02/15/2019, ended 02/20/2019
Since Cases 2 & 3 took place within the timeframe of case 1, I do not want them to be part of the final data. I only want to return cases 1 and 4 for this member.
How can I best do this?
Thank you for any advice you can provide.
What happens to cases that overlap in time, say where they start within an earlier case but then go beyond it?
I would need to note overlapping dates so they could be checked individually. Times where the dates overlap should be rare.
This would be similar to a hotel stay. You check in for a period of time, and in that time you sign up for activities. It would be rare for an activity to start before or to extend past the hotel stay.
If the dates are
01/01/2019 - 01/31/2019
01/20/2019 - 02/15/2019
I would want to look at it individually.
If the dates are
01/01/2019 - 01//31/2019
01/01/2019 - 01/31/2019
I only care about one of the date ranges. I need to know the person was with us during a time frame, and that is all.
I'm not entirely convinced this will deal with all cases but feel free to test it. I've also added an overlapping example (case = 5).
data have;
input member $ case $ start_date :mmddyy10. end_date :mmddyy10.;
format start_date end_date date9.;
datalines;
1 1 01/01/2019 01/31/2019
1 2 01/03/2019 01/04/2019
1 3 01/14/2019 01/18/2019
1 4 02/15/2019 02/20/2019
1 5 02/18/2019 02/22/2019
;
run;
proc sort data = have;
by member start_date descending end_date;
run;
data want;
drop SD ED;
retain SD ED;
set have;
by member;
if first.member then do;
SD = start_date;
ED = end_date;
end;
else do;
if start_date >= SD and end_date <= ED then delete;
end;
if start_date > ED then do;
SD = start_date;
ED = end_date;
end;
run;
Thank you SASKiwi, I will try this first thing tomorrow morning.
Alternatively, you may try:
data have;
input member case start_date :mmddyy10. end_date :mmddyy10.;
format start_date end_date yymmdd10.;
datalines;
1 1 01/01/2019 01/31/2019
1 2 01/03/2019 01/04/2019
1 3 01/14/2019 01/18/2019
1 4 02/15/2019 02/20/2019
1 5 02/18/2019 02/22/2019
;
proc sql;
select min(start_date)-1, max(end_date)+1
into :d1, :d2
from have;
quit;
data want;
array d_{&d1.:&d2.};
do until(last.member);
set have; by member;
do i = start_date to end_date;
d_{i} = case;
end;
end;
do i = &d1.+1 to &d2-1;
if missing(d_{i-1}) and d_{i} then do;
start_case = d_{i};
start_date = i;
end;
if d_{i} and missing(d_{i+1}) then do;
end_case = d_{i};
end_date = i;
output;
end;
end;
drop d_: i case;
run;
proc print data=want noobs; run;
variable case is replaced by first_case and end_case which my differ in some overlap situations.
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.
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.
Ready to level-up your skills? Choose your own adventure.