请参阅macrolist,其名称取决于变量

时间:2018-06-15 09:00:52

标签: sql sas

%let list_2=‘a’,’b’,’c’;
PROC SQL;  

CREATE TABLE test AS  

SELECT    
     Bin,  /*value is a*/  
     Rank, /*value is 2*/  
     CASE  
     WHEN Bin IN (&list_Rank.)   /*list_2=‘a’,’b’,’c’*/  
     THEN 1  
     ELSE 0  
     END     AS test   

FROM     Source  
;  
QUIT;  

我正在寻找一种方法来在宏变量list_2的引用中使用列Rank的值。

2 个答案:

答案 0 :(得分:4)

正如@John评论的那样,您可以使用SYMGET函数在运行时使用数据查找宏变量的值。我不认为你可以使用IN运算符,因为它需要一个字符串列表,而SYMGET将返回一个字符串。下面我从& LIST_2中取出引号(只是为了更容易使用),并使用FINDW来完成IN的工作。我认为这与你所描述的一致:

%let list_2=a,b,c;
%let list_3=d,e,f ;

data have ;
  input bin $1. rank ;
  cards ;
a 2
a 3
e 2
e 3
;
run ;

proc sql ;
  select
    bin
   ,rank
   ,case when findw(symget(cats("list_",rank))
                   ,bin
                   ) then 1
    else 0
    end as test
   ,symgetc(cats("list_",rank)) as symgetc /*debugging*/
   from have ;
quit ;

答案 1 :(得分:3)

您可以添加另一个CASE语句。实际上因为它是SAS代码,你可以消除当前的CASE语句,只使用IN操作的结果,它将是0(假)或1(真)。

%let list_1='a','b','c';
%let list_2='d','e','f';
%let nlists=2;

PROC SQL;  

CREATE TABLE test AS  
SELECT    
     Bin   /*value is a*/  
   , Rank  /*value is 2*/  
   , case
       when (rank=1) then bin in (&list_1)
       when (rank=2) then bin in (&list_2)
       else 0  
     end as test    
FROM Source  
;  
QUIT;  

如果您在宏中运行,可以使用%do循环生成when子句。

%do i=1 %to &nlists ;
  when (rank=&i) then bin in (&&list_&i)
%end;

如果您不在宏中,则创建一个宏来运行%do循环并在适当的位置调用它。