1

For a given x, y series, I need to fit a spline. Then at a given value of y (say 0.65), I want to draw a tangent and extract its corresponding x-value. I use the smooth.spline function to fit the curve.

spl <- smooth.spline(y ~ x)

My data is below. Any help how should I go about it.

structure(list(x = c(0.55, 0.575, 0.6, 0.625, 0.65, 0.675, 0.7, 
0.725, 0.75, 0.775, 0.8, 0.825, 0.85, 0.875, 0.9, 0.925, 0.95, 
0.975, 1, 1.025, 1.05, 1.075, 1.1, 1.125, 1.15, 1.175, 1.2, 1.225, 
1.25, 1.275, 1.3, 1.325, 1.35), y = c(0, 0.004065041, 0.02173913, 
0.067164179, 0.166666667, 0.357142857, 0.642857143, 0.907407407, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1)), .Names = c("x", "y"), class = "data.frame", row.names = c(NA, 
-33L))

There is a similar solution at here! But the new data in this example is a point on x-axis, while in my case the new data is a point on y-axis.

Ralf Stubner
  • 26,263
  • 3
  • 40
  • 75
NKaz
  • 47
  • 8

1 Answers1

4

You can use unitroot to find the point where y matches:

x <- seq(0,40)
y <- pnorm(seq(0,40), mean=25, sd=5)
spl <- smooth.spline(y ~ x)

newy <- 0.85
newx <- uniroot(function(x) predict(spl, x, deriv = 0)$y - newy,
                interval = c(0, 40))$root

plot(x, y)
lines(spl, col=2)
points(newx, newy, col=3, pch=19)

enter image description here

Concerning the algorithm, we get from ?uniroot:

uniroot() uses Fortran subroutine ‘"zeroin"’ (from Netlib) based on algorithms given in the reference below. They assume a continuous function (which then is known to have at least one root in the interval).

[...]

Based on ‘zeroin.c’ in http://www.netlib.org/c/brent.shar.

[...]

Brent, R. (1973) Algorithms for Minimization without Derivatives. Englewood Cliffs, NJ: Prentice-Hall.

See also https://en.wikipedia.org/wiki/Brent%27s_method.

Ralf Stubner
  • 26,263
  • 3
  • 40
  • 75
  • That's what I was looking for! Could you please give an insight, how it is being calculated inside the uniroot call? – NKaz Jun 21 '18 at 12:54