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;
@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.
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;
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...
@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.
Now I understand what you mean, Tom. Thank you so much! I have just started learning macro by myself. So this is really helpful!
@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.
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!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.
Select SAS Training centers are offering in-person courses. View upcoming courses for: