Search code examples
rggplot2plotcharts

Adding mean bars to GGPlot Line graph


I am working on putting together a graph for a manuscript for a project I'm the statistician for, and was wondering if anyone could help me recreate a graph.

I am not allowed to share the real data so I will just create a sample dataset:


set.seed(123)

record_id <- rep(1:20, each = 2)

visit <- rep(1:2, times = 20)

treatment <- rep(sample(c("AB", "BA"), 20, replace = TRUE), each = 2)

trt_seq <- ifelse(treatment == "AB" & visit == 1, "A", 
                  ifelse(treatment == "AB" & visit == 2, "B",
                         ifelse(treatment == "BA" & visit == 1, "B", "A")))

O2 <- rnorm(40, mean = 30, sd = 5)

sample_data <- data.frame(
  Record_ID = record_id,
  Visit = visit,
  Treatment = treatment,
  Trt_Seq = trt_seq,
  O2 = O2
)

This is basically what my data looks like. The actual effect doesn't matter, I just want to add something to the visualization.

library(ggplot2)
cbPalette <- c("#999999", "#E69F00", "#56B4E9", "#009E73", "#F0E442", "#0072B2", "#D55E00", "#CC79A7")
# This is colorblind friendly colors for ggplot

ggplot(sample_data, 
       aes(factor(Trt_Seq), O2, 
           group = record_id,
           color = Treatment)) +
  geom_point(size = 2) +
  geom_line() +
  scale_colour_manual(values = cbPalette) + 
  theme_bw(base_size = 16) +
  ylim(0, 45) +
  ylab("Peak O2") +
  xlab("Treatment") + 
  ggtitle("Peak O2 Treatment Effect")

example_graph_output This is what that would look like ! Sorry, I am not sure how to include the graph completely in line with the text?

I would like to know how to make it look like this: Example_graph_goal

If anyone has anything they could recommend, I would really appreciate it!! I believe the graph that I want is coming from Prism (something that doctor's tend to use), but I am using Rstudio so I would love any and all assistance.

I tried to add arguments using geom_segment or geom_hline? But they didn't really work.

mean_O2 <- aggregate(O2 ~ Treatment, data = sample_data, FUN = mean)

ggplot(sample_data, 
       aes(factor(Trt_Seq), O2, 
           group = record_id,
           color = Treatment)) +
  geom_point(size = 2) +
  geom_line() +
   geom_segment(data = mean_O2, aes(x = as.numeric(factor(Treatment)) - 0.2, 
       xend = as.numeric(factor(Treatment)) + 0.2, 
      y = O2, yend = O2), color = "black", size = 0.5) +

  scale_colour_manual(values = cbPalette) + 
  theme_bw(base_size = 16) +
  ylim(0, 45) +
  ylab("Peak O2") +
  xlab("Treatment") + 
  ggtitle("Peak O2 Treatment Effect")

Added this but it just gave me weird vertical lines.

Please help meee!!


Solution

  • Here is one possible option to achieve your desired result which uses dplyr::reframe and ggplot2::mean_se to get a data frame of means and standard errors, then uses a geom_errorbar and a geom_point to add these to your plot:

    library(ggplot2)
    library(dplyr, warn = FALSE)
    
    mean_O2 <- sample_data |>
      reframe(mean_se(O2, mult = 2), .by = Treatment) |>
      mutate(
        x = as.numeric(factor(Treatment)),
        x = x + .3 * if_else(x == 1, -1, 1)
      )
    
    ggplot(
      sample_data,
      aes(factor(Trt_Seq), O2,
        group = record_id,
        color = Treatment
      )
    ) +
      geom_point(size = 2) +
      geom_line() +
      geom_errorbar(
        data = mean_O2,
        aes(x = x, y = y, ymin = ymin, ymax = ymax, group = 1),
        width = .1
      ) +
      geom_point(
        data = mean_O2,
        aes(x = x, y = y, group = 1)
      ) +
      scale_colour_manual(values = cbPalette) +
      theme_bw(base_size = 16) +
      ylim(0, 45) +
      ylab("Peak O2") +
      xlab("Treatment") +
      ggtitle("Peak O2 Treatment Effect")