2

I have a multi-panelled density plot with two density curves/panel. I'd like to add the mean value for each density curve as a vertical line in each panel (i.e., 2 lines/panel). How do I do this with stat_summary?

set.seed(42)
data_frame(site = rep(LETTERS[1:4], each = 25),
                 sex = rep(c("f", "m"), 50),
                 mass = rnorm(100, 50, 5)) %>% 
  ggplot(aes(x = mass, col = sex)) +
  geom_density() +
  stat_summary(fun = mean, geom = "vline") +
  facet_wrap(~site)
Error in `stat_summary()`:
! Problem while computing stat.
ℹ Error occurred in the 2nd layer.
Caused by error in `compute_layer()`:
! `stat_summary()` requires the following missing aesthetics: y
Run `rlang::last_trace()` to see where the error occurred.

When I add a term for y, I get another error message:

data_frame(site = rep(LETTERS[1:4], each = 25),
                 sex = rep(c("f", "m"), 50),
                 mass = rnorm(100, 50, 5)) %>% 
  ggplot(aes(x = mass, col = sex)) +
  geom_density() +
  stat_summary(fun = mean, geom = "vline", aes(y = 0)) +
  facet_wrap(~site)
Error in `stat_summary()`:
data_frame(site = rep(LETTERS[1:4], each = 25),
                 sex = rep(c("f", "m"), 50),
                 mass = rnorm(100, 50, 5)) %>% 
  ggplot(aes(x = mass, col = sex)) +
  geom_density() +
  stat_summary(fun = mean, geom = "vline", aes(y = 0)) +
  facet_wrap(~site)
! Problem while setting up geom.
ℹ Error occurred in the 2nd layer.
Caused by error in `compute_geom_1()`:
! `geom_vline()` requires the following missing aesthetics: xintercept
Run `rlang::last_trace()` to see where the error occurred.

and when I add a term for xintercept, then I get the value for every individual instead of the mean:

data_frame(site = rep(LETTERS[1:4], each = 25),
                 sex = rep(c("f", "m"), 50),
                 mass = rnorm(100, 50, 5)) %>% 
  ggplot(aes(x = mass, col = sex)) +
  geom_density() +
  stat_summary(fun = mean, geom = "vline", aes(xintercept = mass, y = 0)) +
  facet_wrap(~site)

enter image description here

1 Answer 1

4

The issue is that by default stat_summary will compute the mean of the variable mapped on y for each value of the variable mapped on x. Instead, to achieve your desired result you have to set orientation="y" to compute the mean of x, map a constant on y e.g. y = 0 and use after_stat() to map the computed mean on xintercept:

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"
  ) +
  facet_wrap(~site)

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

Comments

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.