我有这样的客户调查数据:
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我是宏的初学者
答案 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')
注意几件事:
IN
运算符接受空格或逗号(或两者)作为列表中的定界符。由于使用逗号来分隔参数,因此在宏调用中传递逗号分隔列表很麻烦。如果列表在数据集中,则可以使用PROC SQL轻松地将值列表生成为宏变量。只要确保结果列表对于宏变量来说就不会太长(最大64K字节)。
proc sql noprint;
select distinct quote(trim(customer))
into :custlist separated by ' '
from my_subset
;
quit;
%subset(&custlist)