SAS-IML中的Do-loop

时间:2013-07-05 18:07:59

标签: matrix sas sas-macro do-loops sas-iml

我想在proc iml中使用一个宏do循环,如下所示:

%Let Tab1=FirstTable;
%Let Tab2=SecondTable;
%Let Tab3=ThirdTable;

*&Tab1-3 have been initialised as sas datasets;   

proc iml;

* This works;

use &Tab1;
read all into Mat3;
print Mat3;


* This doesn't work;

%Macro Define_mx;
    %do i=1 %to 2;
    use &Tab&i;
    read all into Mat&i ;
   %end;
  %Mend Define_mx;
%Define_mx;

*The two matrixes have not been initialised;

print Mat1;
print Mat2;
quit;

实际上,我必须初始化50个矩阵,因此需要执行do循环。 我无法弄清楚为什么循环不能将& Tab& i视为宏变量。 我还尝试使用substr连接正常(非宏)do循环来连接变量名称,但它也没有工作。我在这里错过了什么?

2 个答案:

答案 0 :(得分:2)

好的,所以宏应该是:

%Macro Define_mx;
 %do i=1 %to 2;
   use &&Tab&i;
   read all into Mat&i ;
 %end;
 %Mend Define_mx;
%Define_mx;

Tab上的第二个amperstand是必要的,因为没有它,宏处理器会尝试将& Tab解释为宏变量(它不存在)。因此,在尝试连接多个宏变量以创建新宏变量时,请使用&&。

答案 1 :(得分:1)

如果你有SAS / IML 12.1(以9.3m2发布),有一种更简单的方法。 USE statement supports dereferencing data set names,就像这样:

ds = "MyData";
use (ds);

此外,正如我在article on using the VALSET function中所示,SAS / IML语言支持VALSET函数,它可以动态创建名为Mat1,Mat2等的矩阵。 您可以结合使用这些功能来完全消除宏:

data a b c;                 /* create sample data sets */
x=1;y=2; output;
x=2;y=3; output;
run;

proc iml;
dsnames = {a b c};          /* names of data sets */
do i = 1 to ncol(dsnames);
   use (dsnames[i]);        /* open each data set */
   read all into X;
   close (dsname);
   MatName = "Mat"+strip(char(i)); /* create Mat1, Mat2,... */
   call valset(MatName, X);        /* assign values from data set */
end;
show names;