Adding arrows to confidence intervals when using shape_plot()

ckbplotr

5 Nov 2022

Modified:

20 Jul 2023

Using ckbplotr::shape_plot() you may have confidence interval limits outside your chosen limits for the y axis. The confidence interval lines (and text labels) will extend outside the plotting area and maybe outside the plot entirely:

my_results <- data.frame(
  risk_factor = c(  17,    20,  23.5,    25,    29),
  est         = c(   0, 0.069, 0.095, 0.182, 0.214),
  se          = c(0.05, 0.048, 0.045, 0.045, 0.081)
)

shape_plot(my_results,
           col.x        = "risk_factor",
           xlims        = c(15, 30),
           ylims        = c(0.95, 1.35),
           exponentiate = TRUE)

If you definitely want to keep those axis limits, you may want to add arrows to the confidence interval lines. First use addaes in ckbplotr::shape_plot() to truncate the confidence interval lines (and change the position of the text):

p <- shape_plot(my_results,
                col.x        = "risk_factor",
                xlims        = c(15, 30),
                ylims        = c(0.95, 1.35),
                exponentiate = TRUE,
                quiet        = TRUE,
                addaes       = list(ci = c("ymin = pmax(0.95, exp(est-1.96*se))",
                                           "ymax = pmin(1.35, exp(est+1.96*se))"),
                                    estimates = "y = pmin(1.35, exp(est+1.96*se))"))

Then add geom_segment() layers to the plot to add small segments with arrows. Use the data argument to filter the data to only include the rows where the confidence limit is outside the axis limit.

p$plot +
  geom_segment(aes(x    = risk_factor,
                   xend = risk_factor,
                   y    = 1.35 - 1e-6,
                   yend = 1.35),
               arrow = arrow(length = unit(2, "mm"),
                             type = "closed"),
               data = ~ dplyr::filter(., exp(est + 1.96 * se) > 1.35)) +
  geom_segment(aes(x = risk_factor,
                   xend = risk_factor,
                   y = 0.95 + 1e-6,
                   yend = 0.95),
               arrow = arrow(length = unit(2, "mm"),
                             type = "closed"),
               data = ~ dplyr::filter(., exp(est - 1.96 * se) < 0.95))