BookmarkSubscribeRSS Feed
luciacossaro
Obsidian | Level 7

Hi,

I tried to do a macro program but it does not work. I have a data set with 5  5 sets of  variables such as variableA_1 variableA_2 variableA_3 variableA_4 variableA_5 and another variable "X" that takes values 1, 2, 3, 4 and 5.

I want to create a new variable "want" which will take the value of variable_1 when X = 1, will take the value of variable_2 when X = 2, etc ...

I tried this program but did not work, could someone tell me where I am wrong?

 

%let i=1; 

options mprint ;
%macro test; 
	%do i=1 %to 5 ;
	
	data have ; 
	set have ; 
	%if X = &i. %then %do ; 
		VariableA = VariableA_&i. ; 
		VariableB = VariableB_&i. ; 
		VariableC = VariableC_&i. ;
		VariableD = VariableD_&i. ;
		VariableE = VariableE_&i. ;
		%end ; 
		%else %if NIVEAU_FINAL ne &i. %then %do ; 
		VariableA = VariableA ; 
		VariableB = VariableB ; 
		VariableC = VariableC;
		VariableD = VariableD ;
		VariableE = VariableE ;
		%end ; 
		run ;
	%end ; 
%mend ; 

%test ; 

Thank you so much !

9 REPLIES 9
Astounding
PROC Star

This would normally be done with arrays, not with macro language.  For example:

 

data want;

set have;

array a_list {5} variableA_1 - variableA_5;

array b_list {5} variableB_1 - variableB_5;

array c_list {5} variableC_1 - variableC_5;

array d_list {5} variableD_1 - variableD_5;

array e_list {5} variableE_1 - variableE_5;

do k=1 to 5;

    .........

end;

run;

 

Inside the loop (represented as ........):

 

a_list{k} refers to 1 of the 5 "A" variables, depending on the value of k

b_list{k} refers to 1 of the 5 "B" variables, depending on the value of k

etc.

luciacossaro
Obsidian | Level 7

Thanks you for your answer. 

 

But what is the syntax in the do loop?
Because I put A_list = A_list {k} and I have several error messages. I also added $ after the name of the array before the loop for the list with variable characters.

Far exemple i have this message "Too many array subscripts specified for array A_list" and i do not understand why.

Astounding
PROC Star

The syntax depends on what you want to accomplish.  

 

  • You don't have to copy any of the array elements to new variables.  Just use them, referring to a_list{k} or b_list{k} etc.
  • Yes, you will get error messages if you use a_list in any other way.  SAS is very fussy about that.  Once a_list is the name of an array, it cannot be the name of anything else in that DATA step.  Even this combination of statements would generate an error:

 

array a_list {*} a1-a5;

array a_list {*} a1-a5;

 

Once a_list has been defined, reusing the name (even with no change to the definition) causes an error.

 

So what would you like to calculate here?

Kurt_Bremser
Super User

Since the string X is not equal to any of the numbers 1,2,3,4,5, the macro condition will never be true.

OTOH, the second macro condition will always be true, so you create 5 data steps that do NOTHING (they only run to set the variables to the values they already have).

Keep in mind that the macro preprocessor is a pure text processing engine, and it will not have any knowledge about values or processes within the code it generates. So it does not have access to data step variables x or niveau_final.

 

Add mlogic to your options statement, and look at the log. It should be enlightening.

luciacossaro
Obsidian | Level 7

X is an existing variable in the database and takes the values 1,2,3,4 and 5.
What I need is for the observations where X = 1, VariableB take the value that has VariableB_1, variableC take the value of VariableC_1 etc.
I put the mlogic option and I see that the problem is that for the condition it does not update the value of i to 1,2,3,4,5 but in the 5 executions it is always X = i and then the condition is false. Do you know why SAS does not update the condition so that it is for example X = 1 in the first execution, X = 2 in the second etc?

Astounding
PROC Star

Once the array statements are in place, you can use:

 

a_variable = a_list{X};

b_variable = b_list{X};

 

etc.

Kurt_Bremser
Super User

@luciacossaro wrote:

X is an existing variable in the database and takes the values 1,2,3,4 and 5.


Irrelevant. The macro preprocessor does not see data step variables and their values. It only sees and works with program text.

Tom
Super User Tom
Super User

@luciacossaro wrote:

X is an existing variable in the database and takes the values 1,2,3,4 and 5.
What I need is for the observations where X = 1, VariableB take the value that has VariableB_1, variableC take the value of VariableC_1 etc.
I put the mlogic option and I see that the problem is that for the condition it does not update the value of i to 1,2,3,4,5 but in the 5 executions it is always X = i and then the condition is false. Do you know why SAS does not update the condition so that it is for example X = 1 in the first execution, X = 2 in the second etc?


So if you wanted to use a macro approach (which you shouldn't) then the macro should generate SAS code to test the value X.

%do i=1 to 5 ;
if x=&i then do;
  vara = vara_&i;
  varb = varb_&i;
  ...
end;
%end;

So you would end up with 5 blocks of actual SAS code that the macro %DO loop generated.

 

But for this type of problem there is no need to resort to code generation. The SAS language already has features to do this type of operation. Define an array for each of your variable groups and use the value of X as the index into the array.

array _vara vara_1 - vara_5 ;
array _varb varb_1 - varb_5;
...
vara = _vara(x);
varb = _varb(x);
...
Tom
Super User Tom
Super User

This %IF condition can NEVER be true.

%if X = &i. %then %do ; 

The macro variable I will have a value of 1 or 2 or .... or 5.  Which can never be the same as an uppercase letter X.

 

You appear to be confusing macro code and regular code. The use of macro code is to generate regular code. Once the macro processor has generated a complete step of SAS code then SAS will take that generated code and run it.

 

You need to provide example input and required output because at this point it is not clear what you are trying to do.

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

Register Now

Creating Custom Steps in SAS Studio

Check out this tutorial series to learn how to build your own steps in SAS Studio.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 9 replies
  • 1860 views
  • 2 likes
  • 4 in conversation