2015-02-24 73 views
2

取样输入数据:
FirstName LastName Group Age LastVenue Position
Jack Smith ULDA 25 TheaterA 1
Jesse James GODL 37 TheaterB 12
Jane Doe ULDA 29 TheaterA 3
Izzy Gord IIPA 41 TheaterC 8
Ann Roswell GODL 30 TheaterB 16
Chelsea Jenk ULDA 19 TheaterA 11
如何用条件创建这个宏?

我想创建:
%macro group_members(group=); proc print data=sample; var Position Age Group FirstName LastName; where group=&group; %mend group_members;

但是我想为它添加条件,所以如果没有输入任何内容%group_members()那么它将显示所有组的变量顺序如上所示。如果在这种情况下输入了一个无效的组:%group_members(LOL)那么我希望将一个注释发送到日志%put 'An invalid group was entered'。因此没有什么应该打印。我正尝试在一个更大的数据集上创建一个非常相似的程序。
我感谢任何帮助先进!谢谢:)

到目前为止,我曾尝试:
%macro group_members(group=); proc sql; select count(*) into :ct from sample where group="&group" quit; proc print data=sample; %if &group ^= %then %do; where group="&group."; %end; %if &ct = 0 %then %put An Invalid group was entered; %else %do; where group="&group."; %end; run; %mend group_members;

我得到的错误,从每一个测试。例如%group_members()返回一个错误:
ERROR: More positional parameters found than defined

回答

1
  1. 输入空导致显示的所有组可以通过用以下宏代码围绕where声明来实现:
 
    %if &group ^= %then %do; 
     where group="&group."; 
    %end; 

这只会提交where声明,如果填充了&group变量。还要注意,我已经添加了双引号,因此where语句不会生成语法错误。

  1. 该宏需要知道哪些组是有效的或无效的。这就要求proc print前一个额外的处理步骤:
 
    proc sql; 
     select count(*) into :ct 
     from sample 
     where group="&group"; 
    quit; 

    %if &ct = 0 %then %put An invalid group was entered; 
    %else %do; 
    ... 

& CT包含的where条款相匹配的记录数。如果为零,那么我假设这意味着它是一个无效的组。

+0

谢谢你的代码中的注释!我是SAS Macro的新手。我会放置proc sql; proc打印之前的宏内部? – Jax 2015-02-24 01:17:22

+0

是的,'&group'宏变量在宏外不可用,所以它在外面是没有意义的。 – mjsqu 2015-02-24 01:18:26

+0

我试过这个,但我不能得到它的工作......这是我有:'%macro group_members(group =); \t proc sql; \t select count(*)into:ct \t from sample where group =“&group” quit; \t proc print data = sample; \t%if&group^=%then%do; \t where team =“&group。”; \t%end; \t%if&ct = 0%then%put一个无效组被输入; \t%else%do; \t其中group =“&group。”; \t%end; \t run; %修补group_members; %group_members()' – Jax 2015-02-24 02:26:05

0

感谢@mjsqu

第一步:测试是否&group是有效的组。 count(*)为你做这个。

第2步:如果count(*)返回0,则输出用户定义的消息。

第3步:否则,继续proc print。如果&group =则列出所有记录。

%macro group_members(group); 
    proc sql noprint; 
    select count(*) into :ct 
    from sample 
    where group="&group."; 
    %if &ct = 0 and &group ne %then %put An Invalid group was entered; 
    %else %do; 
    proc print data=sample; 
    var Position Age Group FirstName LastName; 
    %if &group ne %then 
    %do; 
    where group="&group."; 
    %end; 
    %end; 
%mend group_members; 
%group_members(); 
%group_members(GODL); 
%group_members(G); 
+0

我会建议在'proc sql'后面添加'noprint'。它会在'proc print'结果之上隐藏'&ct'的值。 – Lovnlust 2015-02-24 03:10:55

+0

当Group为空时,您的代码仍然会打印 - 输入了一个无效的组,也不会输出任何内容,我不认为OP在寻找什么。 – NEOmen 2015-02-24 05:05:22

0

/创建示例数据集/

data test; 
infile datalines dlm="," missover; 
input FirstName : $10. 
     LastName : $10. 
     Group : $8. 
     Age : 8. 
     LastVenue : $10. 
     Position : 8. 
     ; 
     datalines; 
Jack,Smith,ULDA,25,TheaterA,1 
Jesse,James,GODL,37,TheaterB,12 
Jane,Doe,ULDA,29,TheaterA,3 
Izzy,Gord,IIPA,41,TheaterC,8 
Ann,Roswell,GODL,30,TheaterB,16 
Chelsea,Jenk,ULDA,19,TheaterA,11 
; 
run; 

是否加入本身

%macro group_members(group=); 
%put &group.; 

/*Checking if the group is valid or invalid*/ 
proc sql noprint; 
select count(*) into :num from test where group="&group."; 
quit; 
%put &num.; 


data final; 
set test; 

/*checking if the group entered is NULL, if it is ,then it will output all the records*/ 
%if "&group."="" %then %do; %end; 


/*If the group is Valid or not, if it is invalid then nothing will be in output and a msg in the LOG will be displayed, you can put ERROR statement if you want*/ 
%else %if &num. = 0 %then %do; 
where group="&group."; 
%put "An Invalid group was entered"; 

/*If above two are not the case then it will filter on that group*/ 
%end; 
%else %do; 
where group="&group."; 
%end; 
run; 

%mend group_members; 

%group_members(group=);