将宏 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-loops
和 non-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;
一些上下文:
我有一串数字(未排序,但已知范围为 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-loops
和 non-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;