2013-07-05 69 views
1

我想用宏做循环PROC IML内像这样:DO循环的SAS-IML

%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循环是必要的。 我不明白为什么循环无法看到&选项卡&我作为一个宏变量。 我也尝试了使用substr来连接变量名称的正常(非宏)do循环的解决方法,但它也不起作用。我在这里错过了什么?

+0

Tabs上的双重amperstand ...我是个白痴。 – Pane

+1

太棒了!请提交您的解决方案作为答案并接受它。这绝对是一个非常常见的错误,值得在StackOverflow中作为一个解决方案:) – Joe

回答

2

好了,所以宏应该是:

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

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

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; 
+0

摆脱宏是我在某个时候的目标。我想你可以写'调用valset(“Mat”+ strip(char(i)));'用你的解决方案使它更整洁。不幸的是,我仍然在9.2。据我了解,这个解决方案不适用于这个版本? – Pane