Personal tools
You are here: Home Staff Documentation monao SAS Macro for Rolling Up Multiple Records by Groups

SAS Macro for Rolling Up Multiple Records by Groups

— filed under: , ,

SAS Macro for Rolling up multiple records by Groups into a single record w/ arrays for the multiple records. If there are arrays within the data care should be taken in concatenating the variable index.

This is a template of the general logic and macro code for the Roll Up:


/***********************************************************************/
/* a.rollup_template.macro */
/* SAS pgm code => rollup.macro */
/* roll up written for taking a dataset of multiple records BY GROUP(s)*/
/* and placing records' info into an array */
/* Use the code as a BASIC template to be modified for your needs */
/***********************************************************************/

/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
 /*!!! WARNING !!! This is written for a one dimensional array... */
 /* the concept can be used for 2 dimensions but be careful */
 /* in concatentating the array indices */
 /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
/* sort the data, DATANAME by the GROUPS ie. GROUPS=> family_id &/or age */
Proc sort data=DATANAME; by GROUPS; run;
%macro rollup;

/***********************************************************************/
/* determines the content info of the DATANAME to be used later */
/* capture the variable names & make them a value using */
/* proc contents & out= option => edit the values & use to create a data stmts for output */
/***********************************************************************/
 proc contents data=DATANAME out=DATANAMECONT noprint;
 run;
/***************************************************/
 /* order the variables in creation order->VARNUM */
 /***************************************************/
 proc sort data=DATANAMECONT; by VARNUM; run;

/* maxrecs= #recs in GROUPS for all DATANAMES */
 %let maxrecs=0;
 /* numrecs= #recs in GROUPS at given moment */
 data _NULL_;
 set DATANAME;
 by GROUPS;
 retain numrecs 0 maxrecs 0;
 if first.GROUPS then do;
 numrecs=0;
 end;
 numrecs=numrecs+1;
 if numrecs>maxrecs then do;
 maxrecs=numrecs;
 call symput("maxrecs",maxrecs);
 end;
 run;
 %put &maxrecs.;

/***************************************************/
 /*count the variables that are to be rolled up */
 /***************************************************/

data _NULL_;
 set DATANAMECONT;
 retain varcount 0;
 /* substitute GROUPS for the sort by variable names */
 if NAME="GROUPS" then delete;
 varcount=varcount+1;
 call symput(compress("var"||varcount),NAME);
 %do j=1 %to &maxrecs.;
 call symput(compress("nvar"||varcount||"&j."),compress(NAME||"_&j."));
 %end;
 call symput(compress("lab"||varcount),trim(LABEL));
 /* put varcount NAME TYPE; */
 call symput(compress("type"||varcount),trim(TYPE));
 call symput(compress("len"||varcount),trim(LENGTH));
 call symput("varnum",varcount);
 run;

/***************************************************/
 /* roll the data up into the array */
 /***************************************************/

data DATANAMEARRAY;
 set DATANAME;
 by GROUPS;
 retain indx 0;
 if first.GROUPS then do;
 /* indx begins at 0 for each new GROUP */
 indx=0;
 /* test for problem alphabetics */
 %do i=1 %to &varnum.;
 %do j=1 %to &maxrecs.;
 %if &&type&i.=2 %then %do;
 /* %put "CHAR" &i. &j. &&nvar&i&j. &&type&i. &&len&i.; */
 length &&nvar&i&j. $&&len&i..;
 &&nvar&i&j.=" ";
 %end; %else %do;
 &&nvar&i&j.=.;
 %end;
 %end;
 %end;
 /* test */
 end;
 indx=indx+1;
 %do i=1 %to &varnum.;
 %do j=1 %to &maxrecs.;
 if &j.=indx then do;
 &&nvar&i&j.=&&var&i.;
 /* added to accomadate labels in the roll up */
 LABEL &&nvar&i&j.=%nrbquote(&&lab&i&j.);
 %end;
 %end;
 %end;

/*******************************************************/
 /* Building the SAS Data stmts so ADD variables that */
 /* need to be "dropped", "retained" etc */
 /*******************************************************/
 /* each variable up to varnum will be an array of size maxrecs */
 retain GROUPS numrecs
 %do i=1 %to &varnum.;
 %do j=1 %to &maxrecs.;
 &&nvar&i&j.
 %end;
 %end;
 ;
 drop indx
 %do i=1 %to &varnum.;
 &&var&i.
 %end;
 ;
 /* on the last rec for the GROUPS output the record */
 if last.GROUPS then output;
 run;

%mend;

%rollup;


Document Actions

Copyright ©2009, The Pennsylvania State University | Privacy and Legal Statements
Contact the Help Site Administrator | Last modified Aug 19, 2008 | Weblion Partner