The original paper can be found here:
Base SAS: GTL Template Language
SAS 9.4 GTL feature: Value statement's TextAttrs option
%let graphs='.';
%let dpi=100;
%let w=8in;
%let h=4.5in;
/*--Leading blanks in the subgroup variable must be non--blank spaces --*/
/*--Use character value 'A0', or copy from Windows System Character Map--*/
/*--Regular leading blanks will be stripped, losing the indentation --*/
data forest;
input Indent Subgroup $3-27 Count Percent Mean Low High PCIGroup Group PValue;
format PCIGroup Group PValue 7.2;
zero=0;
if count ne . then CountPct=put(count, 4.0) || "(" || put(percent, 3.0) || ")";
datalines;
0 Overall..................2166 100 1.3 0.9 1.5 17.2 15.6 .
0 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 .
0 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 .
0 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.6 1.6 16.7 15.0 .
0 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 .
0 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 .
0 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 .
0 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 .
0 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;
/*--Replace '.' in subgroup with blank--*/
data forest2;
set forest;
subgroup=translate(subgroup, ' ', '.');
val=mod(_N_-1, 6);
indent=ifn(indent eq 2, 1, 0);
if val eq 1 or val eq 2 or val eq 3 then ref=subgroup;
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' = (", ",6pt)
'GraphLabelFont' = (", ",6pt, bold);
end;
run;
/*--Define templage for Forest Plot--*/
/*--Template uses a Layout Lattice of 6 columns--*/
proc template;
define statgraph Forest;
dynamic _show_bands _color _thk;
begingraph;
entrytitle 'Forest Plot of Hazard Ratios by Patient Subgroups ';
discreteattrmap name='text';
value '0' / textattrs=(weight=bold);
value other;
enddiscreteattrmap;
discreteattrvar attrvar=type var=indent attrmap='text';
layout lattice / columns=6 columnweights=(0.25 0.1 0.4 0.08 0.08 0.09);
/*--Column headers--*/
sidebar / align=top;
layout lattice / rows=2 columns=4 columnweights=(0.2 0.25 0.25 0.3);
entry textattrs=(size=8) halign=left "Subgroup";
entry textattrs=(size=8) halign=left " No.of Patients (%)";
entry textattrs=(size=8) halign=left "Hazard Ratio";
entry halign=center textattrs=(size=8) "4-Yr Cumulative Event Rate" ;
entry " ";
entry " ";
entry " ";
entry halign=center textattrs=(size=8) "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=_thk color=_color);
axistable y=subgroup value=subgroup / indentweight=indent textgroup=type;
endlayout;
/*--Second column showing Count and percent--*/
layout overlay / xaxisopts=(display=none)
yaxisopts=(reverse=true display=none) walldisplay=none;
referenceline y=ref / lineattrs=(thickness=_thk color=_color);
axistable y=subgroup value=countpct;
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=_thk color=_color);
scatterplot y=subgroup x=mean / xerrorlower=low xerrorupper=high
markerattrs=(symbol=squarefilled);
referenceline x=1;
endlayout;
/*--Fourth column showing PCIGroup--*/
layout overlay / x2axisopts=(display=(tickvalues) offsetmin=0.25 offsetmax=0.25)
yaxisopts=(reverse=true display=none) walldisplay=none;
referenceline y=ref / lineattrs=(thickness=_thk color=_color);
axistable y=subgroup value=PCIGroup / display=(label) labelposition=max;
endlayout;
/*--Fifth column showing Group--*/
layout overlay / x2axisopts=(display=(tickvalues) offsetmin=0.25 offsetmax=0.25)
yaxisopts=(reverse=true display=none) walldisplay=none;
referenceline y=ref / lineattrs=(thickness=_thk color=_color);
axistable y=subgroup value=group / display=(label) labelposition=max;
endlayout;
/*--Sixth column showing P-Values--*/
layout overlay / x2axisopts=(display=(tickvalues) offsetmin=0.25 offsetmax=0.25)
yaxisopts=(reverse=true display=none) walldisplay=none;
referenceline y=ref / lineattrs=(thickness=_thk color=_color);
axistable y=subgroup value=pvalue / display=(label) labelposition=max;
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';
entryfootnote halign=left 'This graph uses the new AXISTABLE plot to display the textual columns';
endgraph;
end;
run;
/*--Need format to show missing as blank--*/
proc format;
value misblank
. = ' ';
run;
/*----Create Graph-----*/
ods listing style=htmlblue gpath=&graphs image_dpi=&dpi;
ods graphics / reset noscale width=&w height=&h imagename='GTL_ForestPlot';
proc sgrender data=Forest2 template=Forest;
format pvalue group pcigroup misblank7.2;
dynamic _color='cxf0f0f0' _thk=12;
run;
No comments:
Post a Comment