0

I previously asked a question about using stat_summary to add a vertical line for the median value in my density plot. I'm now trying to adapt this to also add vertical lines for the 95% confidence interval. I've been using another question as the base for my code, but it doesn't add any lines to my plot. How can I get this to work?

library(ggplot2)

set.seed(42)

dat <- data.frame(
  site = rep(LETTERS[1:4], each = 25),
  sex = rep(c("f", "m"), 50),
  mass = rnorm(100, 50, 5)
)

dat |>
  ggplot(aes(x = mass, col = sex)) +
  geom_density() +
  stat_summary(
    aes(xintercept = after_stat(x), y = 0),
    fun = mean, geom = "vline", orientation = "y"
  ) +
  stat_summary(
    aes(xintercept = after_stat(x), y = 0),
    fun.min = function(pred) { quantile(pred, probs = 0.025) }, 
    fun.max = function(pred) { quantile(pred, probs = 0.975) },
    geom = "vline", orientation = "y", linetype = "dashed"
) +
facet_wrap(~site)
5
  • 1
    Remove orientation = "y". But you'll also have to make other changes to get what you want... [It would have been helpful to report the warning you get with your current code: "Removed 8 rows containing missing values or values outside the scale range (geom_vline())" is a big clue to what's going on.] Commented Mar 22, 2024 at 18:20
  • 1
    Note the 95% quantiles are not the same thing as a 95% confidence interval (presumably for the mean). How exactly do you want to interpret these lines? Commented Mar 22, 2024 at 18:25
  • @Limey any idea what the other changes are? If I remove orientation = "y", I get a lot of vertical lines! Commented Mar 22, 2024 at 18:38
  • @MrFlick, hmmm... ok, I'm trying to show what values fall within the CIs, so if I can't use the quartiles, how should I do this? Commented Mar 22, 2024 at 18:39
  • If you look at the answer I've just posted, you'll see that I do! ;-) Commented Mar 22, 2024 at 18:41

1 Answer 1

1

This

dat |>
  ggplot(aes(x = mass, col = sex)) +
  geom_density() +
  stat_summary(
    aes(xintercept = after_stat(x), y = 0),
    fun = mean, geom = "vline", orientation = "y"
  ) +
  geom_vline(
    data = dat %>% 
      group_by(site, sex) %>% 
      reframe(
        tibble(
          value = quantile(mass, probs = c(0.025, 0.975)), 
          prob = c(0.025, 0.975)
        )
      ),
    aes(xintercept = value, col = sex),
    linetype = "dashed"
  ) +
  facet_wrap(~site)

gives

enter image description here

Personally, I find overriding the data argument of a geom_xxx call more intuitive than calling stat_summary and after_stat.

This code gives you what (I think) you expect your code to do. But I support MrFlick's warning about whether it's appropriate.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @Limey. I'm still holding out hope for an example for how to do this within stat_summary.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.