2013-07-05 68 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