forestploter icon indicating copy to clipboard operation
forestploter copied to clipboard

specify rows for vert_line argument

Open tsl1999 opened this issue 2 years ago • 2 comments
trafficstars

Hi, I am trying to plot a forest plot for different subgroups therefore want to show different vertical lines for different subgroup rows. Is there a way that I could specify rows for a particular vertical line to appear. e.g. vert_line[1] to appear on row 3 to row 5?

tsl1999 avatar Nov 15 '23 14:11 tsl1999

No, you can't specify rows for vertical line. But there are two options. First, assume the below is your data

dt <- read.csv(system.file("extdata", "example_data.csv", package = "forestploter"))

# indent the subgroup if there is a number in the placebo column
dt$Subgroup <- ifelse(is.na(dt$Placebo), 
                      dt$Subgroup,
                      paste0("   ", dt$Subgroup))

# NA to blank
dt$Treatment <- ifelse(is.na(dt$Treatment), "", dt$Treatment)
dt$Placebo <- ifelse(is.na(dt$Placebo), "", dt$Placebo)
dt$se <- (log(dt$hi) - log(dt$est))/1.96

# Add blank column for the forest plot to display CI.
# Adjust the column width with space. 
dt$` ` <- paste(rep(" ", 20), collapse = " ")

# Create confidence interval column to display
dt$`HR (95% CI)` <- ifelse(is.na(dt$se), "",
                           sprintf("%.2f (%.2f to %.2f)",
                                   dt$est, dt$low, dt$hi))
dt <- dt[1:7, ]

Here are how you can do that, choose whichever suits you.

  1. Use add_grob
g <- forest(dt[,c(1:3, 20:21)],
            est = dt$est,
            lower = dt$low, 
            upper = dt$hi,
            ci_column = 4,
            ref_line = 1,
            xlim = c(0, 4),
            ticks_at = c(0.5, 1, 2, 3))

g <- add_grob(g, 
         row = 1:3, 
         col = 4,
         order = "background",
         gb_fn = segmentsGrob,
         gp = gpar(col = "red", lty = "dotted"),
         x0 = unit(c(0.3, 0.5, 1.5),"native"), # This is the lines you want to put
         x1 = unit(c(0.3, 0.5, 1.5),"native"), # Repeat it here to get a vertical line
         y0 = unit(0,"npc"),
         y1 = unit(1,"npc"),
         vp = viewport(xscale = c(0, 4))) # This is the xlim you used.

g <- add_grob(g, 
              row = 6:7, 
              col = 4,
              order = "background",
              gb_fn = segmentsGrob,
              gp = gpar(col = "blue", lty = "dotted"),
              x0 = unit(c(0.6, 1.7),"native"),
              x1 = unit(c(0.6, 1.7),"native"),
              y0 = unit(0,"npc"),
              y1 = unit(1,"npc"),
              vp = viewport(xscale = c(0, 4)))
plot(g)

method1

  1. Draw two plots and combine them together.

fig_dat1 <- dt[1:4,]
fig_dat2 <- dt[5:7,]

p1 <- forest(fig_dat1[,c(1:3, 20:21)],
             est = fig_dat1$est,
             lower = fig_dat1$low, 
             upper = fig_dat1$hi,
             vert_line = c(0.5, 1.4),
             ci_column = 4,
             ref_line = 1,
             xlim = c(0, 4),
             ticks_at = c(0.5, 1, 2, 3))

p2 <- forest(fig_dat2[,c(1:3, 20:21)],
             est = fig_dat2$est,
             lower = fig_dat2$low, 
             upper = fig_dat2$hi,
             ci_column = 4,
             ref_line = 0,
             xlim = c(0, 4),
             vert_line = c(1.4),
             ticks_at = c(0.5, 1, 2, 3))
# You can change the theme for each plot of course.
# Combine plots, you can also use other methods to combine two plots.
p <- rbind(p1, p2)

plot(p)

method2

adayim avatar Nov 15 '23 21:11 adayim

Brilliant, thanks so much! That solved my problem! I adopted the first solution and that worked out nicely!

tsl1999 avatar Nov 16 '23 10:11 tsl1999