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

Hey all,

Does someone see why my values don't update by each iteration i ?
I want values update in each iteration i and throughout my statements.

 

data need;
	do i= 1 to 5;
		min= 1; max= 10; val_m1= 5; val_m2= 7;
		m1= 3;
		m2= 5;
		min= m1; m1= m2;	 		            /*here 2 updates*/
 		val_m1= val_m2;  		                    /*update*/
		m2= (m2 + max) / 2; 		            /*update*/
		call execute('%mymacro('||m2||')'); 
 /*These macro have to use the last m2 update value */
		val_m2= &val_m2; 	
 /*A global macro var named val_m2 is created in %mymacro*/
	
       output;
       end;
run;

 

Mymacro like this one:

 

%macro mymacro (m2);
   %glabal val_m2;                      /*name can be changed if optimal*/
   ...
   ...
%mend;

 

Best Regards

1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

Kurt mentioned the right principle ... there is absolutely nothing about your code that changes &USED within this statement:

 

val2 = &used;

 

Its value gets changed by this code, but the statements within the DATA step depend on the initial value of &USED before the DATA step begins.  You could work around this by replacing that statement with:

 

val2 = input(symget('used'), 12.);

 

It's untested but worth a try with one just one precaution.  I hope this is just a test to see how macro language works.  If this were a real application, there would likely be many better ways to handle the situation.

View solution in original post

11 REPLIES 11
Kurt_Bremser
Super User

In this line

val_m2= &val_m2;

the macro variable &val_m2 is resolved by the macro PREprocessor before the data step is compiled and run.

 

I strongly suggest that you pack the logic contained in the macro in a user defined function, or rewrite the macro so that you can use it to create standard code for use in the data step itself (without call execute).

 

For further help, post the code of your macro %mymacro.

DoumbiaS
Quartz | Level 8

" the macro variable &val_m2 is resolved by the macro PREprocessor before the data step is compiled and run "

 

You 're right, thanks.

 

But i reformulated the problem for simplicity.

%macro mymacro(var);
%Global used;
	%let used= %sysevalf(&var +1);
%Mend;

data need;
do i= 1 to 3;
	if i= 1 then do;
		x= 2;
		y= 3;
		call execute('%mymacro('||x||')');
		val2= &used;           
	end;
	else do;
		x= x+2;
		y= (y+2)/2;
		call execute('%mymacro('||x||')');
		val2= &used;
	end;
output;
end;
run;

 

 

Data want:

 

 i     x    y         val2

1    2    3          3
2    4    2.5       5
3    6    2.25     7
Astounding
PROC Star

Kurt mentioned the right principle ... there is absolutely nothing about your code that changes &USED within this statement:

 

val2 = &used;

 

Its value gets changed by this code, but the statements within the DATA step depend on the initial value of &USED before the DATA step begins.  You could work around this by replacing that statement with:

 

val2 = input(symget('used'), 12.);

 

It's untested but worth a try with one just one precaution.  I hope this is just a test to see how macro language works.  If this were a real application, there would likely be many better ways to handle the situation.

Kurt_Bremser
Super User

Still the same mistake. &used will be resolved BEFORE!! the macro calls from the call execute will create the macro variable.

If you just want to build an increment, macro programming is NOT NEEDED AT ALL.

 

DoumbiaS
Quartz | Level 8

i knew very well that the macro reference were resolved first. 

Thanks so much to all !

 

Regards  

DoumbiaS
Quartz | Level 8

What about te informat 12. applied to the numeric variable val2 ?

Could the number of digit in my global macro var used be an issue ?

Such it doesn't work with my initial data.

 

Regards

DoumbiaS
Quartz | Level 8

For example this one fails do execute:

:

data need4;
do i= 1 to 3;
	if i= 1 then do;
		x= 22222222222;
		y= 33333333333;
		val_x= 11111111111;
		call execute('%mymacro('||x||')');
		val_y = input(symget('used'), 12.); 
	end;
	else do;
		x= x+2;
		y= (y+2)/2;
		val_x= val_y; 
		call execute('%mymacro('||x||')');
		val_y = input(symget('used'), 12.);
	end;
output;
end;
run;

run;
Astounding
PROC Star

When I run your code, it works.  What failed to execute?

 

Yes, the informat could be a problem.  But not for 11-digit integers.  There might be an issue with different formulas if they generate decimal fractions.  But the code that you posted should run without incident.

DoumbiaS
Quartz | Level 8

True. It may be because of my own operations.
Also, in my elso do: call execute don't use my last x value. Any thoughts ?

 

Regards

Astounding
PROC Star

Here are the results I got:

 

Obs i  x            y             val_x          val_y

 

1   1  22222222222 33333333333.0 11111111111 22222222223

2   2  22222222224 16666666667.5 22222222223 22222222225

3   3  22222222226 8333333334.8  22222222225 22222222227

 

Did you get the same?  The results are short enough that you should be able to post them and explain how they are different than what you expect.

 

 

 

DoumbiaS
Quartz | Level 8

True. My problem is from my original own macro i think.

Regards

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
  • 11 replies
  • 1120 views
  • 5 likes
  • 3 in conversation