FOCUS AREAS

Graphics

forest plot
Base SAS: Graph Template Language

/* This program requires SAS 9.4 TS Level 1M2 or later */
%let gpath='.';
%let dpi=100;

/*--Create Forest Plot data--*/
data forest;
  input Indent Subgroup $3-27 Count Percent Mean  Low  High
        PCIGroup Group PValue;
  format PCIGroup Group PValue 7.2;

  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.85  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   . 
;
run;

ods html close;
ods listing;

/* Add in reference "band" data */
data forest2;
  set forest;
  if mod(_N_-1, 6) in (1, 2, 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' = (", ", 6 pt, bold); 
  end;
run;

/*--Define templage for Forest Plot--*/
/*--Template uses a Layout Lattice of 5 columns--*/
proc template;
  define statgraph Forest;
    dynamic _color;
    begingraph / designHeight=6in designWidth=8in;
      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.35 0.1 0.1 0.1);

        /*--Column headers--*/
        sidebar / align=top;
          layout lattice / columns=4 columnweights=(0.2 0.25 0.2 0.35);
            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";
            /* Dummy entries */
            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=10 color=_color);
          axistable y=subgroup value=subgroup / indentweight=indent
            textgroup=type display=(values);
        endlayout;

        /*--Second column showing Count and percent--*/
        layout overlay / xaxisopts=(display=none) 
            yaxisopts=(reverse=true display=none) walldisplay=none;
          referenceline y=ref / lineattrs=(thickness=10 color=_color);
          axistable y=subgroup value=countpct / display=(values);
        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=10 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=10 color=_color);
          axistable y=subgroup value=PCIGroup / showmissing=false;
        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=10 color=_color);
          axistable y=subgroup value=group / showmissing=false;
        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=10 color=_color);
          axistable y=subgroup value=pvalue / showmissing=false;
        endlayout;

      endlayout;
      entryfootnote halign=left  
        'The p-value is from the test statistic for testing the interaction between the '
        'treatment and any subgroup variable' / textAttrs=GraphValueText;
    endgraph;
  end;
run;

ods _all_ close;
ods listing gpath=&gpath image_dpi=&dpi style=listingSF;

ods graphics / reset imagename='V94_ForestPlot' width=6.93in height=3.15in;
proc sgrender data=Forest2 template=Forest;
  dynamic _color='cxf0f0f0';
run;

ods _all_ close;