loopssortingsasproceduresas-macro

How to use SAS multiple Macro variables in procedure block using loops only if it exist


I created multiple macro variables using call symput using data values and I wanted to use them in procedure block using loops in macro and it's not working out for me.

  • Creating macro variables;
Data _null_;
  set all;
  n= _n_;
  n1 = strip(put(n, best.));
  call symput('seq'||n1, n1);
  *creates macro variables like sort1, sort2, sort3,....;
  if ~missing(var) then call symput('sort'||left(_n_), var);
run;

  • finding no of records;
Proc sql noprint;
  select count(var) into:Noobs from all;
quit;

%put &Noobs

  • Macro block;

%macro sortuntil(n= );
  %do i = 1 %to n;
     %let data = i;
     %do %until (&data eq &seq(i));
        Proc sort data = dif;
           by &sort1 &sort2 &sort3 &sort4 . . . etc;
        run;
      %end;
   %end;
%mend;

%sortuntil(n=&Noobs);

The above code should sort the data based on no of macro variables created in data null block example: All dataset has 15 records in var variable so, in this case it execute below code

Proc sort data = dif;
             by &sort1 &sort1 &sort1 &sort1 &sort1 . . . sort15;
         run;

Solution

  • There are easier ways to do this. For example, you can use PROC SQL with SELECT INTO to create a single macro variable that will hold a list of variable names. But if you're interested in macro looping, that approach can be used as well. Note that your code has the looping wrong. You are running PROC SORT inside the loop, so if you call %SortUntil(n=15) it will run PROC SORT 15 times. Instead you would want to use the loop to build the list of variables on the BY statement. You could do that like:

    data dif ;
    x=1 ; y=2 ; z=3 ;
    run ;
    
    %let sort1=x ;
    %let sort2=y ;
    %let sort3=z ;
    
    %macro sortuntil(n= );
      %local i ;
      proc sort data = dif;
        by
          %do i = 1 %to &n;
            &&sort&i
          %end ;
        ;
      run ;
    %mend;
    
    options mprint ;
    %sortuntil(n=3)
    %sortuntil(n=1)