Clinician's corner


Back to main page

Programmer's corner

So, you use WinBUGS a lot?
Want more?

Patrick Blisle
Division of Clinical Epidemiology
McGill University Health Center
Montreal, Quebec CANADA
patrick.belisle@rimuhc.ca
Last modification: 14 jun 2017



Version 1.10 (November 2014)
forest.plot.or
[R] Drawing a forest plot
[ 
forest.plot.or is an R function developped to produce a forest plot.

] 
Menu
Top
Syntax
forest.plot.or(m0 = NULL,
n0 = NULL,
m1 = NULL,
n1 = NULL,
authors,
log.scale = standard.or.plot,
group.labels = c('Group 0', 'Group 1'),
meta.ci = rep(NA,3),
study.categories = numeric(0),
category.labels = character(0),
categories.ci = matrix(NA,length(category.labels),3),
studies.ci = matrix(NA,length(authors),3),
plot.categories.ci = rep(T,length(category.labels)),
categories.indent = T,
plot.lim = matrix(c(0,10,.2,5),ncol=2,byrow=T)[1+log.scale,],
xlim = c(0,100),
ylim = c(0,diff(xlim)*par()$fin[2]/par()$fin[1]),
authors.spaces = 20,
nN.spaces = 20,
OR.plot.spaces = 20,
OR.num.spaces = 20,
ci.spaces = c(5,5),
J = 0.5,
test = F,
na.rm = F,
na.string = "n/a",
tick.lim = T,
ref.vline.at = 1,
add.ticks.at = ref.vline.at,
tick.pch = 17,
dots.prop2n = F,
f.radius = 0.5,
cex = 10.3*length(grep("^win\\.metafile\\:", names(dev.cur()))),
circles.cex = cex,
or.side.labels = character(0),
or.side.labels.cex = cex,
blank.after.category.label = F,
blank.between.categories = T,
blank.before.category.subtotal = F,
blank.after.total = plot.xaxis,
meta.ci.pch = 15,
category.subtotal.pch = meta.ci.pch,
ci.txt = "Odds Ratio (95% CrI)",
study.txt = "Trial",
ratios.gr1.over.gr0 = T,
or.ncharacters = 4,
or.min.ndecimals = 0,
standard.or.plot = T,
show.nN.indiv = standard.or.plot,
show.nN.tot = F,
print.or.ci = T,
report.meta.ci = standard.or.plot,
sort.by.desc.samplesize = F,
placebo.index = seq(along=m1),
plot.xaxis = F,
reverse.printed.columns.order = F,
nN.txt = "n/N"
)
Top
forest.plot.or arguments
Table below presents the complete list of forest.plot.or arguments along with their signification and, for some of them,
a link to an illustrative example.
In most applications, only the arguments in the upper part of the table need be defined, while default values for the remaining will do.
m0 
Number of events in unexposed (or control, or placebo) group. 
m1 
Number of events in exposed (or treatment) group. 
n0 
Total number of subjects in unexposed (or control, or placebo) group. 
n1 
Total number of subjects in exposed (or treatment) group. 
authors 
Publications short reference label (typically, authors and year of publication).
◊ Character vector of same length as m0 and n0.

group.labels 
Group labels. 
meta.ci 
Credible interval as calculated (outside of this program) from the meta analysis of all papers included in the forest plot.
◊ Vector of length 3, where first component is the median and the next two the lower and upper credible interval limits, respectively.

In most applications, default values for each option below will do.
However, they can add considerable flexibility to the plot if necessary.

log.scale 
Whether or not forest plot should be drawn on the log scale.
◊ Logical. Default is T when standard.or.plot is T. 
study.categories 
When studies are divided into different categories, category index for each study.
◊ Numeric vector of same length as authors. 
category.labels 
When studies are divided into different categories, labels for each category presented.
Must be used along with study.categories. 
categories.ci 
When studies are divided into different categories and metaanalysis results for each category (taken separately) are to be presented
in the forest plot, enter credible intervals for each category through categories.ci.
◊ Matrix of m rows and 3 columns, where m is equal to the length of category.labels.

studies.ci 
Credible intervals for the Odds Ratio for each study.
◊ A matrix of m rows x 3 columns, where m is equal to the length of
m0, n0 or authors.
Default is empty, in which case forest.plot.or
will estimate it by a sampling method, sketched in comments (right). →

plot.categories.ci 
A vector indicating whether or not each corresponding row of categories.ci is to be plotted in the forest plot.
◊ Logical vector of same length as category.labels.

categories.indent 
Whether or not authors list should be indented, relatively to categories labels. 
plot.lim 
Lower and upper limits of the plotted area.
◊ Vector of length 2.

xlim 
Lower and upper limits of the xaxis of the produced figure (as a whole, that is, taking into account surrounding text).
◊ Vector of length 2.

ylim 
Lower and upper limits of the yaxis of the produced figure.
◊ Vector of length 2.

authors.spaces nN.spaces OR.plot.spaces OR.num.spaces ci.spaces 
Horizontal space allowed to each part of the forest plot. Each of these arguments are single numeric values, except for ci.spaces, which is a numeric vector of length 2. 
J 
Weight added to each cell count in the computation of individual studies' odds ratio median and credible interval estimates, to prevent against division by zero's.
◊ Default is 0.5.

test 
Whether function is called as a test to see what the plot would look like (it terms of spacing, character expansion, etc.),
without actually computing values for studies.ci (if it was left empty in function call), which may take some time.
◊ Logical. Default is F 
na.rm 
Whether or not studies with a missing value in any of m0, n0, m1 or n1 should be dropped from forest plot.
◊ Logical. Default is F. 
na.string 
Text to display when some of the m/n values are missing.
◊ Default is "n/a".

tick.lim 
Whether or not ticks should be plotted at the lower and upper limits of the plot region.
◊ Logical. Default is T. 
ref.vline.at 
At which xvalue to draw a reference vertical line.
◊ Numeric. Default reference vertical line location at 1. 
add.ticks.at 
Where to add ticks on the xaxis.
◊ Numeric. Default is to add a tick under the vertical line, at ref.vline.at. 
tick.pch 
Plotting character to use in xaxis ticks.
◊ Default is 17, the code for a solid triangle.

dots.prop2n 
Whether or not dots sizes (around point estimates) should be proportional to total sample size (n0+n1) of corresponding study.
◊ Logical. Default is F. 
f.radius 
Size of larger dot (around point estimates), in fraction of vertical spacing allowed to each study. 
cex 
A numerical value giving the amount by which plotting text should be magnified relative to the default.
◊ Default is 0.7 in Windows Metafiles (.wmf), 1 in other figure formats. 
circles.cex 
A numerical value giving the amount by which plotting symbols (i.e., the circles around studies OR point estimates) should be magnified relative to the default.
◊ Default is equal to cex.

or.side.labels 
Text to be displayed on each side of the plot region.
◊ Character vector of length 2.

or.side.labels.cex 
A numerical value giving the amount by which the side OR side labels (see or.side.labels above) should be magnified relative to the default. 
blank.after.category.label blank.between.categories blank.before.category.subtotal blank.after.total 
Whether or not each line/section described should be preceded or followed by a blank line.
◊ Logical. Default are F, T, F and plot.xaxis, in order. 
meta.ci.pch 
Plotting character drawn at OR's point estimate (read or obtained from meta.ci).
◊ Numeric. Default is 15, the code for a dark square. 
category.subtotal.pch 
Plotting character drawn at OR's point estimate in each category (read from categories.ci). 
ci.txt 
Text to be displayed on top of both credible interval numeric description and graphical representation.
◊ Character value. Default is Odds Ratio (95% CrI).

study.txt 
Text to be displayed on top of authors list.
◊ Default is "Trial".

ratios.gr1.over.gr0 
Whether or not ORs should be calculated in terms og group 1 vs group 0 (T), or the inverse (F).
◊ Logical. Default is T.

or.ncharacters 
Length of ORs to be displayed (in number of characters). 
or.min.ndecimals 
Minimum number of decimal places to display (even though the length of displayed number thus exceeds or.ncharacters). 
standard.or.plot 
Whether or not forest.plot.or is used to draw a forest plot for a metaanalysis on odds ratios.
◊ Logical. Default is T. 
show.nN.indiv show.nN.tot 
Whether or not you want the fractions m0/n0 and m1/n1
for individual studies and in total to be displayed or not.
◊ Logical. Default is T for show.nN.indiv if standard.or.plot is T, F for show.nN.tot.

print.or.ci 
Whether or not the numeric values for OR point estimates and credible interval endpoints should be reported.
◊ Logical. Default is T. 
report.meta.ci 
Whether or not the Total line at the bottom of the forest plot, including the total numbers n/N, the graphical representation of the posterior credible interval for OR and the OR numeric point estimate and credible interval endpoints should be reported.
◊ Logical. Default is T if standard.or.plot is T. 
sort.by.desc.samplesize 
Whether or not study entries should be listed in descending order of total sample size (n0+n1).
◊ Logical. Default is F. 
placebo.index 
A (numeric) vector of indices, of same length as m1 and n1,
indicating to which component of group 0 numbers (m0 and n0)
each component of m1 and n1 do correspond.
◊ Default is a componentwise correspondance.

plot.xaxis 
Whether or not an xaxis should be plotted at the bottom of plot region.
◊ Logical. Default is F. 
reverse.printed.columns.order 
Whether or not the order in which group results are printed should be reversed. ◊ Logical. Default is F, that is, group 0 results are printed in the left column, followed by group 1 results in the right column. 
nN.txt 
Text to be displayed below group labels.
◊ Character. Default is "n/N" 
Output example
Typically, forest plots drawn with forest.plot.or will look like the forest plot illustrated below.
A few arguments illustrated
Horizontal spacing
category.labels and study.categories
category.labels = c("Observational studies", "Randomized controlled trials"), study.categories = rep(seq(2), c(21, 3))



categories.indent
categories.indent=F



categories.indent=T



or.side.labels
or.side.labels=character(0)



or.side.labels=c('Thrombectomy better', 'Thrombectomy worse')



plot.xaxis
plot.xaxis = F



plot.xaxis = T



show.nN.tot
show.nN.tot = F



show.nN.tot = T



standard.or.plot = F
forest.plot.or(authors=c('Paper 1', 'Paper 2', 'Paper 3', 'Paper 4', 'Paper 5'), studies.ci=studies.ci, ci.txt="95% CI for mean", plot.lim=c(5, 5), ref.vline.at=0, standard.or.plot=F)



Top
Sample code
Shall you want to give a quick try to forest.plot.or, you might want to use the code below.
source('yourpath/forestplot.R')
group.labels < c('Thrombectomy', 'No Thrombectomy')
side.labels < c('Thrombectomy worse', 'Thrombectomy better')
studies.ci < c( 1.1663, 0.4136, 4.2673, 1.0398, 0.4235, 2.5669, 1.1868, 0.3871, 5.7488, 1.0496, 0.3552, 3.2706, 1.0351, 0.4493, 2.4721,
1.0252, 0.4676, 2.3361, 1.9648, 0.8545, 5.9002, 1.0448, 0.3556, 3.1771, 1.0250, 0.2536, 4.1454, 0.93792, 0.3260, 2.3974,
1.1643, 0.4098, 4.3059, 1.1414, 0.5254, 2.8010, 0.93734, 0.2671, 2.7538, 0.60781, 0.3176, 1.0824)
studies.ci < matrix(studies.ci, ncol=3, byrow=T)
authors < c("Beran G 2002", "Napodano M 2003", "Antoniucci D 2004", "Kunii H 2004", "Burzotta F 2005", "Lefèvre T 2005",
"Ali A 2006", "Kaltoft A 2006", "SilvaOrrego P 2006", "Dudek D 2007", "Sardella G 2007", "Chevalier B 2008",
"Ikari Y 2008", "Svilaas T 2008")
meta.ci < c(1.0690, 0.6298, 1.9214)
data < structure(list(N = 14,
m.placebo = c(1, 5, 0, 2, 6, 7, 4, 2,0, 1, 4, 6, 31, 2),
n.placebo = c(33, 46, 50, 129, 48, 101, 240,107, 74, 87, 94, 129, 531, 171),
m.treatment = c(2, 5, 1, 2,6, 7, 15, 2, 0, 2, 3, 7, 15, 1),
n.treatment = c(33, 46, 50,129, 48, 100, 240, 108, 74, 88, 102, 120, 529, 178)),
.Names = c("N", "m.placebo", "n.placebo", "m.treatment", "n.treatment"))
forest.plot.or(m0=data$m.treatment, n0=data$n.treatment, m1=data$m.placebo, n1=data$n.placebo, authors=authors, or.side.labels=rev(side.labels), plot.lim=c(.1, 5),
group.labels=group.labels, studies.ci=studies.ci, meta.ci=meta.ci, show.nN.tot=T)
title('Death, myocardial infarction or stroke\nAll Thrombectomy Devices')
Top
Download
forest.plot.or is a free R function. Download version 1.10 now.
