I want to following code’s result to be y_1 = 5, y_2=5, y_3
=5, it didn’t give me the matrix name what I wanted. It always gives me: k_3
=5, k_3 = 5, k_3=5
I want the matrix name to be based on the do loop k as post
fix. How do I do that?
proc iml;
do k = 1 to 3;
call symputx("run_k", k);
mc_k = num(symget("run_k"));
y_&mc_k. = 5;
print y_&mc_k.;
end;
quit;
The macro variable &mc_k will be resolved just once at compile time, so I presume it had the value 3 before you ran the code above (the macro variable here is not the same as the matrix mc_k). There is no need to resort to the SAS macro language as you can use call execute to get what you want. A line of IML code can be constructed in a character matrix and then you can have IML execute it, but note that this will only work from inside a module.
start yarray;
yname = 'y_1' : 'y_3';
do k = 1 to 3;
call execute( yname
end;
print y_1 y_2 y_3;
finish;
run yarray;
In a real application the code quickly becomes difficult to read, since every time you refer to y_k, there will be a complicated call execute statement. In the case where all the matrices are the same size, then it may be better to store them as sub-matrices of a single large matrix.
I only wish there was a better way to have an array of matrices.
Just realised that once the matrices are defined as above, it's possible to refer to them using the value function. So
x = 2 # value(yname[2]);
would set x to 10.
I am not following your code,
x = 2 # value(yname[2]);
Can you put out a complete version?
Thanks so much.
what is the generic way to automatically rename matrix name with i as post fix?
Personally I tried to avoid using call execute statement, it looks cumbersome to me, especially when code gets bigger and intertwined with other logic.
If you really want to go down this route, see this article on indirect assignment.
However, actually requiring this feature is very rare. Why don't you share what you are trying to accomplish? There is probably a simpler approach. For your example, the conventional approach would be to form the vector
y = {5,5,5};
so that y[1] = y[2] = y[3] = 5.
assigning the matrix to the same matrix name in a loop is very inconvenient, especially in debug stage.
For instance, in the 3 loops, 2nd looping has some calculation needs special treatment, but the matrix name is the same, how am I supposed to manipuate the 2nd matrix? It is very cumbersome to do matrix manipulation without the valid reference.
You can access and manipulate each matrix independently. Rick's point is that doing everything indirectly is going to look ugly, as I imagine the actual problem you are trying to solve is a lot more complicated than the three 5s, and you will end up with a program full of VALSET and VALUE which will be difficult for others to understand. For example:
/* create an 'array' of 3 identity matrices of varying size */
y = 'y_1' : 'y_3';
do k = 1 to 3;
call valset( y
print (value(y
end;
/* scale each identity matrix in the array by its side,
for the 2nd matrix also add 5 to all elements */
do k = 1 to 3;
call valset( y
if k = 2 then call valset (y
print (value(y
end;
I'd like to help. If you tell us what you are trying to accomplish, it would be easier.
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 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.