Search code examples
arrayssassas-macro

Using SAS macrovariables inside a SAS data step


I have a macrovariable &var_list which stores a list of integer variable names from the dataset have.

%put &var_list.;

id trt grade

Now I want to create a new dataset want where each of the above variable names itself becomes an array- and I need this done using macrovariables, because eventually my &varlist will have about a 1000 variables. I want macro code that creates a new data set where all the existing variables become arrays of length 4. Like so:

data want;

array id_var{4};

array trt_var{4};

array grade_var{4};

set have;

run;

I have tried the following macro code but it doesn't run correctly. I am trying to iterate through &var_list, concatenate the string "var" to the variable name and also add a {4} at the end to declare each variable as an array. But SAS complains that the keyword "array" is an undeclared array variable. It doesn't realise that I am trying to use the keyword array inside the %do macro. Also, what do I do about the {4} in the declaration statement?

%put &var_list.;

id trt grade

%macro getArrayData(dat);

data &dat;

%do i=1 %to 3;

       array %scan(&var_list,&i.)_var {4};

%end;

set have;
run;
%mend getArrayData;

%getArrayData(want);

Solution

  • Aside: With the idea of eventually having 1,000 {4} item arrays you might want to consider using one 2-dimensional array {1000,4}

    What does the log show when you turn on OPTIONS MPRINT;

    The code you show does work correctly. I recommend coding var_list as a macro parameter instead of relying on a global macro variable.

    data have;
    run;
    
    %macro getArrayData(dat, var_list);
    
    data &dat;
    
    %do i=1 %to 3;
    
           array %scan(&var_list,&i.)_var {4};
    
    %end;
    
      set have;
    run;
    %mend getArrayData;
    
    options mprint;
    
    %getArrayData(want, a b c);
    

    Log

    56   %getArrayData(want, a b c);
    MPRINT(GETARRAYDATA):   data want;
    MPRINT(GETARRAYDATA):   array a_var {4};
    MPRINT(GETARRAYDATA):   array b_var {4};
    MPRINT(GETARRAYDATA):   array c_var {4};
    MPRINT(GETARRAYDATA):   set have;
    MPRINT(GETARRAYDATA):   run;
    
    

    Depending on what columns are in have the above will create variables a_var1-a_var4 , b_var1-bvar4 , cvar1-cvar4

    In general, a space separated list in macro is iterated as

    %do index = 1 %to %sysfunc(countw(&list,%str( )));
      %let item = %sysfunc(scan(countw(&list,%str( )));
    
      /* do things with &item */
    
    %end;