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

HI, I'm trying to use sas macro to create a dynamic variable name. Below is the snippet of my code:

 

%macro test123;
%do i= 0 %to 76;
if ((Fdevyr - Flye) * 4 + int((Fdevm - 1) / 3) - int((FM - 1) / 3)) = &i. then do;
if component = 'Counts' then Amount_0&i. = count;
end;
%end;
%mend test123;

 

this code creates a new Variable - Amount_00, Amount_01..upto Amount_76.and so on but instead I would like to create the variable names as Amount_01,Amount_02...Amount_77 using the above code. 

I have tried using Amount_0&i+1 but I think that's not a valid way of using it.

I have tried %let j= &i.+1 inside my Do Loop but I think we cannot have another macro variable inside a macro.

I'm a beginner to SAS and any suggestions are much appreciated. Thank you

1 ACCEPTED SOLUTION

Accepted Solutions
Patrick
Opal | Level 21

Something like below should do what you want.

%macro test123;
  %do i= 1 %to 77;
    %if &i>1 %then else;
    if ((Fdevyr - Flye) * 4 + int((Fdevm - 1) / 3) - int((FM - 1) / 3)) = %eval(&i.-1) then
      do;
        if component = 'Counts' then
          Amount_0&i. = count;
      end;
  %end;
%mend test123;

View solution in original post

6 REPLIES 6
novinosrin
Tourmaline | Level 20

I am failing to understand why you would want to loop from 0 to 76 when you apparently want var names suffixes from 1 to 77?

 

If I were to assume you want a leading zero for values that are single digit numbers, you could address that with a Z format to standardize that, i.e 

 

/*First Check the values in the log to see if this is what you are after*/
%macro test123;
%do i= 1 %to 77;
%put %sysfunc(putn(&i,z2.));
%end;
%mend test123;

/*If the above is what are after then plug that*/

%macro test123;
%do i= 1 %to 77;
if ((Fdevyr - Flye) * 4 + int((Fdevm - 1) / 3) - int((FM - 1) / 3)) = &i. then do;
if component = 'Counts' then Amount_%sysfunc(putn(&i,z2.)) = count;
end;
%end;
%mend test123;
Tom
Super User Tom
Super User

How are you using that code that macro generates? 

Why is the macro any better than just defining an ARRAY in the data step that is using that code?

Patrick
Opal | Level 21

Something like below should do what you want.

%macro test123;
  %do i= 1 %to 77;
    %if &i>1 %then else;
    if ((Fdevyr - Flye) * 4 + int((Fdevm - 1) / 3) - int((FM - 1) / 3)) = %eval(&i.-1) then
      do;
        if component = 'Counts' then
          Amount_0&i. = count;
      end;
  %end;
%mend test123;
carl01
Calcite | Level 5

Thanks Patrick

Patrick
Opal | Level 21

@carl01 wrote:

Thanks Patrick


ehhmm... .then may-be you should mark my answer as the solution....
From a coding perspective using a SAS datastep array instead of macro coding is "better".

RichardDeVen
Barite | Level 11

I'm a beginner to SAS

That is a good justification for not jumping into Macro.  There is huge utility in the DATA Step language without a need for any macro.

 

Far less confusing would be to use a variable based array to create the variable names amount_00-amount_76.  Your complex formula would compute the index for assignment.

 

data want;

  array amts amount00-amount76;

  index = ((Fdevyr - Flye) * 4 + int((Fdevm - 1) / 3) - int((FM - 1) / 3));
  if component = 'Counts' then amts(index) = count;

run;

 

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!
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
  • 724 views
  • 3 likes
  • 5 in conversation