マクロ コードとデータ ステップ コードを正しく組み合わせていません。%if = マクロ言語。つまり、テキスト "coverageid" が %superq(&v) が評価するテキストと等しいかどうかを実際に評価していることを意味し、coverageid 変数の内容が &v の値と等しいかどうかではありません。%if を if に変換することもできますが、それが適切に機能したとしても、非常に非効率的です (データセットを N 回書き換えているため、coverageID に 1500 の値がある場合、500MB のデータセット全体または 1500 以外を書き換えます)。 1 回ではなく 2 回)。
あなたがやりたいことが変数「coverageid」を取り、それをカバレッジIDのすべての可能な値、1/0バイナリで構成される一連の変数に変換することである場合、それを行う方法はたくさんあります。ETSモジュールにはこれを行うだけの手順があると確信していますが、頭のてっぺんから思い出したことはありません-これをSASメーリングリストに投稿するとしたら、そこにいる人の1人が間違いなく持っているでしょうすぐに。
私にとって簡単な方法は、完全にデータステップ コードでこれを行うことです。最初に 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;