BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
thb
Fluorite | Level 6 thb
Fluorite | Level 6

Hello,

 

I am having trouble getting the highest count of consecutive data for my dataset.  Here's an example of my data:

 

IDApptYearMonth
1A201410
1A201411
1A201412
1B20151
1B20152
1B20153
1B20154
2A201410
2A201411
2A201412
2A20151
2A20152
2B20161
2B20162
2B20163
2B20164

 

 

 

The code I am using is below, but I am not getting the results that I want.  Since an ID can have multiple consecutive appointment times, I need to only take the highest consecutive count.  With the code below, I am getting the following data:

 

IDApptYearMonthConsecutive
1A2014101
1A2014112
1A2014123
1B201514
1B201525
1B201536
1B201547
2A2014101
2A2014112
2A2014123
2A201514
2A201525
2B201616
2B201627
2B201638
2B201649
          

 

 

However, I want the following table to be produced:

 

IDApptYearMonthConsecutive
1A2014101
1A2014112
1A2014123
1B201511
1B201522
1B201533
1B201544
2A2014101
2A2014112
2A2014123
2A201514
2A201525
2B201611
2B201622
2B201633
2B201644

 

Then, ideally I would only want the final table with the highest consecutive count:

 

IDApptYearMonthConsecutive
1B201511
1B201522
1B201533
1B201544
2A2014101
2A2014112
2A2014123
2A201514
2A201525

 

 

 

data TestD (KEEP = ID Appt Year Month Consecutive);
	SET TestC;
	BY ID Appt;
	RETAIN Consecutive;
	IF First.ID or First.Appt THEN Consecutive = 0;
	ELSE Consecutive = Consecutive +1;
  	IF Consecutive GT 0 THEN OUTPUT;     
run;

 

Thank you for your help in advance!

1 ACCEPTED SOLUTION

Accepted Solutions
novinosrin
Tourmaline | Level 20

 

 

 

 

 

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;

View solution in original post

20 REPLIES 20
novinosrin
Tourmaline | Level 20
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;
if 0 then set have;
do Consecutive=1 by 1 until(last.appt);
set have;
by id appt;
output;
end;
run;

 

 
thb
Fluorite | Level 6 thb
Fluorite | Level 6

Hi novinosrin.

 

Thank you for your response, but unfortunately that does not give me the data that I need.

 

 

novinosrin
Tourmaline | Level 20

does that solve the first problem?

thb
Fluorite | Level 6 thb
Fluorite | Level 6

No, the main problem is trying to get a true consecutive count by ID, Appt, Year, and Month.

novinosrin
Tourmaline | Level 20

I wonder why my understanding is so poor,

 

are you after this?

 

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 Year	Month;
if dif(month) ne 1 then Consecutive=1;
else Consecutive+1;
run;


or

 

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;

 

thb
Fluorite | Level 6 thb
Fluorite | Level 6

Hi 

 

 

 

 

novinosrin
Tourmaline | Level 20

I think this is prolly more closer?

 

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 dif(month)=1 or (dif(month) ne 1 and month=1 and lag(month)=12) then Consecutive+1;
else Consecutive=1;
run;

 

thb
Fluorite | Level 6 thb
Fluorite | Level 6

Hello,

 

Yes, this is the consecutive count that I want, however I only want to keep the data for the ID with the highest consecutive count.

 

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
 

  It's so close - any idea on how to get rid of the over observations?

 

Thank you 

Reeza
Super User
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;


date = mdy(month, 1, year);
prev_date = mdy(lag(month), 1, lag(year));

if first.id then do;
consecutive=0;
prev_date=.;
end;


if intck('month', date, prev_date) > 1 then consecutive=1;
else consecutive+1;


run;

@thb wrote:

Hello,

 

I am having trouble getting the highest count of consecutive data for my dataset.  Here's an example of my data:

 

ID Appt Year Month
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

 

 

 

The code I am using is below, but I am not getting the results that I want.  Since an ID can have multiple consecutive appointment times, I need to only take the highest consecutive count.  With the code below, I am getting the following data:

 

ID Appt Year Month Consecutive
1 A 2014 10 1
1 A 2014 11 2
1 A 2014 12 3
1 B 2015 1 4
1 B 2015 2 5
1 B 2015 3 6
1 B 2015 4 7
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
2 B 2016 1 6
2 B 2016 2 7
2 B 2016 3 8
2 B 2016 4 9
              

 

 

However, I want the following table to be produced:

 

ID Appt Year Month Consecutive
1 A 2014 10 1
1 A 2014 11 2
1 A 2014 12 3
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
2 B 2016 1 1
2 B 2016 2 2
2 B 2016 3 3
2 B 2016 4 4

 

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

 

 

 

data TestD (KEEP = ID Appt Year Month Consecutive);
	SET TestC;
	BY ID Appt;
	RETAIN Consecutive;
	IF First.ID or First.Appt THEN Consecutive = 0;
	ELSE Consecutive = Consecutive +1;
  	IF Consecutive GT 0 THEN OUTPUT;     
run;

 

Thank you for your help in advance!


 

thb
Fluorite | Level 6 thb
Fluorite | Level 6

Hi 

 

novinosrin
Tourmaline | Level 20

Hi @Reeza, Sorry for the bother and very embarrassing to ask. I  haven't understood the requirement well enough and rather the task seems far too simple. Have you got it? If yes, when you post, please include a couple of notes 😞

@thb Hang in there

novinosrin
Tourmaline | Level 20

This seems to match your 1st result

 

 

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;

 

 

 

novinosrin
Tourmaline | Level 20

Can you confirm the just previous, or here again. if yes, 2nd part is no biggie

 

 

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;

 

thb
Fluorite | Level 6 thb
Fluorite | Level 6
Hi,

Yes, the first part is correct. Thank you! Now I just need the second part.

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
Mastering the WHERE Clause in PROC SQL

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.

Discussion stats
  • 20 replies
  • 2427 views
  • 0 likes
  • 4 in conversation