Search code examples
rpredictloess

Predict using loess curve, an x-coordinate from a given y-coordinate


I would like to return the loess predicted x-value where y = 30 using the following data and plot. How do you get this and plot as a vertical line on the below plot?

> dput(t)
structure(list(vol = c(0L, 5L, 10L, 20L, 40L, 80L, 120L, 160L
), pc = c(0.27, 10.8, 16.4, 19.07, 53.56, 70.69, 83.85, 86.7)), class = "data.frame", row.names = c(NA, 
-8L))
library(ggplot2)
ggplot(data = t, aes(x = vol, y = pc)) +
  geom_point() +
  theme_bw() +
  geom_smooth(method = "loess", size = 1.5, span = 0.9, se = FALSE) +
  scale_x_continuous(breaks = seq(0, 160, by = 10)) +
  scale_y_continuous(breaks = seq(0, 100, by = 10)) +
  geom_hline(yintercept = 30)

Solution

  • Since there is no equation, there is no way to exactly back out the value of x that produces a prediction of 30. However, you could write a little function that would find it and then use that value in your plot. Here's an example:

      t <- structure(list(vol = c(0L, 5L, 10L, 20L, 40L, 80L, 120L, 160L
    ), pc = c(0.27, 10.8, 16.4, 19.07, 53.56, 70.69, 83.85, 86.7)), class = "data.frame", row.names = c(NA, 
                                                                                                        -8L))
    lo <- loess(pc ~ vol, data=t, span=.9)
    
    f <- function(x){
      p <- predict(lo, newdata = data.frame(vol=x))
      (p-30)^2
    }
    
    opt <- optimize(f, c(0,160))
    
    library(ggplot2)
    ggplot(data = t, aes(x = vol, y = pc)) +
      geom_point() +
      theme_bw() +
      geom_smooth(method = "loess", size = 1.5, span = 0.9, se = FALSE) +
      geom_vline(xintercept = opt$minimum) + 
      scale_x_continuous(breaks = seq(0, 160, by = 10)) +
      scale_y_continuous(breaks = seq(0, 100, by = 10)) +
      geom_hline(yintercept = 30)
    #> `geom_smooth()` using formula 'y ~ x'
    

    Created on 2022-04-15 by the reprex package (v2.0.1)