R ggplot - calculate intercept of multiple plotted curves and geom_hline

Viewed 162

I'm wanting to calculate interpolated x-intercepts for lines like these with geom_hline:

sample plot

library(dplyr)
library(ggplot2)

g1=data.frame(grp="1", x=seq(1,50,1), y=rnorm(50,5,1))
g2=data.frame(grp="2", x=seq(1,30,1), y=rnorm(30,8,2))
g3=data.frame(grp="3", x=seq(1,45,1), y=rnorm(45,10,1))
comb.dat=rbind(g1,g2,g3)
plot.dat=comb.dat %>% group_by(grp) %>% mutate(cum=cumsum(y)/sum(y))

p1=ggplot(plot.dat, aes(x = x, y = cum, color=grp)) +geom_line()+ geom_hline(yintercept=.5, linetype="dashed", color = "black")

print(p1)

hline=data.frame(plot.dat %>% group_by(grp) %>% mutate(test=cum>0.49 & cum<0.51))#
print(hline[hline$test==T,])# only works when an exact value in the range exists

F1=approxfun(plot.dat$cum,plot.dat$x,ties=mean)
#data.frame(plot.dat %>% group_by(grp) %>% mutate(F1(0.50)))#works only on first group

g1b=plot.dat[plot.dat$grp=="1",]
F2=approxfun(g1b$cum,g1b$x)
F2(0.5)#works but inefficient

I have a lot of these plots and I am looking for the most efficient way to find the x-intercepts with the horizontal line for each factor level so the intercept values can be compared to each other and annotated to the plot. I thought there was a logic approach but then I realized I need interpolation, probably using approxfun. I have not found a way to do this without breaking the groups out of the data frame and doing it one by one...Thanks for setting me straight.

1 Answers

Here's a dplyr approach using base::approx.

x_seq = seq(1, 50, by = 0.01)
intersections <- plot.dat %>%
  group_by(grp) %>%
  summarise(interpolated = approx(x = x, y = cum, xout = x_seq)$y) %>%
  mutate(x_seq = x_seq) %>%
  slice_min(abs(interpolated - 0.5))

ggplot(plot.dat, aes(x = x, y = cum, color=grp)) +
  geom_line() + 
  geom_hline(yintercept=.5, linetype="dashed", color = "black") +
  geom_point(data = intersections, aes(x_seq, interpolated), size = 3) +
  geom_text(data = intersections, aes(x_seq, interpolated, label = x_seq), vjust = -1)

enter image description here

Related