这与此问题有关:SAS macro variable change。
以下代码解释了问题:
%macro test (arg=);
options mlogic mprint symbolgen;
array arraytwo [%EVAL(&arg+1)] _temporary_;
sum=0;
%do i = 1 %to %EVAL(&arg+1);
sum=sum+&i;
arraytwo[&i]=sum;
%end;
return=arraytwo[&arg+1];
%mend test;
/* This is ok */
data dat1;
%test(arg=9);
run;
data dat2;
input M;
cards;
5
6
7
;
run;
/* This give an error= A character operand was found in the %EVAL function or %IF condition where a numeric
operand is required. The condition was: M+1 */
data dat3;
set dat2;
%test(arg=M);
run;
所以问题是为什么它在最后一次测试中会出错?感谢。
答案 0 :(得分:4)
如果您正好使用SAS 9.2或更高版本,您可能需要查看proc fcmp以创建执行此操作的函数。
如果将其作为函数而不是宏编写,则可以传入将解析为数值的数据集变量 - 或直接传递数值。例如,尝试以下代码:
proc fcmp outlib=work.funcs.simple;
function sumloop(iter);
x=1;
do i=1 to iter+1;
x+i;
end;
return(x);
endsub;
run;
/* point to the location the function was saved in */
option cmplib=work.funcs;
data _null_;
input M;
y=sumloop(M); /* data set variable */
z=sumloop(9); /* static numeric value */
put M= @7 y= @14 z= @20 ;
cards;
1
2
3
4
5
6
7
8
9
;
run;
/* My log looks like this:
14 data _null_;
15 input M;
16 y=sumloop(M); /* data set variable */
17 z=sumloop(9); /* static numeric value */
18 put M= @7 y= @14 z= @20 ;
19 cards;
M=1 y=3 z=55
M=2 y=6 z=55
M=3 y=10 z=55
M=4 y=15 z=55
M=5 y=21 z=55
M=6 y=28 z=55
M=7 y=36 z=55
M=8 y=45 z=55
M=9 y=55 z=55
*/
答案 1 :(得分:2)
我不得不说我不完全确定你要做什么;但这会给你带来你想要的结果吗?上面代码的问题在于您尝试组合数据集变量和宏变量的方式 - 这并不像人们希望的那样容易......
%macro test (argList=, totNumObs=);
%local arg;
%local j;
%local i;
%do j = 1 %to &totNumObs;
%let arg = %scan(&argList, &j);
array array&j [%EVAL(&arg+1)] _temporary_;
sum = 0;
%do i = 1 %to %EVAL(&arg+1);
sum = sum+&i;
array&j[&i] = sum;
%end;
return = array&j[&arg+1];
output;
%end;
%mend test;
data dat2;
input M;
cards;
5
6
7
;
run;
proc sql noprint;
select
count (*) into :numObs
from dat2 ;
select
M into :listofMs separated by ' '
from dat2
order by M;
quit;
options mlogic mprint symbolgen;
data dat3;
%test(argList= &listofMs, totNumObs= &numObs);
run;
proc print data= dat3;
run;