Date: Mon, 5 Oct 2009 17:25:54 -0700
Reply-To: xlr82sas <xlr82sas@AOL.COM>
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: xlr82sas <xlr82sas@AOL.COM>
Organization: http://groups.google.com
Subject: Re: Clinical Trials Reporting.
Content-Type: text/plain; charset=ISO-8859-1
On Sep 30, 2:01 pm, iebup...@GMAIL.COM ("Data _null_;") wrote:
> * Goals:
> * 1) Use standard SAS meta data objects, FORMATS LABELS.
> * 2) Dynamic, with regards to input
> * a) levels of column variable
> * b) column variable type
> * c) number of analysis variables.
> * d) just need the names
> * 3) No references to the values of a variable,
> * In order words we don't need to know any value of any variable
> * 4) Reasonable looking CT table.
> * 5) Code can be reused, more specifically the technique
> * 6) Combine into one table cell MEAN(SD) and MIN, MAX.
> ;
>
> * Assumptions:
> * 1) Formatted value of column variable will provide column labels
> * 2) Internal value of column variable determines the column order
> * 3) No variables from input data begin with "COL"
> ;
> proc format;
> value $sex 'F'='Female' 'M'='Male';
> value sex 1 ='Female' 2 ='Male';
> run;
> data work.ADSL;
> set sashelp.class;
> sexN = index('MF',sex);
> format age F3.0 height 6.1 weight Comma7.2 sex $sex. sexN sex.;
> attrib sex: label='Treatment' ;
> *rename sexN=sex sex=sexC; /*un-comment to test SEX numeric*/
> run;
> proc contents varnum;
> proc print;
> format _all_;
> run;
>
> * Specify the analysis variables and column variable;
> %let trt = sex;
> %let vars = age--weight;
>
> * Expand the (VARS) variable list, and make a FORMAT statement
> argument for MEAN, STD and MEDIAN;
> * To display those statistics with one more decimal place than the
> format assiociated with the variable;
> proc transpose data=work.adsl(obs=0) out=vars;
> var &vars;
> run;
> data work.vars(index=(_name_));
> set work.vars end=eof;
> vorder = _n_;
> vformatN = vformatNX(_name_);
> vformatD = vformatdX(_name_);
> length fmt1 $16.;
> fmt1 = cats(vformatN,12,'.',vformatD+1);
> return;
> set work.adsl(keep=&vars);
> drop &vars;
> run;
> proc sql noprint;
> select _name_, catx(' ',_name_, fmt1) into :vars separated by ' ',
> :fmt1 separated by ' ' from work.vars;
> quit;
> run;
> %put NOTE: VARS=&vars;
> %put NOTE: FMT1=&fmt1;
>
> ** Compute summary statistics;
> proc summary data=work.ADSL nway completetypes;
> class sex / preloadfmt;
> var &vars;
> output out=work.stats(drop=_type_);
> output out=work.median(drop=_type_) median=;
> run;
> proc format;
> invalue statord(upcase just) 'N'=1 'MEAN'=2 'STD'=4 'MEDIAN'=4
> 'MIN'=5 'MAX'=5;
> invalue statgrp(upcase just) 'N'=1 'MEAN','STD'=2 'MEDIAN'=3 'MIN','MAX'=4;
> value statgrp 1='N' 2='Mean (SD)' 3='Median' 4='Min, Max';
> run;
>
> data stats;
> set stats median(in=in2);
> by sex;
> if in2 then _STAT_ = 'MEDIAN';
> order = input(_stat_,statord.);
> retain dummy '12345678';
> run;
>
> proc transpose data=stats out=stat1;
> by sex _freq_ _stat_ order notsorted;
> where _stat_ eq 'N';
> var &vars dummy;
> format &vars 12.;
> run;
> proc transpose data=stats out=stat2;
> by sex _freq_ _stat_ order notsorted;
> where _stat_ in('MIN','MAX');
> var &vars dummy;
> run;
> proc transpose data=stats out=stat3;
> by sex _freq_ _stat_ order notsorted;
> where _stat_ in('MEAN','STD','MEDIAN');
> var &vars dummy;
> format &fmt1;
> run;
> data work.stats;
> set work.stat1 work.stat2 work.stat3;
> where upcase(_name_) ne 'DUMMY';
> attrib statgrp length=8 format=statgrp. label='Statistic';
> statgrp = input(_stat_,statgrp.);
> col1 = left(col1);
> format statgrp statgrp.;
> run;
> proc sort;
> by _name_ sex _freq_ statgrp order _stat_;
> run;
> proc transpose data=work.stats out=work.stats;
> by _name_ sex _freq_ statgrp;
> var col1;
> run;
> data stats;
> set stats;
> length cell $32;
> select(statgrp);
> when(2) cell = catx(' ',col1,cats('(',col2,')'));
> when(4) cell = catx(', ',col1,col2);
> otherwise cell = col1;
> end;
> * Create column header for the "treatment" columns;
> length label $64;
> label = catx('~',vvalue(sex),cats('(N=',_freq_,')'));
> * Variable order;
> set vars(keep=_name_ vorder) key=_name_/unique;
> drop col:;
> run;
> proc sort;
> by vorder _name_ statgrp sex;
> run;
> proc transpose data=stats out=display prefix=col_;
> by vorder _name_ statgrp;
> var cell;
> id sex;
> format sex;
> idlabel label;
> run;
> proc contents varnum;
> run;
> proc print;
> format _all_;
> run;
>
> ods rtf file='demogTable01.rtf';
> ods listing close;
> title 'Table 14-1.2.3b';
> title2 'Summary of Age, Height and Weight';
> proc report list nowd data=display headline split='~';
> column vorder _name_ statgrp col_:;
> define vorder / order noprint;
> define _name_ / order 'Variable';
> define statgrp / order order=internal 'Statistic' width=10 style=[just=left];
>
> define col_: / display style(column)=[just=center];
> * conditional blank lines;
> compute before _name_;
> n + 1;
> if n gt 1 then l=1; else l=0;
> text = ' ';
> line text $varying1. l;
> endcomp;
> run;
> ods rtf close;
> ods listing;
> title;
Nice Job
Avoiding the macro language is a good practice and your code is more
dynamic.
I am trying to employ some of your techniques in my 'program
templates'.
You got the key elements, variable ordering, N= in column header and
number of decimals.
Most of these techniques can be used in pharma reports.
Thanks
I am working on a new tip using these techiques, I will give you
credit.
Thanks for the education!
|