Macro multfmt

From sasCommunity
Jump to: navigation, search

Macros_by_Ian_Whitlock

%macro multfmt(data = _last_ ,    /* sas data set name */
                 vflist = ,         /* var fmt. ...      */
                             /* use . for default format */
                 obs = 0 ,   /* 0 for max                */
                 where =     /* overrides obs            */
               );
 
%if %upcase(&data ) = _LAST_ %then %let data = &syslast;
 
%local i j w1 w2 fmts nv savv opt;
 
%if %length(&where ) > 0 %then %let opt = where =(&where );
%else %if &obs       > 0 %then %let opt = obs = &obs;
 
%let i = 1;
%let w1 = %scan(&vflist , &i , %str() );
%let w2 = %scan(&vflist , &i + 1 , %str() );
 
%do %while(%quote(&w2 ) ^= );
 
   %if %quote(&w1 ) ^= %quote(&savv ) %then %do;
       /* new variable */
       %let j = %eval(&j + 1 );
       %local v&j vc&j;
       %let v&j = &w1;
       %let savv = &w1;
       %end;
 
   %let vc&j = %eval(&&vc&j + 1 );
   %if %length(&w2 ) > 1 %then %let fmts = &fmts __v&j._&&vc&j &w2;
 
   %let i = %eval(&i + 2 );
   %let w1 = %scan(&vflist , &i , %str() );
   %let w2 = %scan(&vflist , &i + 1 , %str() );
   %end;
 
%let nv = &j;
 
data __data
    (drop = 
    %do j = 1 %to &nv;
        &&v&j
        %end;
     );
set &data
   (keep = 
    %do j = 1 %to &nv;
        &&v&j
        %end;
    &opt
   );
   %do j = 1 %to &nv;
       %do i = 1 %to &&vc&j;
           __v&j._&i = &&v&j;
           %end;
       %end;
run;
 
proc print data = __data label;
           var
           %do j = 1 %to &nv;
               %do i = 1 %to &&vc&j;
                   __v&j._&i
                  %end;
               %end;
           ;
           format &fmts;
           label
              %do j = 1 %to &nv;
                  %do i = 1 %to &&vc&j;
                      __v&j._&i = "&&v&j"
                      %end;
                  %end;
              ;
run;
%mend  multfmt;

Harvesting and code polishing by:

--macro maven == the radical programmer 22:43, 23 May 2012 (EDT)