Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*=============================================================================
- Project Information
- -------------------------------------------------------------------------------
- Customer Name : Novartis
- Protocol Number : QVA149A2349/QVA149A2350
- Project Code : OXA69155/OXA69156
- Study Drug : QVA149\Indacaterol maleate\Glycopyrronium bromide
- Project Root Path : \Novartis\QVA149\OXA69155
- ------------------------------------------------------------------------------
- Program Information
- -------------------------------------------------------------------------------
- Program : ..\OXA69155\Biostatistics\Production\Macro\m_descr.sas
- Brief Description : Macro for derivation of descriptive statistics
- Copied From : \Client\Compound\Study\Biostatistics\...
- Raw Data Sets Used : \Data\CDM_Data\ [...]
- \Data\SDTM\ [...]
- \Data\External\ [...]
- \Data\PK_Data\ [...]
- \Data\Coding_Dictionaries\ [...]
- Derived Data Sets Used : \Data\Derived\ []
- Data Set Created : \Data\Derived\ [...]
- \Data\QC_Derived\ [...]
- Output Files : \Output\Production_Out\ []
- \Output\QC_Out\ [...]
- Notes / Assumptions : dsin - input dataset; must have vertical structure
- : dsout - output dataset
- : param - parameter name (stats are calculated by parameter)
- : valuen - variable containing numeric result of corresponding parameter
- : by - name of by-variable (e.g. by=TRTSEQP if stats needed by treatment group)
- : keep_stat - which descriptive stats to keep in &dsout.
- Default are n,mean,sd,min,max,median,missing,q1 and q3
- : dp_var - variable containing number of decimal points expected per parameter.
- If &dp_var left blank, macro will calculate it as maximum DP in the
- current data, perparameter, and will use it for rounding and formatting.
- Set to dp_var=base for baseline tables with fixed DP
- (1dp for min/max, mean and med, 2dp for SE and std).
- : missing - set to missing=y to force display "missing" row for each parameter (¶m).
- -------------------------------------------------------------------------------
- Programmer Information
- -------------------------------------------------------------------------------
- Author : Tetiana Batrak [Q819473]
- Creation Date : 16MAY2016
- -------------------------------------------------------------------------------
- Environment Information
- -------------------------------------------------------------------------------
- SAS Version : SAS V9.4 (TS Level 2M3)
- Operating System : Windows Server 2008 R2
- -------------------------------------------------------------------------------
- Change Control Information
- -------------------------------------------------------------------------------
- Modifications :
- Programmer/Date :
- Reason :
- ==============================================================================*/
- options mprint mlogic;
- %macro m_descr( dsin=,
- dsout=,
- valuen=,
- param=,
- by=,
- dp_var=,
- missing=,
- keep_stat=%quote('N' 'MEAN' 'SD' 'MIN' 'MEDIAN' 'MAX' 'MISSING' 'UPPERCL' 'LOWERCL' 'Q25' 'Q75')
- );
- proc sort data=&dsin; by &by ¶m;
- run;
- options linesize=max;
- ods output BasicIntervals=ci;
- ods listing close;
- proc univariate data=&dsin cibasic;
- var &valuen;
- by &by ¶m;
- output out=stat1_ n=n1 mean=mean1 std=sd1 STDMEAN=se1 min=min1 max=max1
- pctlpts=25 50 75 pctlpre=pct pctlname=_25 _50 _75 nmiss=nmiss1;
- run;
- ods listing;
- options linesize=138;
- proc sort data=stat1_ out=stat1a_;
- by &by ¶m;
- run;
- proc sort data=ci;
- by &by ¶m;
- run;
- data stat1;
- merge ci(where=(parameter="Mean")keep=parameter ¶m &by lowercl uppercl) stat1a_;
- by &by ¶m;
- run;
- /***----------------------------------------***/
- /*** check number of decimals per parameter ***/
- /*** (select max DP collected in the data) ***/
- /*** and create dynamic format ***/
- /***----------------------------------------***/
- %if &dp_var= %then %do;
- data dp1;
- set &dsin;
- if not missing(&valuen) then valuec=put(&valuen,best.);
- run;
- data dp2;
- set dp1;
- if index(valuec,'.')>0 then dp=length(compress(scan(valuec,2,'.')));
- else dp=0;
- run;
- proc sql;
- create table dp_fmt as
- select distinct ¶m as start, start as end, max(dp) as dp,
- case when max(dp)=0 then put(6+(max(dp)/10),best.)
- when max(dp)>0 then put(7+max(dp)+(max(dp)/10),best.)
- else " "
- end as label,
- 'C' as type, 'DP' as fmtname length=20
- from dp2
- group by ¶m
- ;
- quit;
- proc format cntlin=dp_fmt;
- run;
- %end;
- %else %if &dp_var ne base %then %do;
- proc sql;
- create table dp_fmt as
- select distinct ¶m as start, start as end, max(&dp_var) as dp,
- case when max(&dp_var)=0 then put(6+(max(&dp_var)/10),best.)
- when max(&dp_var)>0 then put(7+max(&dp_var)+(max(&dp_var)/10),best.)
- else " "
- end as label,
- 'C' as type, 'DP' as fmtname length=20
- from &dsin
- group by ¶m
- ;
- quit;
- proc format cntlin=dp_fmt;
- run;
- %end;
- /***----------------------------------------***/
- /*** apply formats and create final dataset ***/
- /***----------------------------------------***/
- data stat2;
- set stat1;
- length _mean _sd _se _min _pct_25 _pct_50 _pct_75 _max _upper _lower $200;
- %if &dp_var=base %then %do;
- if n(mean1)=1 then _mean=put(round(mean1,.1),8.1);
- if n(sd1)=1 then _sd=put(round(sd1,.01),9.2);
- if n(se1)=1 then _se=put(round(se1,.01),9.2);
- if n(min1)=1 then _min=put(round(min1,.1),8.1);
- if n(pct_25)=1 then _pct_25=put(round(pct_25,.1),8.1);
- if n(pct_50)=1 then _pct_50=put(round(pct_50,.1),8.1);
- if n(pct_75)=1 then _pct_75=put(round(pct_75,.1),8.1);
- if n(max1)=1 then _max=put(round(max1,.1),8.1);
- if n(uppercl)=1 then _upper=put(round(uppercl,.1),8.1);
- if n(lowercl)=1 then _lower=put(round(lowercl,.1),8.1);
- %end;
- %else %do;
- fmt=put(¶m,dp.);
- if index(fmt,'.')>0 then dp=input(scan(fmt,2,'.'),best.);
- else dp=0;
- if dp>0 then do;
- fmt_mean=put(input(fmt,best.)+1.1,best.);
- fmt_sd=put(input(fmt,best.)+2.2,best.);
- end;
- else if dp=0 then do;
- fmt_mean=put(input(fmt,best.)+2.1,best.);
- fmt_sd=put(input(fmt,best.)+3.2,best.);
- end;
- if not missing(mean1) then _mean =putn(round(mean1,10**-(dp+1)),fmt_mean);
- if not missing(sd1) then _sd =putn(round(sd1,10**-(dp+2)),fmt_sd);
- if not missing(se1) then _se =putn(round(se1,10**-dp),fmt_sd);
- if not missing(min1) then _min =putn(round(min1,10**-dp),fmt);
- if not missing(pct_50) then _pct_50=putn(round(pct_50,10**-(dp+1)),fmt_mean);
- if not missing(max1) then _max =putn(round(max1,10**-dp),fmt);
- if not missing(uppercl) then _upper =putn(round(uppercl,10**-dp),fmt_mean);
- if not missing(lowercl) then _lower =putn(round(lowercl,10**-dp),fmt_mean);
- if not missing(pct_25) then _pct_25=putn(round(pct_25,10**-(dp+1)),fmt_mean);
- if not missing(pct_75) then _pct_75=putn(round(pct_75,10**-(dp+1)),fmt_mean);
- %end;
- _n=put(n1,6.);
- _nmiss=put(nmiss1,6.);
- keep ¶m &by _: ;
- run;
- proc sort data=stat2; by &by ¶m;
- run;
- proc transpose data=stat2/*(%if &by ne %then %do; where=(not missing(&by)) %end;)*/ out=stat3;
- by &by ¶m;
- var _: ;
- run;
- data &dsout;
- length stat $100;
- set stat3;
- if _name_='_N' then do; stat='n'; ord_stat=1; end;
- if _name_='_MEAN' then do; stat='Mean'; ord_stat=2; end;
- if _name_='_SD' then do; stat='SD'; ord_stat=3; end;
- if _name_='_SE' then do; stat='SE'; ord_stat=4; end;
- if _name_='_MIN' then do; stat='Min'; ord_stat=5; end;
- if _name_='_PCT_25' then do; stat='Q25'; ord_stat=6; end;
- if _name_='_PCT_50' then do; stat='Median'; ord_stat=7; end;
- if _name_='_PCT_75' then do; stat='Q75'; ord_stat=8; end;
- if _name_='_MAX' then do; stat='Max'; ord_stat=9; end;
- if _name_='_MIN_MAX' then do; stat='Min - Max'; ord_stat=10; end;
- if _name_='_NMISS' then do; stat='Missing'; ord_stat=11; end;
- if _name_='_UPPER' then do; stat='UpperCL'; ord_stat=12; end;
- if _name_='_LOWER' then do; stat='LowerCL'; ord_stat=13; end;
- %if &missing= %then %do;
- if _name_='_NMISS' and compress(col1)='0' then delete;
- %end;
- drop _name_;
- if upcase(stat) not in (&keep_stat) then delete;
- run;
- %mend m_descr;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement