%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的值。
答案 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
循环并在适当的位置调用它。