SYSPBUFF选项

时间:2018-02-22 00:50:15

标签: sas

我试图编写宏代码,其中我使用了几个关键字参数,并希望其中一个参数能够读取多个参数/值。 我希望实现这样的目标:

%MACRO TEST(CONDITION=, VVAR=, OUT_VAR=)/PARMBUFF;
%LET CNT = %sysfunc(countw(&syspbuff));
&OUT_VAR = .;

%DO I =1 %TO &CNT;
%IF &CONDITION=Y %THEN %DO;
&OUT_VAR=(SALARY+BUNUS)/COUNT(VALUES PASSED TO VVAR PARAMETER);
%END;
%END;
%MEND;

data person;
   input SALARY BONUS COND $;
   datalines;
100 50 Y
200 75 Y
300 0 N
;
%TEST(CONDITION=COND,VVAR=SALARY BONUS,OUT_VAR=AVG_SAL);
RUN;

任何人都可以建议我如何实现这一目标?我厌倦了使用syspbuff选项来读取VVAR参数的值,但它将所有值传递给所有参数。 谢谢!

1 个答案:

答案 0 :(得分:0)

您似乎对宏代码执行的时间以及宏执行的代码由SAS执行时感到困惑。宏处理器首先完成其工作,然后将代码传递给SAS进行解释。当SAS看到完整的数据或proc步骤时,它会运行该步骤。

这是我尝试将您的帖子翻译成可以执行的内容。不确定它是不是你想要的。

首先你有一个宏,它接受三个参数。第一个是一些评估为字符串的SAS表达式。中间是变量列表。最后一个是一个变量名。它使用这些参数值生成可在数据步骤内使用的SAS代码,以有条件地生成列表中变量的均值。

%MACRO TEST(CONDITION=, VVAR=, OUT_VAR=);
IF &CONDITION='Y' THEN DO;
&OUT_VAR=mean(of &vvar);
END;
else &out_var=.;
%MEND;

现在,您需要将该宏作为数据步骤的一部分进行调用,以便在SAS理解它的位置生成代码。 注意当您的数据步骤使用内联数据(CARDS / DATALINES)时,内联数据最多是数据步骤中的最后一项。

data person;
   input SALARY BONUS COND $;
%TEST(CONDITION=COND,VVAR=SALARY BONUS,OUT_VAR=AVG_SAL);
datalines;
100 50 Y
200 75 Y
300 0 N
;

如果使用MPRINT选项运行它,则可以看到宏生成的SAS代码。它就像你直接在数据步骤中输入代码而不是让宏为你生成它一样。

615   data person;
616      input SALARY BONUS COND $;
617   %TEST(CONDITION=COND,VVAR=SALARY BONUS,OUT_VAR=AVG_SAL);
MPRINT(TEST):   IF COND='Y' THEN DO;
MPRINT(TEST):   AVG_SAL=mean(of SALARY BONUS);
MPRINT(TEST):   END;
MPRINT(TEST):   else AVG_SAL=.;
618   datalines;

NOTE: The data set WORK.PERSON has 3 observations and 4 variables.
NOTE: DATA statement used (Total process time):
      real time           0.06 seconds
      cpu time            0.03 seconds


622   ;

如果您想生成多个新变量,那么只需多次调用它。您可以通过将每个输入参数视为分隔的值列表并处理第一组然后处理第二组等来使宏更复杂。但为什么?

如果您想知道宏变量值中出现多少个单词,如上面宏中的VVAR参数,那么您可以使用%sysfunc()宏函数来调用SAS函数{{1} }。

countw()

然后,您可以在需要的地方使用%let cnt=%sysfunc(countw(&vvar)); 的值。假设为宏&cnt循环的上限或生成的SAS代码中的表达式中的整数常量。