2013-10-10 22 views
1

我正在想创建这样的数据集,P1_31,P1_32,P1_36,P1_37在SAS使用下面的代码%DO循环显示我的错误是SAS

%MACRO P_MISS1; 
%LET T1= 3 ; 
%LET H1=1; 
%DO %WHILE(&H1<=1); 
     %LET TR1=%SCAN(&T1,&H1); 
      %DO I= 1,2,6 %TO 7; 
       DATA P1_&TR1&I; 
        VALUE=.; 
        COL&TR1=.; 
       RUN; 
       OUTPUT; 
      %END; 
    %LET H1=%EVAL(&H1+1); 
%END; 
%MEND P_MISS1; 

%P_MISS1 

我用很多宏观的计划,所有上述数据集,但只是为了减少我创建下面的代码的代码大小。我知道我正在做%Do Loop的问题。如果有可能使用上面的代码,请引导我使用代码。

+0

使用%前做我= 1, 2,6%到7,我用%做我= 1,2,6,7。 –

+0

我不认为宏语言支持任何结构。 (两者都是数据步骤中的合法结构,但使用它的人会很奇怪,因为它没有做任何事情。)我相信宏语言只支持%do x%到y,没有逗号列表或类似的东西。 – Joe

回答

3

编写这种代码的更好的方式就像编写代码任何一样,就是把宏写成想要多次运行的代码,然后多次调用它。这使得它更加可重用,更清晰地表明你正在做什么,并最终以更短的代码结束。

这个特定的代码集并不是完全明显的,如何编写它的最好方法是,因为驱动你输入的东西并不明显。但是,这样的事情是有道理的。

%macro make_ds(tr,i); 
DATA P1_&TR1&I; 
    VALUE=.; 
    COL&TR1=.; 
RUN; 
%mend make_ds; 

%macro call_make_ds(tr); 
    %make_ds(&tr,1); 
    %make_ds(&tr,2); 
    %make_ds(&tr,6); 
    %make_ds(&tr,7); 
%mend call_make_ds; 

对于四个项目我只是写出来,如果没有数据集或其他实体包含四个项目。编写复杂循环的代码很简单,容易出错,维护起来也不容易。如果您有一个包含i的可能值的数据集,则使用该数据集调用%make_ds宏。

然后根据适当的参数调用该宏。例如,如果TR可以从一个数据集来决定(假设你有一个包含所有TR值要遍历数据集),你可以做这样的事情:

proc sql; 
select distinct cats('%call_make_ds(',trval,')') into :makelist 
separated by ' ' 
from your_ds; 
quit; 
&makelist; 
+0

感谢您的编程思想。但我可以使用do循环以便我可以创建这些数据集与应用最小的代码,基本上我需要创建大量的数据集:P1_31,P1_32,P1_36,P1_37 P1_22,P1_23,P1_24, P1_26,P1_27 –

+0

再次阅读答案?我想我清楚地回答了。如果您不清楚某些事情,请澄清您需要帮助的内容。 – Joe

1

那么,这条线是错误的,只要我的SAS知识云:

%DO I= 1,2,6 %TO 7; 

通常情况下,你写的:

%do macrovar=startvalue %to endvalue; 

我建议你创建一个宏与项目名单你想使用后缀和循环他们:

%MACRO P_MISS1; 
    %let suffixes=31 32 36 37; 
    %let elementNbr=1; 
    %let elementValue=%scan(&suffixes.,&elementNbr.); /*initiate with first element*/ 

    %do %while(&elementValue. NE %str()); /*as long as we find elements, we continue iterating*/ 
     data P1_&elementValue.; 
      value=.; 
      col3=.; 
      output; 
     run; 
     %let elementNbr=%eval(&elementNbr.+1); /*increase elementNbr, so that we look now for the next item in our list*/ 
     %let elementValue=%scan(&suffixes.,&elementNbr.); /*initiate next element*/ 
    %end; 
%mend; 
%P_MISS1 

你似乎有一些事情与2级:mult 10个单位和10个单位。我在上面的代码中跳过了这个细微差别,但是可以通过嵌套这样的循环来实现它。
例如,外层循环的倍数为10(在你的情况下,它只是第30层中的3层)和内层循环遍历你想要的值(在你的情况下:1,2,6和7)

所有的说法,我似乎错过了你的代码点。您正在创建空数据集,但是目的是什么?你确定你需要在你的场景中有这些吗?

+1

此代码将循环不休。您需要额外的%let elementValue =%scan(&suffixes。,&elementNbr。);在做结束之前避免它。 –

+0

谢谢你指出。纠正它。 – mvherweg

+0

是的,我需要这些空数据集与具有P值的同一系列的其他数据集连接。 –