1
votes

Within proc IML of the SAS system from within a user-defined module I want to be able to access the data in a vector by taking as an argument the name of the vector.

For example in the code below the module called "test" builds the two strings "x_vec1" and "x_vec2" but does not print the contents of these two vectors, but rather prints their names (I think submit blocks produce the same results).

This concept is very easily accomplished using macros by calling IML within macros, but I want to do it purely in IML to keep the code "clean". Whilst IML is brilliant for statistical work I need more than this - I need to keep my code short by having an analogous concept as the macro variable which can be resolved within a function at run time.

proc iml;

start test(ep);

  str = concat("x_",ep);
  print str;

finish;


x_vec1 = J(10,1,34);
x_vec2 = J(10,1,67);

run test("vec1");
run test("vec2");


quit;
2

2 Answers

3
votes

The short answer to your question is that you need the function value.

proc iml;
 x_vec1 = J(10,1,34);
 str = cats('x_','vec1');
 _temp = value(str);
 print(_temp);
quit;

However, it doesn't work in a subroutine quite like you programmed it. That's because the subroutine needs to know that it's allowed to access the variable x_vec1 as a global variable - which you can't actually do here since you're specifying it on the fly.

You can get around this by PUSHing the command back to the calling environment, however.

start test(ep);
  str = cats('print(x_',ep,')');
  print(str);
  call push(str);
finish;

Not sure if this gives you the flexibility you need; if you are trying to do something more complex you may want to clarify what the final result needs to be.

1
votes

Using Joe's answer above, this new example accesses 2 vectors called "x_vec1" and "x_vec2" and adds a user defined amount to each element. Thus I think this approach can be used to create re-usable code that takes vector/matrix names as arguments.

proc iml;

start test(ep,n);

str1 = cats('print(x_',ep,');');
print str1;

str2 = cats('y_',ep,'= x_',ep,'+',char(n),';');
print str2;

str3 = cats('print(y_',ep,');');
print str3;

call queue(str1,str2,str3);

finish;


x_vec1 = J(10,1,34);
x_vec2 = J(10,1,67);

run test("vec1",10);
run test("vec2",100);


quit;