1

I want to add error bars to my geom_col ggplot. The error bar is indeed added to my plot, but the error bars are not correct. Can someone please help me figure out how to adapt my code? I think that the y-values is wrong. It should probably not be the length, but the actual values of the "Number"'s from my data frame. I apologize if this is a really simple question, i am quite new in R. Thank you in advance.

enter image description here

number_of_sprout <- data.frame(
  Condition = c("RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl"), 
  Number = c(8, 11, 11, 17, 18, 13, 16, 4, 11, 9, 12, 11, 15, 11, 17, 8, 18, 9, 7, 11, 11, 12, 8, 12, 6, 8, 10, 19, 9, 14, 7, 9, 12, 11, 8, 12, 6, 8, 10, 8, 11, 11, 10, 7, 6, 6, 6, 9, 11, 10, 11, 12, 8, 14, 7, 8, 11, 9, 9, 12, 10, 7, 13, 17, 15, 9, 14, 11, 11, 8, 14, 13, 7, 8, 6, 7, 9, 7, 10, 7), 
  timepoint = c(24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48)
)


sph1 <- ggplot(data = number_of_sprout, aes(x = factor(timepoint, ordered = TRUE), y=Number, fill = Condition)) +
  stat_summary(fun = mean, geom = "col", position = position_dodge()) +
  scale_fill_manual(values = c("slategray4", "thistle3")) +
  geom_point(position = position_dodge(width = 0.9)) +
    labs(x = "Hours", y = "Number of sprouts") +
    theme_classic() +
    ggtitle("Spheroids - Donor 37") +
    theme_bw() +
    theme(text=element_text(family="Times New Roman", face="bold")) +
    theme(aspect.ratio = 1.5/1)

se5 <- function(y) sd(y)/length(y)   # to calculate standard error in the mean
sph1+stat_summary(geom="errorbar",position=position_dodge(width=0.9),
                 fun.data=function(y)c(ymin=mean(y)-se5(y),ymax=mean(y)+se5(y)), width=0.2)
tjebo
  • 21,977
  • 7
  • 58
  • 94

2 Answers2

1

I assume you just have the wrong formula for the standard error of the mean. I have this saved in my personal utility package, so I don't need to look that up - cheekily stolen from this thread at some point.

Of another note, perhaps check http://data-to-viz.com/caveat/error_bar.html for a more general caveat why error bars might be not ideal (and not very necessary if you plot the entire data, in general)

# replace your function
se5 <- function(x, na.rm=FALSE) {
  if (na.rm) x <- na.omit(x)
  sqrt(var(x)/length(x))
}  # to calculate standard error in the mean
sph1+stat_summary(geom="errorbar",position=position_dodge(width=0.9),
                  fun.data=function(y)c(ymin=mean(y)-se5(y),ymax=mean(y)+se5(y)), width=0.2)

tjebo
  • 21,977
  • 7
  • 58
  • 94
0

As a different answer - different topic. Have you considered a different form of visualisation of your paired data? I'd show this as a relational scatter plot instead, with first measure on the x and second on the y axis.

As you can see, this way the relation between both measurements is much better visible and you can also see the difference (or similarity as in this case) better than with bar graphs.

library(tidyverse)
number_of_sprout <- data.frame(
 Condition = c("RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "RBP7 KO", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl", "Ctrl"), 
 Number = c(8, 11, 11, 17, 18, 13, 16, 4, 11, 9, 12, 11, 15, 11, 17, 8, 18, 9, 7, 11, 11, 12, 8, 12, 6, 8, 10, 19, 9, 14, 7, 9, 12, 11, 8, 12, 6, 8, 10, 8, 11, 11, 10, 7, 6, 6, 6, 9, 11, 10, 11, 12, 8, 14, 7, 8, 11, 9, 9, 12, 10, 7, 13, 17, 15, 9, 14, 11, 11, 8, 14, 13, 7, 8, 6, 7, 9, 7, 10, 7), 
 timepoint = c(24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48)
)
number_of_sprout %>%
 pivot_wider(names_from = timepoint, values_from = Number, 
             names_prefix = "t", values_fn = list) %>%
 unnest(c(t24, t48)) %>%
ggplot(aes(t24, t48)) +
 geom_abline(intercept = 0, slope = 1, color = "grey") +
 geom_point(aes(color = Condition)) +
 scale_color_brewer(palette = "Set1", direction = -1) +
 coord_equal(xlim = c(0,NA), ylim = c(0, NA)) +
 cowplot::theme_cowplot()

Created on 2021-04-29 by the reprex package (v2.0.0)

tjebo
  • 21,977
  • 7
  • 58
  • 94