Solved
New Contributor
Posts: 3

# A problem of row space in the forest plot

Dear all,

I followed the example from SAS to create a forest plot.

But there seems a "double-space" condition in my graphic.

Thank you very much!

Please find the attachment for my graphic, and

Here is my program:

``````/*--Add "Id" to identify methods headings from values                      --*/
data forest;
input Id methods \$3-20 Countpct \$22-40 HR  lci  hci;
indentWt=1;
ObsId=_n_;
datalines;
1	Primary analysis	0.64 (0.43-0.95)	0.64	0.43	0.95
1	Grace period		.	                .	.       .
2	60 days	                0.70 (0.49-1.01)	0.7	0.49	1.01
2	90 days	                1.06 (0.86-1.32)	1.06	0.86	1.32
1	Age groups		    .	                .	.       .
2	<=65 years	        0.43 (0.19-0.93)	0.43	0.19	0.93
2	>65 years	        0.69 (0.44-1.08)	0.69	0.44	1.08
1	Gender		        .	                .	.       .
2	Female	                0.69 (0.43-1.10)	0.69	0.43	1.1
2	Male	                0.57 (0.28-1.15)	0.57	0.28	1.15
1	CVD history		.	                .	.       .
2	Without	                0.69 (0.43-1.08)	0.69	0.43	1.08
2	With	                0.50 (0.24-1.06)	0.5	0.24	1.06
;
run;

data forest2;
set forest;
/*if count ne . then CountPct=put(count, 4.0) || "(" || put(percent, 3.0) || ")";*/
if mod(obsId-1, 6) in (1, 2, 3) then ref=obsId;
/* Reduce indent for methods heading */
if id=1 then indentWt=0;
run;

/**
* Forest plot template using a one-column outermost lattice layout.
* The header uses a nested lattice layout in the top side bar.
* An overlay layout makes up the main area belci it.
* The left side table of values are axis tables placed inside
* inner margin of the overlay layout.
*/
proc template;
define statgraph forestAxisTable;
begingraph;

value '1' / textAttrs=(size=7 weight=bold);
value '2' / textAttrs=(color=gray size=6 weight=normal);
enddiscreteattrmap;

discreteattrvar attrvar=txtDAV var=id attrmap='text';

layout lattice / columns=1;

sidebar / align=top;
layout lattice / columns=2 rowweights=uniform columnweights=(0.35 0.65)
entry textAttrs=(size=8 weight=bold) hAlign=left "Methods"
hAlign=right " HR (95% CI)";
entry textAttrs=(size=8 weight=bold) "Hazard Ratio";
endLayout;
endsidebar;

/* Single cell with inner margins for left and right tables */
layout overlay / xAxisOpts=(display=(line ticks tickvalues)
tickValueAttrs=(size=6 weight=bold)
labelAttrs=(size=6 weight=bold)
linearOpts=(tickValuePriority=true
tickValueList=(0.0 0.5 1.0 1.5 2.0))
offsetMin=0.1
)
yAxisOpts=(reverse=true display=none offsetMin=0) wallDisplay=none;

/* Left-side table */
innerMargin / align=left gutter=0.1in;
axisTable y=obsId value=Methods / textGroup=txtDAV
indentWeight=indentwt display=(values);
axisTable y=obsId value=CountPct /  display=(values);
endInnerMargin;

/* Odds Ratio plot */
referenceLine y=ref / lineAttrs=(thickness=15 color=_bandColor);
scatterPlot y=obsId x=HR / markerAttrs=(symbol=squareFilled)
xErrorLower=LCI xErrorUpper=HCI errorBarCapShape=none;
referenceLine x=1;

endLayout; /* overlay */

endLayout; /* lattice */
endgraph;
end;
run;

ods _all_ close;
ods listing image_dpi=300;
ods graphics / reset width=6in height=4.5in imagename='SAS94M2_ForestPlot_GTL';

proc sgrender data=forest2 template=forestAxisTable;
run;

ods _all_ close;``````

Accepted Solutions
Solution
‎05-05-2016 11:10 AM
SAS Super FREQ
Posts: 1,227

## Re: A problem of row space in the forest plot

The height of your plot is too tall for the number of observations yoy have.  I suggest you reduce your height o 2.6" in the BEGINGRAPH statement.  Also, remove the OFFSETMIN=0 in the YAxisOpts.  Program attached.

data forest;
input Id methods \$3-20 Countpct \$22-40 HR lci hci;
indentWt=1;
ObsId=_n_;
datalines;
1 Primary analysis 0.64 (0.43-0.95) 0.64 0.43 0.95
1 Grace period . . . .
2 60 days 0.70 (0.49-1.01) 0.7 0.49 1.01
2 90 days 1.06 (0.86-1.32) 1.06 0.86 1.32
1 Age groups . . . .
2 <=65 years 0.43 (0.19-0.93) 0.43 0.19 0.93
2 >65 years 0.69 (0.44-1.08) 0.69 0.44 1.08
1 Gender . . . .
2 Female 0.69 (0.43-1.10) 0.69 0.43 1.1
2 Male 0.57 (0.28-1.15) 0.57 0.28 1.15
1 CVD history . . . .
2 Without 0.69 (0.43-1.08) 0.69 0.43 1.08
2 With 0.50 (0.24-1.06) 0.5 0.24 1.06
;
run;

data forest2;
set forest;
/*if count ne . then CountPct=put(count, 4.0) || "(" || put(percent, 3.0) || ")";*/
if mod(obsId-1, 6) in (1, 2, 3) then ref=obsId;
/* Reduce indent for methods heading */
if id=1 then indentWt=0;
run;

/**
* Forest plot template using a one-column outermost lattice layout.
* The header uses a nested lattice layout in the top side bar.
* An overlay layout makes up the main area belci it.
* The left side table of values are axis tables placed inside
* inner margin of the overlay layout.
*/
proc template;
define statgraph forestAxisTable;
begingraph / designheight=2.6in;

value '1' / textAttrs=(size=7 weight=bold);
value '2' / textAttrs=(color=gray size=6 weight=normal);
enddiscreteattrmap;

discreteattrvar attrvar=txtDAV var=id attrmap='text';

layout lattice / columns=1;

sidebar / align=top;
layout lattice / columns=2 rowweights=uniform columnweights=(0.35 0.65)
entry textAttrs=(size=8 weight=bold) hAlign=left "Methods"
hAlign=right " HR (95% CI)";
entry textAttrs=(size=8 weight=bold) "Hazard Ratio";
endLayout;
endsidebar;

/* Single cell with inner margins for left and right tables */
layout overlay / xAxisOpts=(display=(line ticks tickvalues)
tickValueAttrs=(size=6 weight=bold)
labelAttrs=(size=6 weight=bold)
linearOpts=(tickValuePriority=true
tickValueList=(0.0 0.5 1.0 1.5 2.0))
offsetMin=0.1
)
yAxisOpts=(reverse=true display=none) wallDisplay=none;

/* Left-side table */
innerMargin / align=left gutter=0.1in;
axisTable y=obsId value=Methods / textGroup=txtDAV
indentWeight=indentwt display=(values);
axisTable y=obsId value=CountPct / display=(values);
endInnerMargin;

/* Odds Ratio plot */
referenceLine y=ref / lineAttrs=(thickness=15 color=_bandColor);
scatterPlot y=obsId x=HR / markerAttrs=(symbol=squareFilled)
xErrorLower=LCI xErrorUpper=HCI errorBarCapShape=none;
referenceLine x=1;

endLayout; /* overlay */

endLayout; /* lattice */
endgraph;
end;
run;

ods _all_ close;
ods listing image_dpi=200;
ods graphics / reset imagename='SAS94M2_ForestPlot_GTL';

proc sgrender data=forest2 template=forestAxisTable;
run;
ods _all_ close;

All Replies
Frequent Contributor
Posts: 97

## Re: A problem of row space in the forest plot

Hi JayL

Can you try adjusting the width and height in the following statement to see if it makes a difference?

ods graphics / reset width=6in height=4.5in

Norman.
SAS 9.4 (TS1M4) X64_7PRO WIN 6.1.7601 Service Pack 1 Workstation

New Contributor
Posts: 3

## Re: A problem of row space in the forest plot

Hi Norman,

Thanks so much for your help.

I've tried the method you recommend, however, it only changes the overall size of the graph proporionally, with no changes in

the space between rows.

I am trying to find an option that can change the line space under axistable, but has not figured it out yet.

Jay

Solution
‎05-05-2016 11:10 AM
SAS Super FREQ
Posts: 1,227

## Re: A problem of row space in the forest plot

The height of your plot is too tall for the number of observations yoy have.  I suggest you reduce your height o 2.6" in the BEGINGRAPH statement.  Also, remove the OFFSETMIN=0 in the YAxisOpts.  Program attached.

data forest;
input Id methods \$3-20 Countpct \$22-40 HR lci hci;
indentWt=1;
ObsId=_n_;
datalines;
1 Primary analysis 0.64 (0.43-0.95) 0.64 0.43 0.95
1 Grace period . . . .
2 60 days 0.70 (0.49-1.01) 0.7 0.49 1.01
2 90 days 1.06 (0.86-1.32) 1.06 0.86 1.32
1 Age groups . . . .
2 <=65 years 0.43 (0.19-0.93) 0.43 0.19 0.93
2 >65 years 0.69 (0.44-1.08) 0.69 0.44 1.08
1 Gender . . . .
2 Female 0.69 (0.43-1.10) 0.69 0.43 1.1
2 Male 0.57 (0.28-1.15) 0.57 0.28 1.15
1 CVD history . . . .
2 Without 0.69 (0.43-1.08) 0.69 0.43 1.08
2 With 0.50 (0.24-1.06) 0.5 0.24 1.06
;
run;

data forest2;
set forest;
/*if count ne . then CountPct=put(count, 4.0) || "(" || put(percent, 3.0) || ")";*/
if mod(obsId-1, 6) in (1, 2, 3) then ref=obsId;
/* Reduce indent for methods heading */
if id=1 then indentWt=0;
run;

/**
* Forest plot template using a one-column outermost lattice layout.
* The header uses a nested lattice layout in the top side bar.
* An overlay layout makes up the main area belci it.
* The left side table of values are axis tables placed inside
* inner margin of the overlay layout.
*/
proc template;
define statgraph forestAxisTable;
begingraph / designheight=2.6in;

value '1' / textAttrs=(size=7 weight=bold);
value '2' / textAttrs=(color=gray size=6 weight=normal);
enddiscreteattrmap;

discreteattrvar attrvar=txtDAV var=id attrmap='text';

layout lattice / columns=1;

sidebar / align=top;
layout lattice / columns=2 rowweights=uniform columnweights=(0.35 0.65)
entry textAttrs=(size=8 weight=bold) hAlign=left "Methods"
hAlign=right " HR (95% CI)";
entry textAttrs=(size=8 weight=bold) "Hazard Ratio";
endLayout;
endsidebar;

/* Single cell with inner margins for left and right tables */
layout overlay / xAxisOpts=(display=(line ticks tickvalues)
tickValueAttrs=(size=6 weight=bold)
labelAttrs=(size=6 weight=bold)
linearOpts=(tickValuePriority=true
tickValueList=(0.0 0.5 1.0 1.5 2.0))
offsetMin=0.1
)
yAxisOpts=(reverse=true display=none) wallDisplay=none;

/* Left-side table */
innerMargin / align=left gutter=0.1in;
axisTable y=obsId value=Methods / textGroup=txtDAV
indentWeight=indentwt display=(values);
axisTable y=obsId value=CountPct / display=(values);
endInnerMargin;

/* Odds Ratio plot */
referenceLine y=ref / lineAttrs=(thickness=15 color=_bandColor);
scatterPlot y=obsId x=HR / markerAttrs=(symbol=squareFilled)
xErrorLower=LCI xErrorUpper=HCI errorBarCapShape=none;
referenceLine x=1;

endLayout; /* overlay */

endLayout; /* lattice */
endgraph;
end;
run;

ods _all_ close;
ods listing image_dpi=200;
ods graphics / reset imagename='SAS94M2_ForestPlot_GTL';

proc sgrender data=forest2 template=forestAxisTable;
run;
ods _all_ close;

New Contributor
Posts: 3

## Re: A problem of row space in the forest plot

Hi Sanjay,

Thanks so much!  This is really helpful, I've learned a lot.

best regards,

Jay

🔒 This topic is solved and locked.