Search code examples
sassas-macro

sas- rank inside a macro


I'm trying to do a loop over a liststo perform ranks for several variables.

And then I do the loop with:

options mprint;
%macro ranks(listado);
%let count=%sysfunc(countw(&listado));/*counw= count words in a string*/
%do i=1 %to &count;
%put 'count' &count;
    %let vari=%qscan(&listado,&i,%str(,));
    %put 'vari' &vari;

    proc rank data=labo2.J_tabla_modelo groups=10  out=labo2.tmp;
      var &vari.;
      ranks rk_&vari.;
    run;
%end;
%mend;

        %ranks(%str(G_MERGE6_t1_monto6,A_CLI_monto_sucursal_1,A_CLI_monto_sucursal_2,
A_CLI_monto_sucursal_3, A_CLI_monto_sucursal_4,A_M_0705_monto));

I get the following error:

ERROR: Number of VAR statement variables was not equal  to the number of RANKS statement variables.

Don't know how to solve it. Because if I run the code written by the macro works.

Thanks!


Solution

  • First off, don't do the macro loop this way. It's messy. Generate a list of macro calls.

    Second, you're not really wanting to do that either, here. What you need to generate is this:

    proc rank data=whatever out=whatever;
      var v1 v2 v3 v4;
      ranks r_v1 r_v2 r_v3 r_v4;
    run;
    

    What you are generating is a bunch of different PROC RANKs, which isn't ideal.

    How I'd do it:

    data my_vars;
      length vari $32;
      input vari $;
      datalines;
    G_MERGE6_t1_monto6
    A_CLI_monto_sucursal_1
    A_CLI_monto_sucursal_2
    A_CLI_monto_sucursal_3
    A_CLI_monto_sucursal_4
    A_M_0705_monto
    ;;;;
    run;
    
    proc sql;
     select cats('r_',vari) 
       into :ranklist separated by ' '
       from my_vars;
     select vari 
       into :varlist separated by ' '
       from my_vars;
    quit;
    
    proc rank data=whatever out=whatever groups=10;
      var &varlist;
      rank &ranklist;
    run;
    

    If you actually do need the individual PROC RANK calls, then you need to figure out how to deal with the output, and then do a similar approach.

    (Also, odds are that first datastep isn't needed- you probably have that data somewhere, like in dictionary.columns).