Presentation is loading. Please wait.

Presentation is loading. Please wait.

Literate Programming in SAS

Similar presentations


Presentation on theme: "Literate Programming in SAS"— Presentation transcript:

1 Literate Programming in SAS
Bruce Schaalje Gauss June 2018

2 technical definition:
Literate Programming technical definition: programming paradigm in which program logic is given in a natural language, interspersed with source code. in practice: integration of report-creation code and statistical code to "create dynamic reports, which can be updated automatically if data or analysis change.1” 1 Leisch, 2002, “SWEAVE, Part 1”

3 Rajaram et al., 2017, “Automated Generation of Clinical Study Reports”

4 Rajaram et al., 2017, “Automated Generation of Clinical Study Reports”

5 Example Code *******************************************************;
****** automated analysis and report generation *******; ** specify report-specific names and parameter values *; %let project=Report 123; %let crop=Soybean; %let material=OK-999; %let matcode=1; %let reportname=literate example; %let control=OK-888; %let controlcode=1; %let nmat=25; %let nmatword=Twenty five; %let nref=23; %let nrep=2; %let year=1958; %let location=Iowa; %let statistician=Gertrude M. Cox, Senior Statistician; ********************************************************; ******** "here is the line" ****************************; ******* templates and formats **************************; /* This template creates rtf tables with Times New Roman 12 pt font, and margins of 1 inch on all four sides */ PROC TEMPLATE; DEFINE STYLE STYLES.required/STORE=WORK.RPTTABLE; PARENT = STYLES.JOURNAL; STYLE FONTS From FONTS/ 'SASTitleFont' = ("Times",12pt) 'TitleFont2' = ("Times",12pt) 'TitleFont' = ("Times",12pt) 'StrongFont' = ("Times",12pt) 'EmphasisFont' = ("Times",12pt) 'FixedEmphasisFont' = ("Times",12pt) 'FixedStrongFont' = ("Times",12pt) 'FixedHeadingFont' = ("Times",12pt) 'FixedFont' = ("Times",12pt) 'headingEmphasisFont' = ("Times",12pt) 'headingFont' = ("Times",12pt) 'docFont' = ("Times",12pt); REPLACE BODY FROM DOCUMENT / LEFTMARGIN = 1.3in RIGHTMARGIN = 1.0in TOPMARGIN = 1.0in BOTTOMMARGIN = 0.5in; STYLE CONTINUED FROM CONTINUED / PRETEXT=" " FONT=("ARIAL", 1pt) WIDTH=1%; STYLE PARSKIP FROM PARSKIP / FONT=("ARIAL", 1pt); END; RUN; ** create paragraph formats and ods escape character; %let textfont1=%str(^S={font_size=12pt font_face='Times Roman' just=c}); %let textfont2=%str(^S={font_size=12pt font_face='Times Roman' just=l font_weight=bold}); %let textfont3=%str(^S={font_size=12pt font_face='Times Roman' just=j}); %let textfont4=%str(^S={font_size=12pt font_face='Times Roman' just=c font_weight=bold}); %let textfont5=%str(^S={font_size=12pt font_face='Times Roman' just=l}); ods escapechar='^'; options nodate nonumber;

6 Example Code *********************************************************; *********** start ods rft document **********************; ods rtf style=required file="&reportname statistics report.rtf" NOTOC_DATA; footnote1 h=10pt j=l "{ABC Consulting}" j=c "{Page }^{pageof}" j=r "&project"; **********************************************************; ******* Specify titles, subtitles, and paragraphs. *******; **** Note: Line breaks can be inserted anywhere. *********; **** However, the next line must start with a space. *****; ************** report title and introduction *************; ods rtf text = "&textfont1 {Statistical Report}"; ods rtf text=" "; ods rtf text="&textfont4 {Evaluation of &crop &material in &year &location Field Trial}"; ods rtf text="&textfont1 {Study Number: &project}"; ods rtf text="&textfont2 {Purpose}"; ods rtf text=" "; ods rtf text="&textfont3 {The purpose of this analysis was to test whether the average yield of the test material &crop &material was different than the average yield of the conventional control &crop &control or the average yields of various reference materials.}"; ********************************************************; ************* Input and prepare data *******************; ods rtf text="&textfont2 {Data Description}"; {&nmatword materials were planted in &Location, with one test material (&material), one conventional control material (&control), and &nref reference materials. The experimental design was a 5x5 square lattice with &nrep complete replicates and 5 incomplete blocks per replicate. Yield data (bu/acre) were collected at harvest. Yield data were input directly into a SAS (SAS 2012) data set for statistical analysis.}"; data new; input rep block variety yield cards; run;

7 Example Code *******************************************************;
********** Statistical Methods and Results ************; ods rtf text=" "; ods rtf text="&textfont2 {Statistical Methods and Results}"; ods rtf text="&textfont3 {(1) Summary Statistics}"; {PROC MEANS in SAS was used to calculate means and standard deviations of yield for all experimental materials. The results are presented in Table 1. the relationship between the means and the standard deviations of the materials is displayed in Figure 1.}"; ********************************************************; ************** Means and Standard Deviations ***********; proc sort data=new; by variety rep; run; proc means data=new noprint; by variety; var yield; output out=m1 mean=mean std=std; *********************************************************; ****************** Statistical Analysis *****************; ods rtf text=" "; ods rtf text="&textfont3 {(2) Statistical Analysis}"; {The following statistical model was used to analyse the data:}"; y^{sub ijk} = ^S={font_face=symbol font_size=12pt}m + ^S={font_face='Times Roman' font_size=12pt}r^{sub i} + t^{sub j} + b^{sub k} + e^{sub ijk} (1) ^2n where y^{sub ijk} = yield (bu/acre); ^S={font_face=symbol font_size=12pt}m ^S={font_face='Times Roman' font_size=12pt} = overall mean; r^{sub i} = random replicate effect; t^{sub j} = fixed material effect; b^{sub ik} = random block effect; and e^{sub ijk} = residual effect."; {PROC MIXED was used to fit model (1) to the data. Comparisons between the test and other (control and reference) materials were defined within the SAS code, and tested using t-tests. The results of the comparisons are displayed in Table 2.}";

8 Example Code *********************************************************; ****************** statistical analysis *****************; ods exclude all; ods graphics on; proc mixed data=new; class rep block variety yield; model yield = variety / ddfm=kr; random rep block(rep); lsmeans variety / pdiff=all; ods output diffs=indcomps tests3=test; run; ods exclude none; /* Summarizing significance */ data test; set test; if Probf gt 0.05 then sig='not'; else sig =''; call symput('sig',sig); data inddiffs; set indcomps; if variety=&matcode; if Probt lt 0.05 then sig='*'; else sig =' '; if Probt lt 0.05 then signif=1; else signif=0; proc means noprint sum data=inddiffs; var signif; output out=s1 sum=sum n=n; data s1; set s1; call symput('sum',sum); call symput('n',n); ods rtf text=" "; ods rtf text="&textfont2{ Summary of statistical analysis results}"; ods rtf text="&textfont3 {Comparisons between the test and other materials revealed %left(&sum) significant differences out of %left(&n) tests (Table 2).}"; *********************************************************; ****************** insert references ********************; data null; x=" "; run; ods startpage=no; * used to start a new page the first time; proc report data=null nowd noheader style=[bordercolor=white]; column x; ods startpage=now; ods rtf text="&textfont2 {Reference}"; {SAS (2012). Software Release 9.4 (TS1M4). Cary, North Carolina, Copyright by SAS Institute, Inc.}";

9 Example Code *********************************************************; *************** insert tables with headings ************; ods startpage=now; ods rtf text="^S={font_size=12pt font_face='Times Roman' font_weight=bold} {Table 1. } ^S={font_size=12pt font_face='Times Roman'}{Summary Statistics for Yield Data}"; ods rtf text=" "; proc print noobs data=m1 label; format mean std 6.1; var variety mean std; label variety='Soybean Variety' mean='Mean Yield' std='Standard Deviation of Yield'; run; {Table 2. } ^S={font_size=12pt font_face='Times Roman'}{Statistical Comparisons of Varieties}"; proc print noobs data=inddiffs label; var _variety estimate stderr probt sig; label _variety='Soybean Variety' estimate='Difference from Control' stderr='Standard Error' probt='P-value' sig='Significant'; *******************************************************; ************** insert figure with caption ***********; ods startpage=now; ods rtf text="^S={font_size=12pt font_face='Times Roman' font_weight=bold} { Figure 1. } ^S={font_size=12pt font_face='Times Roman'} {Mean Versus Standard Deviation for Soybean Yields.}"; ods rtf text=" "; ODS graphics on / imagefmt=png noborder; footnote; proc sgplot data=m1; scatter y=mean x=std; reg y=mean x=std/nomarkers; run; footnote1 h=10pt j=l "{ABC Consulting}" j=c "{Page }^{pageof}" j=r "&project"; ods startpage=no;

10 Example Code **********************************************************; **************** insert signature page *******************; data signature; x=" "; y=" ";output; x=" "; y=" ";output; x="&statistician";y="Date";output; x="Statistics Team";y=" ";output; x="ABC Consulting";y=" ";output; run; ods startpage=now; ods rtf text="&textfont2 {SUBMITTED BY:}"; proc report data=signature nowd noheader style=[bordercolor=white] style=[paddingright=10] style=[cellpadding=0]; column x y; ods rtf close;

11 Example Output

12 Example Output

13 Example Output

14 Advantages of Literate Programming using SAS RTF
Fast SAS calculates statistics, creates report, creates tables, inserts tables, numbers pages, inserts footnotes, formats report Easy to revise (one step) Easy to create multiple similar reports Accurate No mistakes in inserting tables, no mistakes in page numbers and footnotes Universal name changes SAS can count and insert #tests, etc. Standardized format details can be enforced in all reports (justification, etc.)

15 Advantages of Literate Programming using SAS RTF
GLP friendly All calculations and revisions documented All other changes documented Grammar friendly Document can be word-smithed and locked Protocol friendly Accurate details of protocol can be specified using %let statements Flexible Can be adapted to various degrees of automation

16 Disadvantages of Literate Programming using SAS RTF
Initial setup time “above the line” details have to be specified text must be initially inserted into SAS formatting details must be added Learning curve for ODS text, formatting, escape characters pretty good guidance in SUGI reports SAS documentation not-so-good

17 Disadvantages of Literate Programming using SAS RTF
Some quirky things about SAS ODS RTF but all can be solved or worked around

18 Useful References To ODS RTF and Beyond SAS – tricks and tips
SAS Guide to Report Writing Automated Generation of Reports Reproducible RTF memos

19 Thank You


Download ppt "Literate Programming in SAS"

Similar presentations


Ads by Google