Изменение макропеременной SAS + индекс массива - PullRequest
3 голосов
/ 28 марта 2011

Это связано с этим вопросом: Изменение макропеременной SAS .

Приведенный ниже код объясняет проблему:

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

Итак, вопрос в том, почемуошибка в последнем тесте?Спасибо.

Ответы [ 2 ]

4 голосов
/ 28 марта 2011

Если вы используете 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
*/
2 голосов
/ 28 марта 2011

Я должен сказать, что не совсем уверен, что вы пытаетесь сделать;но дает ли это результаты, которые вы ищете?Проблема с вашим кодом выше состоит в том, как вы пытаетесь объединить переменные набора данных и макропеременные - это не так просто, как можно надеяться ...

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