1

I have a density plot that look like this: plot

I want to add vertical lines that correspond to 25%, 50%, and 75% of the distribution for each facet.

I guess that I could do it "manually" by using the summary statistic of each years, but I'm supposing that there is a more efficient way?

Here is my code:

merge(usa_census_sub, CPI, by.x = "YEAR", by.y = "year")%>%
  select(YEAR, INCWAGE, rate)%>%
  filter(YEAR >= 1960 & INCWAGE !=999999 & INCWAGE !=0)%>%
  mutate(log_INCWAGE <- (log10(INCWAGE)),
         RWAGE = (log_INCWAGE/rate)*158)%>%
  ggplot(usa_census_sub, mapping = aes(x= RWAGE))+
  geom_density()+
  facet_wrap(~YEAR)
Quinten
  • 35,235
  • 5
  • 20
  • 53
Nea
  • 11
  • 3
  • [How to make a great R reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example). Without data and code it's not easy to answer the question. Can [this](https://ggplot2.tidyverse.org/reference/geom_quantile.html) help? – Rui Barradas Mar 26 '23 at 08:16

2 Answers2

2

We could do something like this:

data:

set.seed(123)
df <- data.frame(
  year = rep(c(1960, 1970, 1980, 1990, 2000, 2010), each = 100),
  value = c(rnorm(100, mean = 10, sd = 3),
            rnorm(100, mean = 12, sd = 2))
)
library(dplyr)
library(ggplot2)

# define quantiles
quantiles <- df %>% 
  group_by(year) %>% 
  summarize(q25 = quantile(value, 0.25), 
            q50 = quantile(value, 0.5), 
            q75 = quantile(value, 0.75))

# plot
ggplot(df, aes(x = value, fill = factor(year))) +
  geom_density(alpha = 0.5) +
  facet_wrap(~ year, ncol = 3)+
  geom_vline(data = quantiles, aes(xintercept = q25),
             linetype = "dashed", size = 1) +
  geom_vline(data = quantiles, aes(xintercept = q50),
             linetype = "dashed", size = 1) +
  geom_vline(data = quantiles, aes(xintercept = q75),
             linetype = "dashed", size = 1) 

enter image description here

TarJae
  • 72,363
  • 6
  • 19
  • 66
  • 1
    I tried this but I receive this error: 1: Removed 6 rows containing missing values (`geom_vline()`). 2: Removed 6 rows containing missing values (`geom_vline()`). 3: Removed 6 rows containing missing values (`geom_vline()`). I'm gonna post my code in the question – Nea Mar 26 '23 at 08:46
  • sorry I forgot the example dataset. I now added it. You then have to adapt to our dataframe. – TarJae Mar 26 '23 at 08:50
2

You could use stat_summary to add vline's by calculating the quantile on each. stat_summary calculates the y value according to the x, so that's why x=0. With fun.data you calculate the coordinates for the quantiles for the aesthetics of each facet like this:

library(ggplot2)
df |>
  ggplot(aes(x = RWAGE)) +
  geom_density() +
  stat_summary(aes(x = 0, y = RWAGE),
               geom = "vline",
               fun.data = function(x) data.frame(xintercept = quantile(x, c(0.25, 0.5, 0.75)))) +
  facet_wrap(~year)

Created on 2023-03-26 with reprex v2.0.2


Fake data:

set.seed(7)
df = data.frame(year = rep(c(1960, 1970, 1980, 1990, 2010), each = 100),
                RWAGE = rep(runif(100, 0, 15), each = 5))
Quinten
  • 35,235
  • 5
  • 20
  • 53