%macro calcmean(din=, var=, dec=1, ord=, rowlbl=, blankrow=Y, dout=); %if &dout eq %then %do; %let dout=summ&ord.; %end; proc means data=&din noprint ; var &var; by trt01pn; output out=mn0_&ord. n=n mean=mean std=std min=min max=max median=median p25=p25_ p75=p75_; run; data mn1_&ord.; set mn0_&ord.; length nstr mnstr medstr qrtstr $30; nstr=strip(put(n,best.)); if n=0 then do; mnstr='n/a (n/a)'; medstr='n/a (n/a - n/a)'; qrtstr='n/a, n/a'; end; else if n>0 then do; mnstr=strip(put(mean,8.&dec.))||' ('||strip(put(std,8.%eval(&dec.+1)))||')'; if index(mnstr, '()') then mnstr=tranwrd(mnstr, '()', '(n/a)'); medstr=strip(put(median,8.&dec.))||' ('||strip(put(min,8.%eval(&dec.-1))) ||' - '||strip(put(max,8.%eval(&dec.-1)))||')'; qrtstr=strip(put(p25_,8.&dec.))||', '||strip(put(p75_,8.&dec.)); end; run; /* proc sort data=mn2; by &var; run;*/ proc transpose data=mn1_&ord. out=mnt_&ord. prefix=col; id trt01pn; var nstr mnstr medstr qrtstr; run; data header_; length rowlbl $1000; ord=⩝ ord2=0; blnkfl='Y'; rowlbl="&rowlbl"; run; data &dout; set header_ mnt_&ord.; length rowlbl $1000; ord=⩝ if upcase(_name_)='NSTR' then do; ord2=1; rowlbl=' n'; end; else if upcase(_name_)='MNSTR' then do; ord2=2; rowlbl=' Mean (SD)'; end; else if upcase(_name_)='MEDSTR' then do; ord2=3; rowlbl=' Median (Range)'; end; else if upcase(_name_)='QRTSTR' then do; ord2=4; rowlbl=' 25th, 75th Percentiles'; end; run; %if &blankrow eq Y %then %do; data blankrow; ord=⩝ ord2=999; blnkfl='Y'; run; data &dout; set &dout(in=a) blankrow(in=b); run; %end; %mend calcmean;