BookmarkSubscribeRSS Feed
lucky66
Calcite | Level 5

Hi all,

 

I want to do a variable group by a macro variable, however, the values are wrong.

 

The macro I created is displayed below:

%macro refigrp(refi,refigrp);

if &refi.<=0 then &refigrp.='a.<=0';

else if 0<&refi.<=0.1 then &refigrp.="b.0<-0.1";

else if 0.1<&refi.<=0.2 then &refigrp.="c.0.1<-0.2";

else if 0.2<&refi.<=0.3 then &refigrp.="d.0.2<-0.3";

else if 0.3< &refi.<=0.4 then &refigrp.='e.0.3<-0.4';

else if 0.4<&refi.<=0.5 then &refigrp.='f.0.4<-0.5';

else if 0.5<&refi.<=0.6 then &refigrp.='g.0.5<-0.6';

else if 0.6<&refi.<=0.7 then &refigrp.='h.0.6<-0.7';

else if 0.7<&refi.<=0.8 then &refigrp.='i.0.7<-0.8';

else if 0.8<&refi.<=0.9 then &refigrp.='j.0.8<-0.9';

else if 0.9<&refi.<=1.0 then &refigrp.='k.0.9<-1.0';

else if 1.0<&refi.<=1.1 then &refigrp.='l.1.0<-1.1';

else if 1.1<&refi.<=1.2 then &refigrp.='m.1.1<-1.2';

else if 1.2<&refi.<=1.3 then &refigrp.='n.1.2<-1.3';

else if 1.3<&refi.<=1.4 then &refigrp.='o.1.3<-1.4';

else if 1.4<&refi.<=1.5 then &refigrp.='p.1.4<-1.5';

else if 1.5<&refi.<=1.6 then &refigrp.='q.1.5<-1.6';

else if 1.6<&refi.<=2.0 then &refigrp.='r.1.6<-2.0';

else &refigrp.='s.>2.0';

%mend;

 

what I wanted like this:

refiincentivedifInc100bps refigrp100 should like this
0.321499985 0.3<-0.4
0.355833238 0.3<-0.4
0.227666729 0.2<-0.3
0.465999978 0.4<-0.5
0.389166722 0.3<-0.4
0.477333317 0.4<-0.5
0.939166651 0.9<-1.0
0.971999997 0.9<-1.0
0.537166653 0.5<-0.6

 

However, what I got is shown below:

refiincentivedifInc100bps refigrp100
0.321499985 e.0.3
0.355833238 e.0.3
0.227666729 d.0.2
0.465999978 f.0.4
0.389166722 e.0.3
0.477333317 f.0.4
0.939166651 k.0.9
0.971999997 k.0.9
0.537166653 g.0.5

I tried using %SYSEVALF in the above macro, e.g. if  0.1<%SYSEVALF(&refi.)<0.2 then... it does not work,either.

 

Anyone knows how to fix the code that it works?

6 REPLIES 6
Tom
Super User Tom
Super User

Your macro looks fine, but there is nothing in it to define the length of the new variable. Either add a length statement in the code the macro generates or just define the new variable before you call the macro.

 

data want ;
  set have ;
  length refigrp100 $10 ;
  %refigrp(refiincentivedifInc100bps,refigrp100)
run;
Reeza
Super User

Just a quick comment that this is better accomplished with a format rather than a macro. 

 

If you just want to apply format then you don't even need the letters since it will sort correctly. 

Also your want doesn't show the letters that are clearly in your code (a/b/c). 

Reeza
Super User

You could also dynamically use a formula for this:

 

data have;
input num;
range = catx("->", round(floor(num*10)/10, 0.1), round(ceil(num*10)/10, 0.1));
cards;
0.321499985
0.355833238
0.227666729
0.465999978
0.389166722
0.477333317
0.939166651
0.971999997
0.537166653
;
run;
Kurt_Bremser
Super User

The task is much better handled with a user-defined format than with a long if-then-else-if chain.

Keep in mind that comparison operations are the most CPU-consuming operations (on machine code level) and can therefore cause unnecessary bad performance.

 

In your specific case, the length of the variable named by &refigrp is defined when the data step compiler encounters the first assignment oepration ('a.<=0') and therefore assigns it a length of 5, which is not sufficent to hold the longer values that appear later in the code.

That is why you need an explicit length statement.

It is always good practice to specify length for a newly created character variable, unless you do that implicitly by assigning a format or inputting with a format.

lucky66
Calcite | Level 5

Thanks, adding length statement in the data before calling the macro works.

I have to define variable group in this way, as those categorical variables will be predicators in a model. Formatting cannot work.

 

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 6 replies
  • 1052 views
  • 2 likes
  • 4 in conversation