rggplot2coefplot

Create coefficient plot with 90 and 95% CIs overlayed in ggplot


I have some output from regression models where I've saved the coefficient, SE, and CI values.

I want to additionally calculate the 90% CI upper and lower values, and then basically plot that 90% CI bar above or on top of the 95% bar...so maybe the 95% bar would be faded using alpha or something of that sort, since the 95% bar will extend further than the 90% bar should. What is the most efficient way to do this?

test <- structure(list(var = c("outcome1", "outcome2", "outcome3"), coef = c(0.146788522601128, 
-0.102361679077148, -0.210611566901207), stderr = c(0.223401129245758, 
0.11381608247757, 0.21303091943264), ci_lower = c(-0.293307572603226, 
-0.32657727599144, -0.630278527736664), ci_upper = c(0.586884617805481, 
0.121853902935982, 0.209055408835411)), class = "data.frame", row.names = c(NA, 
-3L))


ggplot(test, aes(x = coef, y = var)) +
  geom_point(size = 3) + 
  geom_errorbarh(aes(xmin = ci_lower, xmax = ci_upper),
                 height = 0,
                 size = 2) +
  theme_minimal()

Solution

  • I like using different thicknesses. Here an example with your data. Modified to include a calculation of the 90% and 95% CI on 2024-11-07. Note my calculation of the 95% CI does not exactly match the values in the OP's ci_lower and ci_upper columns

    test <- structure(list(var = c("outcome1", "outcome2", "outcome3"), 
                           coef = c(0.146788522601128, -0.102361679077148, -0.210611566901207), 
                           stderr = c(0.223401129245758, 0.11381608247757, 0.21303091943264), 
                           ci_lower = c(-0.293307572603226, -0.32657727599144, -0.630278527736664), 
                           ci_upper = c(0.586884617805481, 0.121853902935982, 0.209055408835411)), 
                      class = "data.frame", row.names = c(NA, -3L))
    
    library(tidyverse)
    z90 <- qnorm(0.95) #two tails, alpha = 0.1, use qnorm(1-(alpha/2))
    z95 <- qnorm(0.975) #two tails, alpha = 0.05, use qnorm(1-(alpha/2))
    test <- test |> mutate(ci_90L = coef - stderr * z90,
                           ci_90u = coef + stderr * z90,
                           ci_95l = coef - stderr * z95, #this column should duplicate ci_lower
                           ci_95u = coef + stderr * z95) #this column should duplicate ci_upper
    
    ggplot(test, aes(x = coef, y = var)) +
      geom_point(size = 3) + 
      geom_errorbarh(aes(xmin = ci_lower, xmax = ci_upper, linewidth = "ci95"),
                     height = 0) +
      geom_errorbarh(aes(xmin = ci_90L, xmax = ci_90u, linewidth = "ci90"),
                     height = 0) +
      scale_linewidth_manual(values = c(ci95 = 1, ci90 = 2)) + labs(linewidth = "Error Bar") +
      theme_minimal()
    

    Plot with error bars

    Created on 2024-11-07 with reprex v2.1.1