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
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;
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
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
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.
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
I will give these a read.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.