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

Hi.. I have a dataset that organized by customer level and has a variable called 'balance'.  I want to check, for each customer, if their balance has ever gone above 500; if it has, how many times.

 

I thought about using array, but not sure how I can use it in this case. Does anyone have any suggestion?

 

customerdatebalance
A201804200
A201805600
A201806450
A2018071000
B2017120
B20180150
B201802100

 

customerdatebalanceever500over500
A20180420000
A20180560011
A20180645011
A201807100012
B201712000
B2018015000
B20180210000
1 ACCEPTED SOLUTION

Accepted Solutions
Kurt_Bremser
Super User

@newboy1218 wrote:

And how can I retain the value of ever500 too?


Ups, missed that one.

data have;
input customer $ date $ balance;
datalines;
A 201804 200
A 201805 600
A 201806 450
A 201807 1000
B 201712 0
B 201801 50
B 201802 100
;

data want;
set have;
by customer;
retain ever500 over500;
if first.customer
then do;
  ever500 = 0;
  over500 = 0;
end;
if balance > 500 then ever500 = 1;
over500 + (balance > 500);
run;

proc print data=want noobs;
run;

Result now looks exactly like what you want:

customer     date     balance    ever500    over500

   A        201804       200        0          0   
   A        201805       600        1          1   
   A        201806       450        1          1   
   A        201807      1000        1          2   
   B        201712         0        0          0   
   B        201801        50        0          0   
   B        201802       100        0          0   

Note how I presented the example data in a data step with datalines, so that the dataset can be created with a simple copy/paste and run. Please do so yourself in the future.

View solution in original post

8 REPLIES 8
newboy1218
Quartz | Level 8
Thank you. So do I need to sort the dataset by customer and date first?
newboy1218
Quartz | Level 8

And how can I retain the value of ever500 too?

Kurt_Bremser
Super User

@newboy1218 wrote:

And how can I retain the value of ever500 too?


Ups, missed that one.

data have;
input customer $ date $ balance;
datalines;
A 201804 200
A 201805 600
A 201806 450
A 201807 1000
B 201712 0
B 201801 50
B 201802 100
;

data want;
set have;
by customer;
retain ever500 over500;
if first.customer
then do;
  ever500 = 0;
  over500 = 0;
end;
if balance > 500 then ever500 = 1;
over500 + (balance > 500);
run;

proc print data=want noobs;
run;

Result now looks exactly like what you want:

customer     date     balance    ever500    over500

   A        201804       200        0          0   
   A        201805       600        1          1   
   A        201806       450        1          1   
   A        201807      1000        1          2   
   B        201712         0        0          0   
   B        201801        50        0          0   
   B        201802       100        0          0   

Note how I presented the example data in a data step with datalines, so that the dataset can be created with a simple copy/paste and run. Please do so yourself in the future.

newboy1218
Quartz | Level 8
Amazing Thank you!
hashman
Ammonite | Level 13

@newboy1218:

The way you want your output data set shaped, you need a bit of logic to ensure that:

  1. Before BALANCE becomes >500, EVER500=0
  2. Once BALANCE>500, EVER500=1 propagates though the end of the BY group
  3. OVER500 is incremented only on the records with BALANCE>500

For example (assuming that HAVE is sorted by customer):

 

data have ;                                 
  input customer :$1. date balance ;        
  cards ;                                   
A  201804   200                             
A  201805   600                             
A  201806   450                             
A  201807  1000                             
B  201712     0                             
B  201801    50                             
B  201802   100                             
run ;                                       
                                            
data want ;                                 
  do until (last.customer) ;                
    set have ;                              
    by customer ;                           
    if not ever500 then ever500 = 0 ;       
    if balance > 500 then ever500 = 1 ;     
    over500 = sum (over500, balance > 500) ;
    output ;                                
  end ;                                     
run ;                                       

It helps that the DATA step auto-resets EVER500 and OVER500 to missing values at the top of the implied loop, i.e. before the DO loop starts iterating.

 

Kind regards

Paul D. 

 

 

newboy1218
Quartz | Level 8
Thank you so much!
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
  • 8 replies
  • 4058 views
  • 2 likes
  • 3 in conversation