%let Q1 = 0.2;
%let Q2 = 0.3;
%let Q3 = 0.4;
%let Q4 = 0.5;
a1
有一个名为Qtr
的列,表示今年的季度。原始代码是
data a2;
set a1;
if Qtr = 1 then QtrE = &Q1;
if Qtr = 2 then QtrE = &Q2;
if Qtr = 3 then QtrE = &Q3;
if Qtr = 4 then QtrE = &Q4;
run;
data a3;
set a2;
calculated = base * QtrE;
run;
我认为最初的一个非常笨拙。如果效果按月而不是按季度计算,那么我必须编写更多代码才能进行简单的计算。所以我写了下面的代码。但它没有用。似乎宏变量Qtr
没有逐行更改。
data a3;
set a1;
call symput('Qtr',cat('Q',Qtr));
calculated = base * &&&Qtr;
run;
答案 0 :(得分:2)
您应该阅读有关symput()如何与宏编译器和数据步骤编译器相关的文档。 http://support.sas.com/documentation/cdl/en/mcrolref/68140/HTML/default/viewer.htm#p09y28i2d1kn8qn1p1icxchz37p3.htm
简短的说法是你的代码无效,因为宏编译器会解析&&& Qtr,然后将其传递给数据步骤。
宏为您编写SAS代码。然后编译并运行SAS代码。
以这种方式思考,将Data Step编译成foreach循环。
foreach(record in a1):
call symput(...);
record.calculated = record.base * <value of &qtr>;
但是在编写上面的代码之前,&amp; qtr的值已经解决了。
创建查找表可能是最好的方法。左边用你的值加入桌子上。有很多方法可以在SAS中进行左连接。
答案 1 :(得分:1)
在这种情况下,RESOLVE应该可以为您提供所需的信息。我不同意Dom,实际上你应该创建一个查找表(这里的格式最好是IMO),但具体的问题可以解决。
这是唯一的,因为宏变量的值被用作代码中的值 - 也就是说,它在编译步骤中确实不重要,因为它尚未定义。用于在等号的 left 侧定义变量名的宏变量,或作为函数或其他类似的东西,不能以这种方式使用。
%let Q1 = 0.2;
%let Q2 = 0.3;
%let Q3 = 0.4;
%let Q4 = 0.5;
data a1;
do q=1 to 4;
output;
end;
run;
data a2;
set a1;
qtre=resolve(cats('&Q',q));
run;
答案 2 :(得分:1)
我认为DomPazz建议完全避免使用宏是最好的方法。如果由于某种原因你不能这样做,还有一个选项是使用symget()
函数:
data a3;
set a1;
call symput('Qtr',cat('Q',Qtr));
calculated = base * input(symget(symget('qtr')),best.);
run;
根据documentation,symget ......
在DATA步骤执行期间返回宏变量的值。