2011-03-28 97 views
3

这与这个问题有关:SAS macro variable changeSAS宏变量+数组索引

下面的代码说明问题:

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

所以,问题是为什么它的bug在最后的测试?谢谢。

回答

2

我不得不说我不完全确定你要做什么;但是这会给你你想要的结果吗?上面代码的问题是您要结合数据集的变量及宏观variables--它是不容易做,因为人们可能希望的方式......

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

我也喜欢这个解决方案。谢谢 – francogrex 2011-03-28 20:03:45

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 
*/ 
+0

是的,我使用fcmp它是非常好的;但我正在寻找一种只用宏来实现的方法。谢谢 – francogrex 2011-03-28 19:51:57