Search code examples
rfunctionlinear-regressionbetaderivative

Derivative of a slope in a linear function in R


When deriving the slope of a linear function (y = a + bx) it is stating the rate of change between x and y. However, if I wanted to know the speed of the rate of change (essentially the second derivative) of the function with respect to a change in x, how exactly could this be done?

x = rbind(-0.13612333, -0.02364000,  0.08234000,  0.09092667,  0.02164000,
          -0.07784667, -0.10057333, -0.11222000, -0.07394333, -0.05615667)
y = rbind(0.013591, -0.045430, -0.013332, 0.010612, -0.013214,
         -0.05521, -0.022531, -0.013262, 0.087841, -0.0201230)
beta = cov(x, y) / var(x)
beta = -0.0218445

Solution

  • Assuming that the values of y are equally spaced, a classical approximation for the second derivative is obtained with

    c(NA, y[seq_along(y) - 1]) - 2 * y + y[seq_along(y) + 1]
    #[1]  NA  0.091119 -0.008154 -0.047770 -0.018170  0.074675 -0.023410  0.091834 -0.209067   NA
    

    The result is given in arbitrary units since we don't have information about the units and the distances between subsequent values.

    The common formulas for the calculation of finite-difference approximations of the first and second derivative can be found here.

    Edit / addendum

    Here's another possibility that could be useful. One might fit the entire dataset to a quadratic function and determine the second derivative of the fit, instead of attempting to calculate the local value of the second derivative.

    As clarified by the OP in the comments, the data is sequential in time t, where each value of x and y is recorded at equidistant time steps of one month. I assume that the values of x and y refer to the same month. Based on this assumption we can first eliminate the parameter t of the time sequences x(t) and y(t) and consider the functional dependence y(x)

    y1 <- y[order(x)]  # reorder the data in ascending values of x
    x1 <- x[order(x)]  # do the same for x
    fit <- lm(y1 ~ poly(x1, 2, raw=TRUE)) # fit a second-order polynomial
    

    This yields:

    > fit$coefficients
    #         (Intercept) poly(x1, 2, raw = TRUE)1 poly(x1, 2, raw = TRUE)2 
    #         -0.01834248               0.03744701               1.76134780 
    

    The last coefficient is the second derivative of the fitted function. The result of the fit can be plotted with

    plot(y1 ~ x1)
    lines(fitted(fit) ~ x1, col=4)
    

    enter image description here