Search code examples
rgrid

Separating multiple bands in forestploter to align confidence intervals with adjacent text


Similar to this section in the forestploter tutorial, I would like to have multiple bands (3) of confidence intervals in each row in the plot.

The problem, seen in the image below, is that when I have 3 confidence intervals set to one row and reported stats in 'OR (95% CI)' format, they do not align. An example of the confidence intervals not aligning with the adjacent text

I have the below dummy data and code to reproduce a forest plot showing the problem I displayed.

library(forestploter)

dat <- data.frame(outcome=c(rep('A',3),
                            rep('B',3),
                            rep('C',3)),
                  exposure=rep(c('x','y','z'),3),
                  number=c(1,2,5,6,7,8,9,3,4),
                  o_OR=c(rnorm(9,70,10)),
                  o_lci=c(rnorm(9,30,15)),
                  o_uci=c(rnorm(9,80,10)),
                  p_OR=c(rnorm(9,70,10)),
                  p_lci=c(rnorm(9,30,15)),
                  p_uci=c(rnorm(9,80,10)),
                  q_OR=c(rnorm(9,70,10)),
                  q_lci=c(rnorm(9,30,15)),
                  q_uci=c(rnorm(9,80,10)),
                  ` `=paste(rep('                        ', 9),
                            collapse=' '),
                  `OR (95% CI)`=c('0.853 (0.000, 1.348)\n0.382 (0.129, 6.321)\n3.212 (1.129, 10.321)',
                                  '1.853 (0.287, 4.348)\n0.382 (0.129, 6.321)\n3.212 (1.129, 10.321)',
                                  '0.853 (0.000, 1.348)\n0.382 (0.129, 6.321)\n3.212 (1.129, 10.321)',
                                  '0.853 (0.000, 1.348)\n0.382 (0.129, 6.321)\n3.212 (1.129, 10.321)',
                                  '0.853 (0.000, 1.348)\n0.382 (0.129, 6.321)\n3.212 (1.129, 10.321)',
                                  '0.853 (0.000, 1.348)\n0.382 (0.129, 6.321)\n3.212 (1.129, 10.321)',
                                  '0.853 (0.000, 1.348)\n0.382 (0.129, 6.321)\n3.212 (1.129, 10.321)',
                                  '0.853 (0.000, 1.348)\n0.382 (0.129, 6.321)\n3.212 (1.129, 10.321)',
                                  '0.853 (0.000, 1.348)\n0.382 (0.129, 6.321)\n3.212 (1.129, 10.321)'),
                  `p-value`=c('0.014\n0.314\n0.614',
                              '0.014\n0.314\n0.614',
                              '0.014\n0.314\n0.614',
                              '0.014\n0.314\n0.614',
                              '0.014\n0.314\n0.614',
                              '0.014\n0.314\n0.614',
                              '0.014\n0.314\n0.614',
                              '0.014\n0.314\n0.614',
                              '0.014\n0.314\n0.614'))

# 
tm <- forest_theme(base_size = 10, # set text size
                   refline_col = "#969696", # colour of OR = 1 line
                   refline_lty = 'solid', # default is "dashed"
                   ci_lwd = 1.9, # line width of confidence intervals
                   ci_Theight = 0.3, # specifies height of T end of CIs / 'whiskers'
                   title_just = 'center', # centres the title
                   arrow_type = "closed",
                   legend_name = 'Method',
                   ci_col = c('#440154ff', '#287d8eff', '#73d055ff'),
                   # ci_pch = c(0.5,0.5,0.5),
                   legend_value = c('IVW', 'Egger', 'Weighted Median'),
                   arrow_label_just = "end",
                   core= list(padding=unit(c(4,3), 'mm')),
                   colhead=list(fg_params=list(hjust=0.5, x=0.5))) # centre align

forest(dat[,c(2,1,3, 13:15)],
       # sizes = 0.5,
       est = list(as.numeric(dat$o_OR),
                  as.numeric(dat$p_OR),
                  as.numeric(dat$q_OR)),
       lower = list(as.numeric(dat$o_lci),
                    as.numeric(dat$p_lci),
                    as.numeric(dat$q_lci)), 
       upper = list(as.numeric(dat$o_uci),
                    as.numeric(dat$p_uci),
                    as.numeric(dat$q_uci)),
       ci_column = 4, # the column where you want your forest plot
       ref_line = 1,
       title='A title',
       xlab='OR',
       theme=tm)

Any help is greatly appreciated!


Solution

  • When you have a closer look at the referenced tutorial, you will see that in the examples with multiple groups a value for nudge_y= is provided. Unfortunately, the docs are rather sparse on how to use this argument (But I only had a glimpse). In terms of ggplot2 jargon I would guess that this argument controls the dodge width.

    For the present case of three groups something around .3 seems to work to align the error bars with the labels:

    library(forestploter)
    library(grid)
    
    tm <- forest_theme(
      base_size = 10, # set text size
      refline_col = "#969696", # colour of OR = 1 line
      refline_lty = "solid", # default is "dashed"
      ci_lwd = 1.9, # line width of confidence intervals
      ci_Theight = 0.3, # specifies height of T end of CIs / 'whiskers'
      title_just = "center", # centres the title
      arrow_type = "closed",
      legend_name = "Method",
      ci_col = c("#440154ff", "#287d8eff", "#73d055ff"),
      # ci_pch = c(0.5,0.5,0.5),
      legend_value = c("IVW", "Egger", "Weighted Median"),
      arrow_label_just = "end",
      core = list(padding = unit(c(4, 3), "mm")),
      colhead = list(fg_params = list(hjust = 0.5, x = 0.5))
    )
    
    forest(dat[, c(2, 1, 3, 13:15)],
      # sizes = 0.5,
      est = list(
        as.numeric(dat$o_OR),
        as.numeric(dat$p_OR),
        as.numeric(dat$q_OR)
      ),
      lower = list(
        as.numeric(dat$o_lci),
        as.numeric(dat$p_lci),
        as.numeric(dat$q_lci)
      ),
      upper = list(
        as.numeric(dat$o_uci),
        as.numeric(dat$p_uci),
        as.numeric(dat$q_uci)
      ),
      ci_column = 4, # the column where you want your forest plot
      ref_line = 1,
      title = "A title",
      xlab = "OR",
      theme = tm,
      nudge_y = .3
    )
    

    enter image description here