sassas-macrodatastep

Format every column from a SAS data set in a iterative way


I am new to SAS and came into a seemingly easy problem.

Suppose I want to convert every column to to a specific format/length based on its data type. The pseudo code will look like the following:

for col in df.columns:
    if col has dtype = 'Char', print col, and format it as $255.
    if col has dtype = 'Number', print col, and format it as best8.

I already have the SAS data output so the above loop probably needs to be in the data step, but can this be done earlier at the "import" / proc sql step as well?


Solution

  • No loops required. You could do with PROC DATATSET MODIFY and not create a new data set.

    data class;
       set sashelp.class;
       format _character_ $255. _numeric_ BEST8.;
       run;
    proc contents varnum;
       run;
    

    enter image description here

    Sounds like you want to measure the character variables and resize to min length.
    
    %let data=sashelp.heart;
    data clength(keep=_name_ _l_);
       set &data end=eof;
       array _1 _character_;
       array _2[20] 8 _temporary_;
       do over _1;
          _2[_i_] = max(_2[_i_],length(_1));
          end;
       if eof then do over _1;
          _name_ = vname(_1);
          _l_    = _2[_i_];
          output;
          end;
       run;
    proc sql noprint;
       select catx(' ',_name_,cats('$',_l_)) into :clength separated by ' ' 
          from clength;
       quit;
    
    %put NOTE: &=clength;
    

    You can use &CLENGTH to redefine the character variable length.

    68         %put NOTE: &=clength;
    NOTE: CLENGTH=Status $5 DeathCause $25 Sex $6 Chol_Status $10 BP_Status $7 Weight_Status $11 Smoking_Status $17