# [R] Fast way to draw mean values and 95% confidence intervals of groups with ggplot2

Rui Barradas ru|pb@rr@d@@ @end|ng |rom @@po@pt
Thu Nov 16 13:39:20 CET 2023

```Às 11:59 de 16/11/2023, Luigi Marongiu escreveu:
> Hello,
> I have triplicate (column A) readings (column D) of samples exposed to
> different concentrations (column C) over time (column B).
> Is it possible to draw a line plot of the mean values for each
> concentration (C)? At the moment, I get a single line.
> Also, is there a simple way to draw the 95% CI around these data? I
> know I need to use ribbon with the lower and upper limit, but is there
> a simple way for ggplot2 to calculate directly these values?
> Here is a working example:
>
> ```
> A = c(rep(1, 28), rep(2, 28), rep(3, 28))
> B = rep(c(0, 15, 30, 45, 60, 75, 90), 12)
> C = rep(c(rep(0, 7), rep(0.6, 7), rep(1.2, 7),
>            rep(2.5,7)),3)
> D = c(731.33,    761.67,    730,    761.67,    741.67,    788.67,    784.33,
>        686.67,    685.33,    680,    693.67,    684,    704,    709.67,    739,
>        731,    719,    767,    760.67,    776.67,    768.67,    675,    671.67,
>        668.67,    677.33,    673.67,    687,    696.67,    727,    750.67,
>        752.67,    786.67,    794.67,    843.33,    946,    732.67,    737.33,
>        775.33,    828,    918,    1063,    1270,    752.67,    742.33,
>    735.67,
>        747.67,    777.33,    803.67,    865.67,    700,    700.67,    705.67,
>        722.67,    744,    779,    837,    748,    742,    754,    747.67,
>        775.67,    808.67,    869,    705.67,    714.33,    702.33,    730,
>        710.67,    731,    744,    686.33,    687.33,    670,    702.33,
>        669.33,    707.33,    708.33,    724,    747,    761.33,    715,
>        697.67,    728,    728)
>
> df = data.frame(A, B, C, D)
> library(ggplot2)
> ggplot(data=df, aes(x=B, y=D, z=C, color =C)) +
>    geom_line(stat = "summary", fun = "mean") +
>    geom_ribbon()
> ```
>
> Thank you
>
> ______________________________________________
> R-help using r-project.org mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> and provide commented, minimal, self-contained, reproducible code.
Hello,

I am not sure that the code below is what you want.
The first 3 instructions are to create a named vector of colors.
The pipe is what tries to solve the problem. It computes means and se's
by groups of time and concentration, then plots the ribbon below the lines.

It is important to not set color = C in the initial call to ggplot,
since it would be effective in all the subsequent layers (try it).
To have one line per concentration I use group = C instead.

suppressPackageStartupMessages({
library(ggplot2)
library(dplyr)
})

n_colors <- df\$C |> unique() |> length()
names_colors <- df\$C |> unique() |> as.character()
clrs <- setNames(palette.colors(n_colors), names_colors)

df %>%
mutate(C = factor(C)) %>%
group_by(B, C) %>%
mutate(mean_D = mean(D), se_D = sd(D)) %>%
ungroup() %>%
ggplot(aes(x = B, group = C)) +
geom_ribbon(aes(ymin = mean_D - se_D, ymax = mean_D + se_D), fill =
"grey", alpha = 0.5) +
geom_line(aes(y = mean_D, color = C)) +
geom_point(aes(y = D, color = C)) +
scale_color_manual(name = "Concentration", values = clrs)

Hope this helps,