Thank you @thb Here you go, sure I can optimize and make it efficient, however i have to run to catch the train to get home. I hope this meets your requirement.
data have;
input ID Appt $ Year Month;
cards;
1 A 2014 10
1 A 2014 11
1 A 2014 12
1 B 2015 1
1 B 2015 2
1 B 2015 3
1 B 2015 4
2 A 2014 10
2 A 2014 11
2 A 2014 12
2 A 2015 1
2 A 2015 2
2 B 2016 1
2 B 2016 2
2 B 2016 3
2 B 2016 4
;
data want;
set have;
by id appt ;
if first.appt then Consecutive=0;
if dif(month)=1 or (dif(month) ne 1 and month=1 and lag(month)=12) then Consecutive+1;
else Consecutive=1;
run;
/*want final*/
proc sql;
create table want_final(drop=m) as
select *
from
(select *,max(Consecutive) as m
from want
group by id)
group by id,appt
having count(*)=m
order by id,appt,consecutive;
quit;
Hi novinosrin,
Thank you so much for your help. I am almost there. Unfortunately the code provided for the final table is not pulling all of the data that I need.
The code you provided is giving me the correct consecutive count below in Table 1:
Table 1:
| ID | Appt | Year | Month | Consecutive |
| 1 | A | 2014 | 10 | 1 |
| 1 | A | 2014 | 11 | 2 |
| 1 | A | 2014 | 12 | 3 |
| 1 | A | 2015 | 1 | 4 |
| 1 | A | 2015 | 2 | 5 |
| 1 | A | 2015 | 3 | 6 |
| 1 | A | 2015 | 4 | 7 |
| 2 | B | 2015 | 1 | 1 |
| 2 | B | 2015 | 2 | 2 |
| 2 | B | 2015 | 3 | 3 |
| 2 | B | 2015 | 4 | 4 |
| 2 | B | 2015 | 5 | 5 |
| 2 | B | 2015 | 6 | 6 |
| 2 | B | 2015 | 7 | 7 |
| 2 | B | 2015 | 8 | 8 |
However, when I run the code for *want final*, I am only getting the data below in Table 2:
Table 2:
| ID | Appt | Year | Month | Consecutive |
| 2 | B | 2015 | 1 | 1 |
| 2 | B | 2015 | 2 | 2 |
| 2 | B | 2015 | 3 | 3 |
| 2 | B | 2015 | 4 | 4 |
| 2 | B | 2015 | 5 | 5 |
| 2 | B | 2015 | 6 | 6 |
| 2 | B | 2015 | 7 | 7 |
| 2 | B | 2015 | 8 | 8 |
I need both Appt A and B from Table 1.
Are you sure?
I justreran the same code and i got the below results:
ID Appt Year Month Consecutive
1 B 2015 1 1
1 B 2015 2 2
1 B 2015 3 3
1 B 2015 4 4
2 A 2014 10 1
2 A 2014 11 2
2 A 2014 12 3
2 A 2015 1 4
2 A 2015 2 5
data have;
input ID Appt $ Year Month;
cards;
1 A 2014 10
1 A 2014 11
1 A 2014 12
1 B 2015 1
1 B 2015 2
1 B 2015 3
1 B 2015 4
2 A 2014 10
2 A 2014 11
2 A 2014 12
2 A 2015 1
2 A 2015 2
2 B 2016 1
2 B 2016 2
2 B 2016 3
2 B 2016 4
;
data want;
set have;
by id appt ;
if first.appt then Consecutive=0;
if dif(month)=1 or (dif(month) ne 1 and month=1 and lag(month)=12) then Consecutive+1;
else Consecutive=1;
run;
/*want final*/
proc sql;
create table want_final(drop=m) as
select *
from
(select *,max(Consecutive) as m
from want
group by id)
group by id,appt
having count(*)=m
order by id,appt,consecutive;
quit;
proc print noobs;run;
And those results match with your desired results in the question
You wrote-
"Then, ideally I would only want the final table with the highest consecutive count:
| ID | Appt | Year | Month | Consecutive |
| 1 | B | 2015 | 1 | 1 |
| 1 | B | 2015 | 2 | 2 |
| 1 | B | 2015 | 3 | 3 |
| 1 | B | 2015 | 4 | 4 |
| 2 | A | 2014 | 10 | 1 |
| 2 | A | 2014 | 11 | 2 |
| 2 | A | 2014 | 12 | 3 |
| 2 | A | 2015 | 1 | 4 |
| 2 | A | 2015 | 2 | 5 |
My results:
ID Appt Year Month Consecutive
1 B 2015 1 1
1 B 2015 2 2
1 B 2015 3 3
1 B 2015 4 4
2 A 2014 10 1
2 A 2014 11 2
2 A 2014 12 3
2 A 2015 1 4
2 A 2015 2 5
Hi novinosrin,
For some reason, when I'm running that code for *want final* table, it's dropping my data that has less consecutive appts. For example, it only captures appt A and not appt B.
data have;
input ID Appt $ Year Month;
cards;
1 A 2014 10
1 A 2014 11
1 A 2014 12
1 B 2015 1
1 B 2015 2
1 B 2015 3
1 B 2015 4
2 A 2014 10
2 A 2014 11
2 A 2014 12
2 A 2015 1
2 A 2015 2
2 B 2016 1
2 B 2016 2
2 B 2016 3
2 B 2016 4
;
data month;
do m=1 to 12;
output;
end;
run;
proc sql;
create table temp as
select a.*,b.month,missing(b.month) as group
from (select * from (select distinct ID,Appt,Year from have),(select m from month)) as a
left join
(select * from have) as b
on a.ID=b.ID and a.Appt=b.Appt and a.Year=b.Year and a.m=b.month
order by 1,2,3,4;
quit;
data temp1;
set temp;
by ID Appt group notsorted;
if first.group then count=0;
count+1;
if not missing(month);
drop m group;
run;
proc sql;
create table want as
select *
from temp1
where catx(' ',id,Appt) in
(select catx(' ',id,Appt) from temp1 group by id having count=max(count));
quit;
April 27 – 30 | Gaylord Texan | Grapevine, Texas
Walk in ready to learn. Walk out ready to deliver. This is the data and AI conference you can't afford to miss.
Register now and lock in 2025 pricing—just $495!
SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.
Find more tutorials on the SAS Users YouTube channel.