Hello, %wide outer macro contains three macros %meta, %sum and %freq in this paper(http://www.lexjansen.com/pharmasug/2012/CC/PharmaSUG-2012-CC18.pdf). How to see the execution of these inner macros while the outer macro %wide executes? Wouldn't it be good not to nest these inner macros? Thanks ! %macro wide(indsn=, outdsn=wide,
cols=,
rows=);
%local colvar collist rowvar rowlist i ncol label2 loop;
/* MACRO: give variable metadata of &var */
%macro meta(var);
%global type label;
%local num dsid rc;
%let dsid=%sysfunc(open(&indsn,i));
%let num=%sysfunc(varnum(&dsid,&var));
%let type=%sysfunc(vartype(&dsid,&num));
%let label=%sysfunc(varlabel(&dsid,&num));
%let rc=%sysfunc(close(&dsid));
%mend meta;
%let colvar=%scan(&cols,1,=);
%let collist=%scan(&cols,2,=);
/* create new column variable _COL */
%let i=1;
data temp1;
set &indsn;
%do %while (%length(%scan(&collist,&i,:))>0);
if &colvar in (%scan(&collist,&i,:)) then
do;
_col=&i;
output;
end;
%let ncol=&i;
%let i=%eval(&i+1);
%end;
run;
/* population counts */
proc sql noprint;
%do i=1 %to &ncol;
%global n&i;
select count(_col) into :n&i from temp1(keep=_col where=(_col=&i));
%end;
quit;
/* MACRO: create summary stats from &var by _COL */
%macro sum(var);
proc means data=temp1(keep=_col &var) noprint nway;
class _col;
var &var;
output out=temps1 n=n median=median mean=mean std=sd min=min max=max;
run;
data temps2;
length n1 msd m1 mm $100;
set temps1;
if mean ne . and sd ne . then
msd=strip(put(mean, 12.1))||" ("||strip(put(sd,12.2))||")";
else if mean ne . and sd=. then
msd=strip(put(mean, 12.1))||" (NA)";
if min ne . then
mm=strip(put(min,12.1))||", "||strip(put(max,12.1));
if n ne . then
n1=strip(put(n,best12.));
if median ne . then
m1=strip(put(median, 12.1));
keep _col n1 msd m1 mm;
label N1='n' MSD='Mean (SD)' M1='Median' MM='Min, Max';
run;
proc transpose data=temps2 out=temp2(drop=_name_ rename=(_label_=desc));
id _col;
var n1 msd m1 mm;
run;
%mend sum;
/* MACRO: create freq stats from &var by &list and _COL */
%macro freq(var, list);
%local i;
proc freq data=temp1(keep=_col &var where=(&var ne '')) noprint;
table _col*&var/out=tempf1;
run;
proc sql noprint;
create table tempf2 as
select _col, &var length=100 as desc,
strip(put(count,best12.)) length=100 as freq
from tempf1 order by desc;
quit;
proc transpose data=tempf2 out=tempf3(drop=_name_);
var freq;
by desc;
id _col;
run;
%if %length(&list)>0 %then
%do;
data tempshell;
length desc $100;
%let i=1;
%do %while (%length(%scan(&list,&i,:))>0);
desc=%scan(&list,&i,:);
desc=tranwrd(tranwrd(tranwrd(desc,'(fs)','/'),'(pd)','#'),'(eq)','=');
c=&i;
output;
%let i=%eval(&i+1);
%end;
run;
proc sql noprint;
create table tempf4(drop=desc1 c) as
select a.desc, b.*, a.c from
tempshell a left join tempf3(rename=(desc=desc1)) b on a.desc=b.desc1
order by c;
quit;
%end;
%else
%do;
data tempf4;
set tempf3;
run;
%end;
data temp2;
set tempf4;
%do i=1 %to &ncol;
if _&i='' then
_&i='0';
else _&i=strip(_&i)||' ('||strip(put(input(_&i,best12.)/&&n&i*100,8.1))||'%)';
%end;
run;
%mend freq;
/* empty dataset to build on */
data &outdsn;
stop;
run;
/* loop through variables in &rows */
%let i=1;
%do %while (%length(%scan(&rows,&i,/))>0);
/* &loop holds one variable for one section */
%let loop=%scan(&rows,&i,/);
/* break &loop down into variable and list */
%let rowvar=%scan(&loop,1,=#);
%let rowlist=%scan(%scan(&loop,2,=),1,#);
%meta(&rowvar);
/* see if label for section is specified, if not use variable label */
%let label2=%scan(&loop,2,#);
%if %length(&label2)=0 %then
%let label2="&label";
/* call summary stats of freq stats depending on vartype */
%if &type=N %then
%sum(&rowvar);
%else %freq(&rowvar,&rowlist);
/* temp section label dataset */
data templ;
desc=&label2;
run;
/* append sections one by one, indent section and convert delimiter replacements
*/
data &outdsn;
length desc _1-_&ncol $100;
set &outdsn templ(in=a) temp2(in=b);
if a or b then
order=&i;
if b then
desc=' '||desc;
desc=tranwrd(tranwrd(tranwrd(desc,'(fs)','/'),'(pd)','#'),'(eq)','=');
run;
%let i=%eval(&i+1);
%end;
/* delete temp datasets */
proc datasets library=work;
delete temp:;
quit;
%mend wide;
... View more