SAS宏变量更改+;数组索引

SAS宏变量更改+;数组索引,sas,sas-macro,Sas,Sas Macro,这与以下问题有关: 下面的代码解释了该问题: %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;

这与以下问题有关:

下面的代码解释了该问题:

%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;

所以问题是为什么它会在上一次测试中出错?谢谢。

我不得不说我不完全确定你想做什么;但这能给你带来你想要的结果吗?上面代码的问题在于您试图组合数据集变量和宏变量的方式——这并不像人们希望的那么容易

%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;

如果您碰巧正在使用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
*/

是的,我使用fcmp,它非常好;但我正在寻找一种只使用宏的方法。谢谢,我也喜欢这个解决方案。谢谢