有没有办法在宏代码下传递列表?

时间:2019-01-24 14:36:36

标签: macros sas

我有这样的客户调查数据:

data feedback;
    length customer score comment $50.;
    input customer $ score  comment & $;
    datalines;
A 3 The is no parking
A 5 The food is expensive
B . I like the food
C 5 It tastes good
C . blank                  
C 3 I like the drink
D 4 The dessert is tasty
D 2 I don't like the service
;
run;

有这样的宏代码:

%macro subset( cust=);

    proc print data= feedback;
        where customer = "&cust";
    run;

%mend;

我正在尝试编写一个程序,为反馈数据中的每个客户值调用%subset。请注意,我们不知道数据集中有多少个客户唯一值。另外,我们无法更改%subset代码。

我试图通过使用proc sql创建要传递到宏代码的唯一客户列表来实现这一点,但是我认为您不能在宏代码中传递列表。 有没有办法做到这一点? p.s我是宏的初学者

2 个答案:

答案 0 :(得分:0)

我喜欢保持简单。看一下以下内容:

data feedback;
length customer score comment $50.;
input customer $ score  comment & $;
datalines;
A 3 The is no parking
A 5 The food is expensive
B . I like the food
C 5 It tastes good
C . blank                  
C 3 I like the drink
D 4 The dessert is tasty
D 2 I don't like the service
;
run;

%macro subset( cust=);
    proc print data= feedback;
       where customer = "&cust";
    run;
%mend subset;

%macro test;
   /* first get the count of distinct customers */
   proc sql noprint;
      select count(distinct customer) into : cnt
         from feedback;quit;

   /* do this to remove leading spaces */
   %let cnt = &cnt;

   /* now get each of the customer names into macro variables
   proc sql noprint;
       select distinct customer into: cust1 - :cust&cnt
            from feedback;quit;

/* use a loop to call other macro program, notice the use of &&cust&i */
%do i = 1 %to &cnt;
   %subset(cust=&&cust&i);
%end;
%mend test;
%test;

当然,如果您想简短而有趣,可以使用(只需确保您的数据按客户排序):

data _null_;
set feedback;
by customer;
if(first.customer)then call execute('%subset(cust='||customer||')');    
run;

答案 1 :(得分:0)

首先修复SAS代码。要使用IN运算符而不是=运算符来测试值是否在列表中。

where customer in ('A' 'B')

然后,您可以将该列表传递到宏中,并在代码中使用它。

%macro subset(custlist);
proc print data= feedback;
  where customer in (&custlist);
run;
%mend;
%subset(custlist='A' 'B')

注意几件事:

  1. 由于变量是字符,因此请在值两边加上引号。
  2. 在值之间使用空格。 SAS中的IN运算符接受空格或逗号(或两者)作为列表中的定界符。由于使用逗号来分隔参数,因此在宏调用中传递逗号分隔列表很麻烦。
  3. 您可以将宏参数定义为位置参数,并仍在宏调用中按名称进行调用。

如果列表在数据集中,则可以使用PROC SQL轻松地将值列表生成为宏变量。只要确保结果列表对于宏变量来说就不会太长(最大64K字节)。

proc sql noprint;
  select distinct quote(trim(customer))
    into :custlist separated by ' '
    from my_subset
  ;
quit;
%subset(&custlist)