将宏 DO 循环与数据步骤 DO 循环混合

Mixing macro-DO-loops with data step DO-loops

一些上下文:

我有一串数字(未排序,但已知范围为 1 - 78),我想提取这些数字以用它创建特定变量,所以我有

"64,2,3" => var_64 = 1; var_02 = 2; var_03 = 1; (the rest, like var_01 are all set to missing)

我基本上想到了两种解决方案,一种是使用macro DO loop,另一种是data step DO loop。非宏解决方案是首先初始化所有变量 var_01 - var_78 (通过宏),然后将它们放入一个数组中,然后在逐字遍历字符串的同时逐渐设置该数组的值.

然后我意识到将循环迭代器用作宏变量会更容易,我想出了这个 MWE:

%macro fast(w,l);
do p = 1 to &l.;
    %do j = 1 %to 9;
        if &j. =  scan(&w.,p,",") then var_0&j. = 1 ;
    %end;
    %do j = 10 %to 78;
        if &j. =  scan(&w.,p,",") then var_&j. = 1 ;
    %end;
end;
%mend;

data want;
string = "2,4,64,54,1,4,7";
l = countw(string,",");
%fast(string,l);
run; 

它有效(没有错误,没有警告,预期结果)但我不确定混合使用 macro-DO-loopsnon-macro-DO-loops。这会导致任何不一致,还是我应该继续使用非宏解决方案?

您当前的代码正在将 1 之类的数字与“1”之类的字符串进行比较。

&j. =  scan(&w.,p,",")

只要字符串可以转换成数字就可以,但这不是一个好的做法。最好将字符串显式转换为数字。

input(scan(&w.,p,","),32.)

你可以用数组做你想做的事。使用从列表中的下一项生成的数字作为数组的索引。

data want;
  string = "2,4,64,54,1,4,7";
  array var_ var_01-var_78 ;
  do index=1 to countw(string,",");
     var_[input(scan(string,index,","),32.)]=1;
  end;
  drop index;
run;