/*-------------------------------------------------------------------------*/ /*--Forest Plot for CTSPedia --*/ /*--SAS 9.2 release or later --*/ /*--Name: Sanjay Matange --*/ /*--Company: SAS Institute Inc. --*/ /*--Date : 06Aug 2012 --*/ /*--History: 06Aug2012/SNM - Add horizontal bands. --*/ /*-- 06Sep2012/SNM - Full Width horizontal bands. --*/ /*-- 06Jan2013/SNM - Font weight and color for subgroup headers.--*/ /*-------------------------------------------------------------------------*/ /*--CTSPedia General AE G1 Forest Plot--*/ %let gpath=''; ods html close; /*--To retain leading and trailing blanks, we must use nbsp instead of blank--*/ /*--For visibility, we have used '.' in place of blanks --*/ /*-- Later these '.' values are changed to nbsp 'A0'x --*/ /*--Regular leading blanks will be stripped, losing the indentation --*/ /*--Add "Id" to identify subgroup headings from values --*/ data forest; input Id Subgroup $3-27 Count Percent Mean Low High PCIGroup Group PValue; zero=0; PCI_lbl='PCI Group'; grp_lbl='Group'; pval_lbl='P Value'; ObsId=_n_; if count ne . then CountPct=put(count, 4.0) || "(" || put(percent, 3.0) || ")"; datalines; 1 Overall..................2166 100 1.3 0.9 1.5 17.2 15.6 . 1 Age....................... . . . . . . 0.05 2 ..<= 65 Yr...............1534 71 1.5 1.05 1.9 17.0 13.2 . 2 ..> 65 Yr................ 632 29 0.8 0.6 1.25 17.8 21.3 . 1 Sex....................... . . . . . . 0.13 2 ..Male...................1690 78 1.5 1.05 1.9 16.8 13.5 . 2 ..Female................. 476 22 0.8 0.6 1.3 18.3 22.9 . 1 Race or ethnic group...... . . . . . . 0.52 2 ..Nonwhite............... 428 20 1.05 0.6 1.8 18.8 17.8 . 2 ..White..................1738 80 1.2 0.85 1.6 16.7 15.0 . 1 From MI to Randomization.. . . . . . . 0.81 2 ..<= 7 days.............. 963 44 1.2 0.8 1.5 18.9 18.6 . 2 ..> 7 days..............1203 56 1.15 0.75 1.5 15.9 12.9 . 1 Infract-related artery.... . . . . . . 0.38 2 ..LAD.................... 781 36 1.4 0.9 1.9 20.1 16.2 . 2 ..Other..................1385 64 1.1 0.8 1.4 15.6 15.3 . 1 Ejection Fraction......... . . . . . . 0.48 2 ..< 50%..................1151 54 1.2 0.8 1.5 22.6 20.4 . 2 ..>= 50%................. 999 46 0.9 0.6 1.4 10.7 11.1 . 1 Diabetes.................. . . . . . . 0.41 2 ..Yes.................... 446 21 1.4 0.9 2.0 29.3 23.3 . 2 ..No.....................1720 79 1.1 0.8 1.5 14.4 13.5 . 1 Killip class.............. . . . . . . 0.39 2 ..I......................1740 81 1.2 0.8 1.6 15.2 13.1 . 2 ..II-IV.................. 413 19 0.95 0.6 1.5 25.3 26.9 . ; run; ods listing; /*proc print;run;*/ /*--Replace '.' in subgroup with nbsp 'A0'x --*/ /*--Move subgroup headings into separate column--*/ data forest2; set forest; subgroup=translate(subgroup, 'A0'x, '.'); val=mod(_N_-1, 6); if val eq 1 or val eq 2 or val eq 3 then ref=obsid; /*--Move Subgroup headers into separate columns--*/ if id=1 then do; heading=subgroup; subgroup=''; end; run; /*proc print;run;*/ /*--Create font with smaller fonts for axis label, value and data--*/ proc template; define style listingSF; parent = Styles.Listing; style GraphFonts from GraphFonts "Fonts used in graph styles" / 'GraphDataFont' = (", ",7pt) 'GraphValueFont' = (", ",7pt) 'GraphLabelFont' = (", ",7pt, bold); ; end; run; %let dpi=150; ods listing style=listingSF gpath=&gpath image_dpi=&dpi; /*--Define templage for Forest Plot--*/ /*--Template uses a Layout Lattice of 5 columns--*/ proc template; define statgraph Forest; dynamic _bandcolor _headercolor _subgroupcolor; begingraph; layout lattice / columns=4 columnweights=(0.23 0.07 0.4 0.3); /*--Column headers--*/ sidebar / align=top; layout lattice / rows=2 columns=4 columnweights=(0.18 0.17 0.35 0.3) backgroundcolor=_headercolor opaque=true; entry textattrs=(size=8 weight=bold) halign=left "Subgroup"; entry textattrs=(size=8 weight=bold) " No.of Patients (%)"; entry textattrs=(size=8 weight=bold) "Hazard Ratio"; entry halign=center textattrs=(size=8 weight=bold) "4-Yr Cumulative Event Rate" ; entry " "; entry " "; entry " "; entry halign=center textattrs=(size=6) "Medical Therapy"; endlayout; endsidebar; /*--First Subgroup column, shows only the Y2 axis--*/ layout overlay / walldisplay=none xaxisopts=(display=none) yaxisopts=(reverse=true display=none tickvalueattrs=(weight=bold)); referenceline y=ref / lineattrs=(thickness=15 color=_bandcolor); scatterplot y=obsid x=zero / markercharacter=subgroup markercharacterattrs=(family='Lucida Console' size=6); scatterplot y=obsid x=zero / markercharacter=heading markercharacterattrs=(family='Lucida Console' size=6 color=_subgroupcolor weight=bold); endlayout; /*--Second column showing Count and percent--*/ layout overlay / xaxisopts=(display=none) yaxisopts=(reverse=true display=none) walldisplay=none; referenceline y=ref / lineattrs=(thickness=15 color=_bandcolor); scatterplot y=obsid x=zero / markercharacter=countpct markercharacterattrs=graphvaluetext; endlayout; /*--Third column showing odds ratio graph--*/ layout overlay / xaxisopts=(label=' <---PCI Better---- ----Medical Therapy Better--->' linearopts=(tickvaluepriority=true tickvaluelist=(0.0 0.5 1.0 1.5 2.0 2.5))) yaxisopts=(reverse=true display=none) walldisplay=none; referenceline y=ref / lineattrs=(thickness=15 color=_bandcolor); scatterplot y=obsid x=mean / xerrorlower=low xerrorupper=high markerattrs=(symbol=squarefilled); referenceline x=1; endlayout; /*--Fourth column showing PCIGroup and Group columns--*/ layout overlay / x2axisopts=(display=(tickvalues) offsetmin=0.25 offsetmax=0.25) yaxisopts=(reverse=true display=none) walldisplay=none; referenceline y=ref / lineattrs=(thickness=15 color=_bandcolor); scatterplot y=obsid x=pci_lbl / markercharacter=PCIGroup xaxis=x2 markercharacterattrs=graphvaluetext; scatterplot y=obsid x=grp_lbl / markercharacter=group xaxis=x2 markercharacterattrs=graphvaluetext; scatterplot y=obsid x=pval_lbl / markercharacter=pvalue xaxis=x2 markercharacterattrs=graphvaluetext; endlayout; endlayout; entryfootnote halign=left textattrs=(size=7) 'The p-value is from the test statistic for testing the interaction between the ' 'treatment and any subgroup variable'; endgraph; end; run; /*--Render Forest Plot without horizontal bands--*/ ods graphics / reset width=7in height=5in imagename='Forest_92'; proc sgrender data=Forest2 template=Forest; dynamic _bandcolor='white' _headercolor='white'; run; /*--Render Forest Plot with horizontal bands--*/ ods graphics / reset width=7in height=5in imagename='Forest_Ref_92'; proc sgrender data=Forest2 template=Forest; dynamic _bandcolor='cxf0f0f0' _headercolor='cxd0d0d0'; run; /*--Render Forest Plot with horizontal bands and subgroupcolor--*/ ods graphics / reset width=7in height=5in imagename='Forest_Ref_Sub_92'; proc sgrender data=Forest2 template=Forest; dynamic _bandcolor='cxf0f0f0' _headercolor='cxd0d0d0' _subgroupcolor='cx0000a0'; run;