Permalink
Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
100 lines (80 sloc) 5.03 KB

Forest plots in R (ggplot) with side table

A friend asked me to help with a forest plot recently. After chatting about what she wanted the end result to look like, this is what I came up with.

library(ggplot2)
library(gridExtra)

dat <- data.frame(group = factor(c("A","B","C","D","E","F","G"), levels=c("F","E","D","C","B","A","G")),
                  cen = c(3.1,2.0,1.6,3.2,3.6,7.6,NA),
                  low = c(2,0.9,0.8,1.5,2,4.2,NA),
                  high = c(6,4,2,6,5,14.5,NA))

theme_set(theme_bw())
theme_update(
    axis.line = element_line(colour = "black"),
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    panel.border = element_blank(),
    panel.background = element_blank(),
    axis.text.y = element_blank(),
    axis.ticks.y = element_blank(),
    plot.margin = unit(c(0,0,0,0), "lines")
)

p <- ggplot(dat,aes(cen,group)) + 
    geom_point(size=5, shape=18) +
    geom_errorbarh(aes(xmax = high, xmin = low), height = 0.15) +
    geom_vline(xintercept = 1, linetype = "longdash") +
    scale_x_continuous(breaks = seq(0,14,1), labels = seq(0,14,1)) +
    labs(x="Adjusted Odds Ratio", y="")

lab <- data.frame(V0 = factor(c("A","B","C","D","E","F","G","A","B","C","D","E","F","G","A","B","C","D","E","F","G","A","B","C","D","E","F","G"),, levels=c("G","F","E","D","C","B","A")),
                  V05 = rep(c(1,2,3,4),each=7),
                  V1 = c("Occuption","Active","","Inactive","","Inactive","","Recreation","Inactive","","Active","","Inactive","","Gender","Men","Women","Men","Women","Men","Women","OR",3.1,2.0,1.6,3.2,3.6,7.6)
)

data_table <- ggplot(lab, aes(x = V05, y = V0, label = format(V1, nsmall = 1))) +
    geom_text(size = 4, hjust=0, vjust=0.5) + theme_bw() +
    geom_hline(aes(yintercept=c(6.5,7.5))) + 
    theme(panel.grid.major = element_blank(), 
          legend.position = "none",
          panel.border = element_blank(), 
          axis.text.x = element_text(colour="white"),#element_blank(),
          axis.text.y = element_blank(), 
          axis.ticks = element_line(colour="white"),#element_blank(),
          plot.margin = unit(c(0,0,0,0), "lines")) +
              labs(x="",y="") +
              coord_cartesian(xlim=c(1,4.5))
grid.arrange(data_table, p, ncol=2)

Some other options for forest plots included this:

From Abhijit blog. But I figured I'd start a fresh, and I'd already borrowed some code of Abhijits in the past for a survival curve.

The package rmeta offers two different versions. One with forestplot like so:

library(rmeta)
data(cochrane)
steroid <- meta.MH(n.trt, n.ctrl, ev.trt, ev.ctrl,
names=name, data=cochrane)
tabletext<-cbind(c("","Study",steroid$names,NA,"Summary"),
c("Deaths","(steroid)",cochrane$ev.trt,NA,NA),
c("Deaths","(placebo)", cochrane$ev.ctrl, NA,NA),
c("","OR",format(exp(steroid$logOR),digits=2),NA,format(exp(steroid$logMH),digits=2))
)
m<- c(NA,NA,steroid$logOR,NA,steroid$logMH)
l<- m-c(NA,NA,steroid$selogOR,NA,steroid$selogMH)*2
u<- m+c(NA,NA,steroid$selogOR,NA,steroid$selogMH)*2
forestplot(tabletext,m,l,u,zero=0,is.summary=c(TRUE,TRUE,rep(FALSE,8),TRUE),
clip=c(log(0.1),log(2.5)), xlog=TRUE,
col=meta.colors(box="royalblue",line="darkblue", summary="royalblue"))

And one with metaplot like so:

data(catheter)
a <- meta.MH(n.trt, n.ctrl, col.trt, col.ctrl, data=catheter,
names=Name, subset=c(13,6,5,3,7,12,4,11,1,8,10,2))
metaplot(a$logOR, a$selogOR, nn=a$selogOR^-2, a$names,
summn=a$logMH, sumse=a$selogMH, sumnn=a$selogMH^-2,
logeffect=TRUE)

Ultimately the two would be used for different purposes, and these examples shown are straight from the manual for rmeta.

It wasn't too much work to create 'another' custom option to get what my friend wanted, so thought I'd share the code for anyone else interest. There was a little bit of 'misdirection' for lack of a better term to get it across the line, and I'm sure elements of this are sloppy. You can access the code on my github.

I wrote this post in RStudio using the R Markdown language and then knitr to turn in into markdown (.md), and then pandoc to turn it into html. The original file is available here on github.

system("pandoc -s forest_plot.md -o forest_plot.html")