DATA Step, Macro, Functions and more

Using arrays in a macro

Accepted Solution Solved
Reply
Occasional Contributor
Posts: 11
Accepted Solution

Using arrays in a macro

[ Edited ]

I am trying to run a macro, but I am getting this message: "Array subscript out of range at line 12 column 31". What am I doing wrong? I am attaching the program, and the data to this post. I have already checked if the number of variables match my array and do definitions. 

 

This is the part of the macro that I am having problems (please see files for the entire macro, and note that this section is inside of a macro).

 

array change {11}  Adjusted_gross_income_category Number_of_returns Adjusted_gross_income
Wages_Number_of_returns Wages_Amount UE_comp_number_of_returns UE_comp_amount
SS_number_benefits_AGI SS_amount_benefits_AGI Taxable_inc_number_returns Taxable_amount
;
%do i = 1 %to 11;
  %if change{i} = "**" %then change{i}=" ";
%end;
array numeric_change {10} Number_of_returns Adjusted_gross_income Wages_Number_of_returns
Wages_Amount UE_comp_number_of_returns UE_comp_amount SS_number_benefits_AGI SS_amount_benefits_AGI
Taxable_inc_number_returns Taxable_amount
;
array new_numeric {10} Number_of_returns_2 Adjusted_gross_income_2 Wages_Number_of_returns_2
Wages_Amount_2 UE_comp_number_of_returns_2 UE_comp_amount_2 SS_number_benefits_AGI_2
SS_amount_benefits_AGI_2 Taxable_inc_number_returns_2 Taxable_amount_2
;
%do i = 1 %to 10;
  new_numeric{i}=input(numeric_change{i},comma12.);
%end;

 

 

Attachment

Accepted Solutions
Solution
‎02-21-2018 06:14 PM
Trusted Advisor
Posts: 1,345

Re: Using arrays in a macro

Posted in reply to priscilabaddouh

@priscilabaddouh

 

@Tom was giving you the right advice.  But I believe the error message you got arose from this code:

 
   %do i = 1 %to 10;
     new_numeric{i}=input(numeric_change{i},comma12.);
   %end;

which executes the statement

  new_numeric{i}=input(numeric_change{i},comma12.);

ten times, without changing the value of i.

 

As a result, the variable i may have a missing value, or some value other than the natural numbers 1 through 10.  Hence the "array index out of range" message.

 

Now the %do I=1 %to 10 statement changes the macrovar i (not the sas variable i).  In that case, the macrovar would have to be referred to with an ampersand, as in

   new_numeric{&i}=input(numeric_change{&i},comma12.);

 

which in turn would generate these ten lines of sas code:

      new_numeric{1}=input(numeric_change{1},comma12.);

      new_numeric{2}=input(numeric_change{2},comma12.);

         ....

      new_numeric{9}=input(numeric_change{9},comma12.);

      new_numeric{10}=input(numeric_change{10},comma12.);

 

But as @Tom points out, that's just not good coding (imagine if the loop were 1 to 200).  Instead change both of your loops from

  %do i=1 %to ....

to

   do i=1 to ...

and of course change the corresponding %end to end.

 

The benefit is you will not be populating your program with excessives lines of code.

View solution in original post


All Replies
Super User
Super User
Posts: 8,121

Re: Using arrays in a macro

[ Edited ]
Posted in reply to priscilabaddouh

I have no idea what the overall problems are but the mistake in the snippet you posted was using macro code where you needed to use data step code.  For example this statement:

  %if change{i} = "**" %then change{i}=" ";

The condition in the %IF statement is always false since the letter c does not equal a double quote character.

 

What you wanted was this data step code that could run for each iteration of the data step:

do i = 1 to 11;
  if change{i} = "**" then change{i}=" ";
end;

 

 

Occasional Contributor
Posts: 11

Re: Using arrays in a macro

Hi Tom. Thank you for answering me! I copied and pasted only part of the code, and then uploaded the entire code (the entire macro)  as one of my uploaded files. Are you able to see it? So actually, the macro notation is correct, since it is inside of a macro. But I have not figured out what is the real issue yet...

Super User
Super User
Posts: 8,121

Re: Using arrays in a macro

[ Edited ]
Posted in reply to priscilabaddouh

priscilabaddouh wrote:

Hi Tom. Thank you for answering me! I copied and pasted only part of the code, and then uploaded the entire code (the entire macro)  as one of my uploaded files. Are you able to see it? So actually, the macro notation is correct, since it is inside of a macro. But I have not figured out what is the real issue yet...


This loop that I pointed to before is not doing anything at all.

%do i = 1 %to 11;
  %if change{i} = "**" %then change{i}=" ";
%end;

So the first time through the loop the macro variable I is set to 1. Then the %IF statement compares the string 'change{i}' to the string '"**"' and finds that they are different so SAS statement 'change{i}=" "' is not generated.   The same thing happens eleven times since nothing inside the loop is referencing the the macro variable I.

 

In general macro code is used to generate SAS code. So make sure you are generating valid SAS code.  Don't change your SAS IF statements into macro %IF statement just because you are using a macro to generate the SAS code. You only need to use %IF if you want to conditionally generate some code.  The code your macro generates still needs to be valid SAS code.

 

Occasional Contributor
Posts: 11

Re: Using arrays in a macro

Now I understand what you mean, Tom. Thank you so much! I have just started learning macro by myself. So this is really helpful! 

Solution
‎02-21-2018 06:14 PM
Trusted Advisor
Posts: 1,345

Re: Using arrays in a macro

Posted in reply to priscilabaddouh

@priscilabaddouh

 

@Tom was giving you the right advice.  But I believe the error message you got arose from this code:

 
   %do i = 1 %to 10;
     new_numeric{i}=input(numeric_change{i},comma12.);
   %end;

which executes the statement

  new_numeric{i}=input(numeric_change{i},comma12.);

ten times, without changing the value of i.

 

As a result, the variable i may have a missing value, or some value other than the natural numbers 1 through 10.  Hence the "array index out of range" message.

 

Now the %do I=1 %to 10 statement changes the macrovar i (not the sas variable i).  In that case, the macrovar would have to be referred to with an ampersand, as in

   new_numeric{&i}=input(numeric_change{&i},comma12.);

 

which in turn would generate these ten lines of sas code:

      new_numeric{1}=input(numeric_change{1},comma12.);

      new_numeric{2}=input(numeric_change{2},comma12.);

         ....

      new_numeric{9}=input(numeric_change{9},comma12.);

      new_numeric{10}=input(numeric_change{10},comma12.);

 

But as @Tom points out, that's just not good coding (imagine if the loop were 1 to 200).  Instead change both of your loops from

  %do i=1 %to ....

to

   do i=1 to ...

and of course change the corresponding %end to end.

 

The benefit is you will not be populating your program with excessives lines of code.

Occasional Contributor
Posts: 11

Re: Using arrays in a macro

Thank you, I will try it soon. I am still a beginner, so I really appreciate all help.
☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats
  • 6 replies
  • 213 views
  • 2 likes
  • 3 in conversation