您以不正确的方式将宏代码与数据步骤代码组合在一起。%if = 宏语言,这意味着您实际上是在评估文本“coverageid”是否等于 %superq(&v) 评估的文本,而不是 coverageid 变量的内容是否等于 &v 中的值。您可以将 %if 转换为 if,但即使您让它正常工作,它也会非常低效(您正在重写数据集 N 次,因此如果您有 1500 个coverageID 值,您将重写整个 500MB 数据集或诸如此类的 1500次,而不是一次)。
如果您要做的是获取变量“coverageid”并将其转换为一组变量,这些变量包含所有可能的coverageid 值,1/0 二进制,对于每个变量,有很多方法可以做到这一点。我相当肯定 ETS 模块有一个程序可以做到这一点,但我不记得它 - 如果你要将它发布到 SAS 邮件列表,其中一个人无疑会有它很快。
对我来说,简单的方法是使用完整的 datastep 代码来做到这一点。首先确定 COVERAGEID 有多少潜在值,然后将每个值分配给直接值,然后将值分配给正确的变量。
如果 COVERAGEID 值是连续的(即,从 1 到某个数字,没有跳过,或者您不介意跳过),那么这很容易 - 设置一个数组并对其进行迭代。我会假设它们不是连续的。
*First, get the distinct values of coverageID. There are a dozen ways to do this, this works as well as any;
proc freq data=save.test;
tables coverageid/out=coverage_values(keep=coverageid);
run;
*Then save them into a format. This converts each value to a consecutive number (so the lowest value becomes 1, the next lowest 2, etc.) This is not only useful for this step, but it can be useful in the future in converting back.;
data coverage_values_fmt;
set coverage_values;
start=coverageid;
label=_n_;
fmtname='COVERAGEF';
type='i';
call symputx('CoverageCount',_n_);
run;
*Import the created format;
proc format cntlin=coverage_values_fmt;
quit;
*Now use the created format. If you had already-consecutive values, you could skip to this step and skip the input statement - just use the value itself;
data save.test_fin;
set save.test;
array coverageids coverageid1-coverageid&coveragecount.;
do _t = 1 to &coveragecount.;
if input(coverageid,COVERAGEF.) = _t then coverageids[_t]=1;
else coverageids[_t]=0;
end;
drop _t;
run;