SAS Macro for Rolling Up Multiple Records by Groups
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;

