SAS SymputX和Symget函数
我试图通过编写下面的SAS代码来构造表2,但得到的是表1。我想不出我错过了什么。非常感谢你的帮助SAS SymputX和Symget函数,sas,sas-macro,Sas,Sas Macro,我试图通过编写下面的SAS代码来构造表2,但得到的是表1。我想不出我错过了什么。非常感谢你的帮助 &counter = 4 data new;set set1; total = 0; a = 1; do i = 1 to &counter; call symputX('a',a); total = total + Tem_&a.; a = symget('a')+1;
&counter = 4
data new;set set1;
total = 0;
a = 1;
do i = 1 to &counter;
call symputX('a',a);
total = total + Tem_&a.;
a = symget('a')+1;
call symputX('a',a);
end;
run;
Table 1
ID Amt Tem_1 Tem_2 Tem_3 Tem_4 total
4 500 1 4 5 900 3600
5 200 50 100 200 0 0
9 50 40 0 0 0 0
10 500 70 100 250 0 0
Table 2
ID Amt Tem_1 Tem_2 Tem_3 Tem_4 total
4 500 1 4 5 900 910
5 200 50 100 200 0 350
9 50 40 0 0 0 40
10 500 70 100 250 0 420
不幸的是,您不能那样使用SYMPUT和SYMGET。虽然可以使用它们存储/检索宏变量值,但不能在执行后更改发送给编译器的代码 基本上,SAS在查看任何数据(这称为编译)之前,必须先找出在数据步骤循环的每次迭代中应该执行的操作的机器代码。因此,问题是,您不能定义
tem\u&a.
并期望在执行过程中允许更改\u&a.
的内容,因为这会更改机器代码需要执行的操作,而SAS无法对此做好充分准备
因此,您编写的&a.
将在程序编译时得到解决,而&a.
在您的数据步骤之前所具有的任何值都将是tem&a.
将变成的值。大概在您第一次运行此操作时,它就出错了(&a.没有解决
,然后是关于变量名中非法的错误),然后最终调用symput
完成了它的工作,&a
在循环结束时得到了一个4,并且您的tem\u&a.
解析为tem\u 4
解决方案是什么?不要为此使用宏。相反,使用数组
data new;
set set1;
total = 0;
array tem[&counter.] tem_1-tem_&counter.;
a = 1;
do i = 1 to &counter; *or do i = 1 to dim(tem);
total = total + Tem[i];
end;
run;
当然,也可以直接求和
data new;
set set1;
total = sum(of tem_1-tem_4);
run;
如果您真的喜欢宏变量,当然可以在宏执行循环中执行此操作,但不建议这样做,因为坚持使用数据步技术会更好。但无论如何,如果您在宏中运行它,这应该是可行的(这在开放代码中无效)
不幸的是,您不能那样使用SYMPUT和SYMGET。虽然可以使用它们存储/检索宏变量值,但不能在执行后更改发送给编译器的代码 基本上,SAS在查看任何数据(这称为编译)之前,必须先找出在数据步骤循环的每次迭代中应该执行的操作的机器代码。因此,问题是,您不能定义
tem\u&a.
并期望在执行过程中允许更改\u&a.
的内容,因为这会更改机器代码需要执行的操作,而SAS无法对此做好充分准备
因此,您编写的&a.
将在程序编译时得到解决,而&a.
在您的数据步骤之前所具有的任何值都将是tem&a.
将变成的值。大概在您第一次运行此操作时,它就出错了(&a.没有解决
,然后是关于变量名中非法的错误),然后最终调用symput
完成了它的工作,&a
在循环结束时得到了一个4,并且您的tem\u&a.
解析为tem\u 4
解决方案是什么?不要为此使用宏。相反,使用数组
data new;
set set1;
total = 0;
array tem[&counter.] tem_1-tem_&counter.;
a = 1;
do i = 1 to &counter; *or do i = 1 to dim(tem);
total = total + Tem[i];
end;
run;
当然,也可以直接求和
data new;
set set1;
total = sum(of tem_1-tem_4);
run;
如果您真的喜欢宏变量,当然可以在宏执行循环中执行此操作,但不建议这样做,因为坚持使用数据步技术会更好。但无论如何,如果您在宏中运行它,这应该是可行的(这在开放代码中无效)
@Joe可能应该用宏变量引用替换硬编码的上限,或者删除宏变量引用。就目前情况而言,如果计数器不是4,您将有问题。同意@tom,尽管我没有这么做的原因是为了不使代码与原始代码有太大的偏差来显示并行性。@Joe可能应该用宏变量引用替换硬编码的上限,或删除宏变量引用。现在看来,如果计数器不是4,你就有问题了。同意@tom,尽管我没有这么做的原因是为了不让代码与原始代码偏离太多,以显示相似之处。