BookmarkSubscribeRSS Feed
George3
Obsidian | Level 7

Hello Everyone, 

 

I have a bit of an issue with a macro.  The macro uses criterion methods to find the properly fitting model.  With this, it is necessary to run multiple models and compare the best fit.  As I have worked out the number of models that I would have to run for my project, the number is rather large.  The script below is the call for the macro.  The model command is what has to be changed with each new run. In the present model, it is 1 2 the next model would be 1 3.  To me this seems to be a prime candidate for a nested do loops.  

 

%ttm (data = prac,

time = time; 
dv = marijuana,

iv = sensation 
model = 1 2 
);

 

I have set my do loops up as follows:   

 

do I = 1 to 5; 

do j = 1 to 5; 

 

%ttm (data = prac,

time = time; 
dv = marijuana,

iv = sensation 
model = I j
);

 

end; 

end; 

drop I j; 

 

The real issue here is that the model command in the macro is reading the I and j as letters and not as place holders for the numbers the do loops are creating.  To complicate things, I did not write the original macro and am only using it. 

 

I tested the do loops outside of this environment and they are producing the desired numbers.  Further, other pieces of my programs are working wonderfully using the numbers the do loops are generating.  How would I get the macro to recognize the numbers the do loops are generating rather than it recognizing the I and j as letters?  I would prefer not to run, literally, 200 models singularly, but I would prefer to be efficient and accurate by using a loop.  

 

Any suggestions are welcomed.  Thank you

George 

7 REPLIES 7
Tom
Super User Tom
Super User

Is the macro you are calling only generating part of a single data step?  If not then it cannot be called in the middle of DEFINING a data step.

Do you want to make a macro and %DO loops?

%macro call_many;
%local i j ;
%do I = 1 %to 5; 
  %do j = 1 %to 5; 

%ttm 
(data = prac
,time = time
,dv = marijuana
,iv = sensation 
,model = &i &j
);

  %end;
%end;
%mend;
%call_many;
George3
Obsidian | Level 7

Hello Tom, 

This is wonderful, but I have a concern.  This is working but I need some information about this.  To test the method, I made an alteration to the following: 

%do I = 1 %to 2;

%do j = 1 %to 2;

 

I was under the impression that values would be bound between 1 and 2. When it was run, my first run was 1 1 but my second run was 3 2. It seems to me the 3 2 would be out of bounds. Help me understand how to control the numbers?

 

George

Tom
Super User Tom
Super User

Most likely the macro you are calling is using the macro variable I and J, and unlike the little example macro I posted they did NOT make the macro variable LOCAL to the macro. So they modified your macro variable's values.  

 

But you can just change the %DO loops to use other macro variable names that do not conflict.  The names used for the macro variables don't matter.

 

If this is a macro that you control you should fix that mistake.  Your macros need to learn how to play well with others.

https://www.goodreads.com/work/quotes/2399046-all-i-really-need-to-know-i-learned-in-kindergarten

Reeza
Super User
It's possible the external macro is using the same variables and incrementing i, because those are commonly used macro variables.
George3
Obsidian | Level 7

Hello All, 

The naming conventions were the problem.  I changed them to what follows: 

 

%local a b ;
%do a = 1 %to 2;
  %do b = 1 %to 2;

 

In the model statement, it reads: 

model &a &b; 

 

The system is spectacularly controlled now as expected.  Thank you both for your time and suggestions.  This is a tremendous help. 

Reeza
Super User

Or use CALL EXECUTE within a data step or a macro loop?

What do you mean by external macro?

 

 

Here are some references that may be helpful. 
Tutorial on converting a working program to a macro - illustrated for call execute - see last portion

This method is pretty robust and helps prevent errors and makes it much easier to debug your code. Obviously biased, because I wrote it 🙂 https://github.com/statgeek/SAS-Tutorials/blob/master/Turning%20a%20program%20into%20a%20macro.md

Examples of common macro usage - common examples of loops

https://communities.sas.com/t5/SAS-Communities-Library/SAS-9-4-Macro-Language-Reference-Has-a-New-Ap...

 

https://blogs.sas.com/content/iml/2017/02/13/run-1000-regressions.html

 


@George3 wrote:

Hello Everyone, 

 

I have a bit of an issue with a macro.  The macro uses criterion methods to find the properly fitting model.  With this, it is necessary to run multiple models and compare the best fit.  As I have worked out the number of models that I would have to run for my project, the number is rather large.  The script below is the call for the macro.  The model command is what has to be changed with each new run. In the present model, it is 1 2 the next model would be 1 3.  To me this seems to be a prime candidate for a nested do loops.  

 

%ttm (data = prac,

time = time; 
dv = marijuana,

iv = sensation 
model = 1 2 
);

 

I have set my do loops up as follows:   

 

do I = 1 to 5; 

do j = 1 to 5; 

 

%ttm (data = prac,

time = time; 
dv = marijuana,

iv = sensation 
model = I j
);

 

end; 

end; 

drop I j; 

 

The real issue here is that the model command in the macro is reading the I and j as letters and not as place holders for the numbers the do loops are creating.  To complicate things, I did not write the original macro and am only using it. 

 

I tested the do loops outside of this environment and they are producing the desired numbers.  Further, other pieces of my programs are working wonderfully using the numbers the do loops are generating.  How would I get the macro to recognize the numbers the do loops are generating rather than it recognizing the I and j as letters?  I would prefer not to run, literally, 200 models singularly, but I would prefer to be efficient and accurate by using a loop.  

 

Any suggestions are welcomed.  Thank you

George 


 

George3
Obsidian | Level 7

I will give these a read.  

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

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
  • 7 replies
  • 1001 views
  • 0 likes
  • 3 in conversation