Hello,
I want to use a list of values to determine what matrix operations that need to be performed.
I also need to create a sequence of new matrices based on these operation.
I tried to use macro and proc iml to achieve this, but statement x[%eval(&j.+1)] = 1 did not give expected results. It seems it is always false regardless if the value in x[position]. Can someone please explain to me how the syntax should be? Thanks.
x = {0 1 0 1 0 0};
%do i = 0 %to 5;
%if x[%eval(&i.+1)] = 1 %then
%do;
m%eval(&i.+1) = m&i. * another_matrix_&i.;
%end;
%else
%do;
m%eval(&i.+1) = m0;
%end;
%end;
You do not show your entire program, so it is difficult to know what you are trying to accomplish. Why are you creating these matrices m1, m2,.. m6? Are they all the same size? Do you only need them one at a time, or are you going to require them all at the same time to perform some computation?
In general, because SAS/IML is a complete programming language, it is rarely necessary to use macro loops in IML programs. Regarding the interaction between the macro language and SAS/IML, I encourage you to read "Macros and loops in the SAS/IML language"
for some tips and insights.
My advice: If the matrices are the same size, use an array of matrices is to pack them into rows of a big matrix. The alternative (which also works if the matrice are different sizes) is to create a list of matrices. Neither method requires using macro loops.
You do not show your entire program, so it is difficult to know what you are trying to accomplish. Why are you creating these matrices m1, m2,.. m6? Are they all the same size? Do you only need them one at a time, or are you going to require them all at the same time to perform some computation?
In general, because SAS/IML is a complete programming language, it is rarely necessary to use macro loops in IML programs. Regarding the interaction between the macro language and SAS/IML, I encourage you to read "Macros and loops in the SAS/IML language"
for some tips and insights.
My advice: If the matrices are the same size, use an array of matrices is to pack them into rows of a big matrix. The alternative (which also works if the matrice are different sizes) is to create a list of matrices. Neither method requires using macro loops.
One mistake is that the macro processor is not needed here, and indeed produces incorrect results. If you use a PROC IML DO loop and no macro %IF statements, the code works fine.
This brings up an important concept: before writing any macros, you need to have code that works without macros. if you can't get the code to work without macros, then it will never work with macros.
Why doesn't
%if x[%eval(&i.+1)] = 1 %then %do;
work as you think it should? Because in an %IF statement, the macro processor is comparing text strings. When &i is 1, then x[%eval(&i+1)] is the text string x[2] which is not equal to the text string 1. The macro processor does not use the matrix value of x[2] here.
However if you use the IML IF command
if x[&i+1]=1 then do;
then the IML language processor knows that the value of matrix x in position 2 is indeed equal to 1.
Again, you need to produce working code without macros before you try to write macros. And indeed follow the advice from @Rick_SAS which would let you avoid using macros within PROC IML in most situations.
@SAS_Dev wrote:
Thank you for the feedback.
If without using the macro %do statement, is there a way to create a series of matrix by the loop counter?
@Rick_SAS has explained how to do this already in this thread, and linked to a blog post (or maybe several blog posts) on it as well.
Update/correction: my post earlier implied you should use a IML DO loop instead of a macro %DO loop, which is incorrect. A macro %DO loop could work here if you use the IML IF statement and not the macro %IF statement, but again going back to the comments from Rick, it still isn't needed. Following RIck's suggestion avoids all this unpleasant and difficult switching between languages (IML and macro language) and getting them to interact correctly (which isn't easy to do and certainly should be avoided by beginners, and also should be avoided by experienced programmers like me unless there is no other possibility).
There are many ways in SAS/IML to address the issues you discuss. If you state what you are trying to accomplish and provide an example, I am sure someone will be able to help you.
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.
Learn how to run multiple linear regression models with and without interactions, presented by SAS user Alex Chaplin.
Find more tutorials on the SAS Users YouTube channel.