斯科特的答案绝对是一个好答案,但这里有一些替代方案。
首先,最接近您实际编写的方法是将术语括在引号中,将它们选择到宏变量中,然后在数据步骤中使用它们:
proc sql;
select quote(smbl) into :smbllist separated by ' '
from sp500;
quit;
data result;
set mydata;
where company_symbol in (&smbllist.);
run;
这不是一个特别好的方法,但它确实有效。
备择方案:
数据步合并(或 SQL 连接)通常比比较好,因为它更好地利用了哈希/索引/等。
data result;
merge mydata(in=a) sp500(in=sp);
by company_symbol;
if a and sp;
run;
这需要对它们进行排序,并且两者中的变量名称相同(如果需要,您可以在合并语句中的一个数据集上使用 RENAME)。SQL 内连接会做同样的事情,而且不需要显式排序,尽管它可能会在不告诉你的情况下为你排序数据(因此不会节省时间)。取决于哈希解决方案是否有效(如果有效,则不必排序)。
如果排序对您来说是一个额外的步骤(即,如果通常不以这种方式排序),格式通常会更快。
数据for_fmts;设置sp500;fmtname='$SMBLF'; 开始=smbl;标签="1"; *或任何你想要的TRUE;输出; 如果n =1 则执行;hlo='o'; *这会检查不匹配;开始=''; 标签='0'; *或任何你想要的FALSE;输出; 结尾; 跑;
*必须是smbl的NODUPKEY,所以如果有重复,做一个proc sort nodupkey;
proc 格式 cntlin=for_fmts; 辞职;
数据结果;设置我的数据;where put(company_symbol,$SMBLF.)='1'; 跑;
就面向对象的思维而言,哈希表最接近您实际编写的内容。
data result;
if _n_=1 then do;
if 0 then set sp500;
declare hash sp('dataset:sp500');
sp.defineKey('smbl');
sp.defineData('smbl'); *or whatever you want to return when found, if something;
sp.defineDone();
call missing (smbl); *initialize to missing to avoid warning;
end;
set mydata;
rc = sp.find(key:company_symbol);
if rc eq 0 then output; *or you could do this in one statement, skipping the rc, just being clear here;
run;