Reputation: 13
I have a graph as shown below. How do I find the coordinates on x-axis where the horizontal grey line cuts the curve?
below is the toy dataset that I used to generate x, y values
df <- structure(list(x = c(0, -1, -2, -3, -4, -5, -6, -7, -8),
y = c(-5.22672371336103, -2.04798328990208,
-0.998312848674327, -1.13656559451279, -1.80175393429754,
-2.67597356058193, -3.62933726371666, -4.61213085819315,
-5.60579419730348)), .Names = c("x", "y"
), row.names = c(NA, -9L), class = "data.frame")
plot(df$x, df$y, asp = 1)
abline(h=-1.92, col = "gray60")
lines(df$x, df$y)
Upvotes: 1
Views: 303
Reputation: 434
Here comes another solution.
Let me define the x and y vectors separately first.
x= c(0, -1, -2, -3, -4, -5, -6, -7, -8)
y= c(-5.22672371336103, -2.04798328990208,
-0.998312848674327, -1.13656559451279, -1.80175393429754,
-2.67597356058193, -3.62933726371666, -4.61213085819315,
-5.60579419730348)
Instead of focusing on the intersection between the two curves, to simplify, what I´m going to do is to displace/move your curve h
units up.
y<-y+1.92
Now my problem is much simpler: Calculating the roots of the curve.
I´ll fit a 4th degree polynomial (this was a bit random, I have to admit).
fit4 <- lm(y~poly(x,4,raw=TRUE))
summary(fit4)
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -3.2879360 0.0525516 -62.57 3.91e-07 ***
poly(x, 4, raw = TRUE)1 -4.4218115 0.1044875 -42.32 1.86e-06 ***
poly(x, 4, raw = TRUE)2 -1.4833140 0.0583804 -25.41 1.42e-05 ***
poly(x, 4, raw = TRUE)3 -0.1799201 0.0112986 -15.92 9.09e-05 ***
poly(x, 4, raw = TRUE)4 -0.0080516 0.0007005 -11.49 0.000327 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.05373 on 4 degrees of freedom
Multiple R-squared: 0.9995, Adjusted R-squared: 0.9991
F-statistic: 2130 on 4 and 4 DF, p-value: 6.605e-07
As you can see, my R-squared is quite good... so enough.
Now, I get the coefficients and get the roots of my polynomial.
coef<-fit4$coefficients
polyroot(coef)
Which are -1.094 and -4.136.
Upvotes: 2
Reputation: 8846
I'm sure there are more clever ways of doing this, but here's a method using splines and brute force.
spl <- splinefun(df)
s <- seq(min(df$x), max(df$x), by=5e-3)
est <- spl(s)
xs <- s[diff(sign(diff(c(0, abs(-1.92 - est))))) > 0]
plot(df$x, df$y, asp=1)
abline(h=-1.92, col = "gray60")
lines(s, est)
abline(v=xs, col="blue")
Upvotes: 2