BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Shradha1
Obsidian | Level 7
I have a list of customers and their monthly ratings ranging from 0 to 9 for all the months. I want to select only those customers for whom once the rating reached value 2 or above, it kept on increasing thereafter and never fell back to a lower rating(0 or 1), or stayed the same. In other words, I want those customers for whom their rating has been 2 or above, with monotonously increasing in the later months. I am using Sas 9.4.

Data sample;
Input customer$8. Rating month date9.;
Cards;
A 0 Jan19
A 1 Feb19
A 2 Mar19
A 2 Apr19
A 3 May19
A 4 Jun19
B 2 Apr19
B 3 May19
B 4 Jun19
B 5 Jul19
B 6 Aug19
B 5 Sep19
B 4 Oct19
C 2 Jan19
C 2 Feb19
C 3 Mar19
C 4 Apr19
C 5 May 19
;
Run;

As per requirement, I will want the result to contain customer A and Customer C
1 ACCEPTED SOLUTION

Accepted Solutions
PeterClemmensen
Tourmaline | Level 20

Try this. 

 

My logic is this. if the rating increases in the last observation by group compared to the second last and the rating in the last obs is > 2. Then I assume that the rating has already been equal to 2 and has been increasing from then.

 

See if it works for you.

 

Data sample;
Input customer $ Rating month $;
Cards;
A 0 Jan19
A 1 Feb19
A 2 Mar19
A 2 Apr19
A 3 May19
A 4 Jun19
B 2 Apr19
B 3 May19
B 4 Jun19
B 5 Jul19
B 6 Aug19
B 5 Sep19
B 4 Oct19
C 2 Jan19
C 2 Feb19
C 3 Mar19
C 4 Apr19
C 5 May19
;

data want(drop = flag);
   do _N_ = 1 by 1 until (last.customer);
      set sample;
      by customer;
      flag = (dif(Rating) = 1 & Rating > 2);
   end;
   
   do _N_ = 1 to _N_;
      set sample;
      if flag then output;
   end;
run;

 

Result:

 

customer  Rating  month 
A         0       Jan19 
A         1       Feb19 
A         2       Mar19 
A         2       Apr19 
A         3       May19 
A         4       Jun19 
C         2       Jan19 
C         2       Feb19 
C         3       Mar19 
C         4       Apr19 
C         5       May19 

 

View solution in original post

11 REPLIES 11
PeterClemmensen
Tourmaline | Level 20

Can you show us a sample of your data please? makes it much easier to provide a usable code answer.

Shradha1
Obsidian | Level 7
Hi! Have uploaded a short table with the question for sample
PeterClemmensen
Tourmaline | Level 20

Please do not post your data as an image. 

 

But.. what do you want the result to look like given this data?

andreas_lds
Jade | Level 19

@Shradha1 wrote:
Hi! Have uploaded a short table with the question for sample

Please post the data as data-step using datalines - so that we have something to work with. Also show the expected result using that dataset.

Shmuel
Garnet | Level 18

Try next code:

 

proc sort data=have; by customer month; run;
/* assumed month is a sas numeric date */

data want;
 set have;
   by customer; 
        retain max_rate out_flag;
        if first.customer then do;
           if rating ge 2 then out_flag=0; else flag=-1;
           max_rate = rating;
        end; 
        else do;
		   if flag ge 0 then and
		      rating ge max_rate then do;
			     out_flag=1;
				 max_rate=rating;
		end; end;
		if last.customer and out_flag ge 0;
run;
              		   
s_lassen
Meteorite | Level 14

If you only want a single record with the customer id for the relevant customers, this should do it:

data want;
  do until(last.customer);
    set sample;
    by customer;
    dif=dif(rating);
    if first.customer then
      wanted=1;
    else if dif<0 then
      wanted=0;
    end;
  if wanted;
  keep customer;
run;

If you want all the records for those customers, here's how:

data want;
  do until(last.customer);
    set sample;
    by customer;
    dif=dif(rating);
    if first.customer then
      wanted=1;
    else if dif<0 then
      wanted=0;
    end;
  do until(last.customer);
    set sample;
    by customer;
    if wanted then 
      output;
    end;
  drop dif wanted;
run;
PeterClemmensen
Tourmaline | Level 20

Try this. 

 

My logic is this. if the rating increases in the last observation by group compared to the second last and the rating in the last obs is > 2. Then I assume that the rating has already been equal to 2 and has been increasing from then.

 

See if it works for you.

 

Data sample;
Input customer $ Rating month $;
Cards;
A 0 Jan19
A 1 Feb19
A 2 Mar19
A 2 Apr19
A 3 May19
A 4 Jun19
B 2 Apr19
B 3 May19
B 4 Jun19
B 5 Jul19
B 6 Aug19
B 5 Sep19
B 4 Oct19
C 2 Jan19
C 2 Feb19
C 3 Mar19
C 4 Apr19
C 5 May19
;

data want(drop = flag);
   do _N_ = 1 by 1 until (last.customer);
      set sample;
      by customer;
      flag = (dif(Rating) = 1 & Rating > 2);
   end;
   
   do _N_ = 1 to _N_;
      set sample;
      if flag then output;
   end;
run;

 

Result:

 

customer  Rating  month 
A         0       Jan19 
A         1       Feb19 
A         2       Mar19 
A         2       Apr19 
A         3       May19 
A         4       Jun19 
C         2       Jan19 
C         2       Feb19 
C         3       Mar19 
C         4       Apr19 
C         5       May19 

 

Shradha1
Obsidian | Level 7
This was exactly what I was looking for. Thanks a lot!
Shradha1
Obsidian | Level 7
Just noticed that this code is missing cases like this:-
customer Rating month
A 0 Jan19
A 1 Feb19
A 2 Mar19
A 3 Apr19
A 3 May19
A 3 Jun19

In this case customer A is being left out while using this code whereas it is wanted.

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!

How to Concatenate Values

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 11 replies
  • 1400 views
  • 2 likes
  • 5 in conversation