Adding a line with the mean value of plotted points in ggplot with facet wrap

I am working with a dataframe that has centre wise sales made by each person on different dates. Sample data can be generated as follows

library(tidyverse)

tibble(
  centre = rep(c('A', 'B'), 4),
  person = c('p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8')
) %>%
  full_join(
    tibble(date = seq(as.Date('2022-01-01'), as.Date('2022-01-5'), 1)),
    by = character()
  ) %>%
  mutate(
    num = round(runif(nrow(.), min = 50, max = 100),0)
  ) ->
  df

I am trying to plot the sales vs date trend for different people as follows

library(ggplot2)

df %>%
  group_by(centre, person) %>%
  mutate(mean_num = mean(num, na.rm = TRUE)) %>%
  ungroup() %>%
  ggplot(aes(x = date, y = num)) +
  geom_point() +
  geom_line() +
  facet_wrap(~person, scales = 'free') +
  xlab('Date') +
  ylab('Sales') +
  ggtitle('Sales vs Date') ->
  plt

I want to add to each facet the mean of values in that facet (that is the mean of sales made by each person). I have tried three methods, but none of them seem to work. Method 3 from the following link Add mean line to ggplot?

# Method 1
plt +
geom_hline(yintercept = mean(num), linetype = 'dotted', colour = 'red')

# Method 2
plt +
geom_hline(yintercept = mean_num, linetype = 'dotted', colour = 'red')

# Method 3
plt +
stat_summary(fun = mean, geom = 'line', colour = 'red')

I can make a separate dataframe for means and then use that to plot, but wanted to do it in one pipeline. Am I doing something wrong?

>Solution :

You need to pass yintercept as an aesthetic mapping:

plt +
geom_hline(aes(yintercept = mean_num), linetype = 'dotted', colour = 'red')

The code you currently have is looking for a single value for mean_num in the global environment. By passing aes(yintercept = mean_num) to the mapping argument of geom_hline, you make it clear to ggplot that you want to use the variable from df and map it to each facet separately.

Leave a Reply