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

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;

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
mkeintz
PROC Star

@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.

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------

View solution in original post

6 REPLIES 6
Tom
Super User Tom
Super User

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;

 

 

priscilabaddouh
Fluorite | Level 6

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...

Tom
Super User Tom
Super User

@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.

 

priscilabaddouh
Fluorite | Level 6

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

mkeintz
PROC Star

@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.

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
priscilabaddouh
Fluorite | Level 6
Thank you, I will try it soon. I am still a beginner, so I really appreciate all help.

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
  • 1166 views
  • 2 likes
  • 3 in conversation