Statistical programming, matrix languages, and more

set IML matrix name based on the do loop, how do I do that?

Reply
Frequent Contributor
Posts: 133

set IML matrix name based on the do loop, how do I do that?

  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;

Frequent Contributor
Posts: 130

Re: set IML matrix name based on the do loop, how do I do that?

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 + '=5;' );
  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.

Frequent Contributor
Posts: 130

Re: set IML matrix name based on the do loop, how do I do that?

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.

Frequent Contributor
Posts: 133

Re: set IML matrix name based on the do loop, how do I do that?

I am not following your code,
x = 2 # value(yname[2]);

Can you put out a complete version?

Thanks so much.

Frequent Contributor
Posts: 133

Re: set IML matrix name based on the do loop, how do I do that?

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.

SAS Super FREQ
Posts: 3,406

Re: set IML matrix name based on the do loop, how do I do that?

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.

Frequent Contributor
Posts: 133

Re: set IML matrix name based on the do loop, how do I do that?

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.

Frequent Contributor
Posts: 130

Re: set IML matrix name based on the do loop, how do I do that?

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 , i(k) );
    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, value(y) # k );
    if k = 2 then call valset (y, value(y) + 5 );
    print (value(y));
  end;

SAS Super FREQ
Posts: 3,406

Re: set IML matrix name based on the do loop, how do I do that?

I'd like to help. If you tell us what you are trying to accomplish, it would be easier.

Ask a Question
Discussion stats
  • 8 replies
  • 589 views
  • 0 likes
  • 3 in conversation