I have the following data points
example<-structure(list(y = c(1, 0.961538461538462, 0.923076923076923,
0.884615384615385, 0.846153846153846, 0.807692307692308, 0.769230769230769, 0.730769230769231, 0.730769230769231, 0.730769230769231, 0.687782805429864, 0.687782805429864, 0.641930618401207, 0.596078431372549, 0.596078431372549, 0.54640522875817, 0.496732026143791, 0.496732026143791, 0.496732026143791,
0.496732026143791, 0.496732026143791, 0.496732026143791, 0.496732026143791, 0.496732026143791, 0.496732026143791, 0.496732026143791, 0.496732026143791
), x = c(0, 59, 115, 156, 268, 329, 353, 365, 377, 421, 431,
448, 464, 475, 477, 563, 638, 744, 769, 770, 803, 855, 1040,
1106, 1129, 1206, 1227)), .Names = c("y", "x"), row.names = c(NA,
-27L), class = "data.frame")
I would like to fit a smooth line. There are several methods in R to do it, using loess
, ksmooth
, locpoly
etc.
Is there any way however to ensure or force that the resulting smoothed line will be monotonic (in the case of the present example monotonically decreasing?)
You can use the scam()
function in the scam package for uni- or multivariate smoothing with constraints. The help file, ?scam:::shape.constrained.smooth.terms
shows all of the available options. For example, the B-spline basis which is used for smoothing can be penalized to yield monotonically decreasing coefficients with scam(y~s(x,bs="mpd"))
.
require(scam)
attach(example)
yhat <- predict(scam(y~s(x,bs="mpd")),se=TRUE)
plot(x,y)
lines(x,y=yhat$fit)
lines(x,y=yhat$fit+1.96*yhat$se.fit,lty=2)
lines(x,y=yhat$fit-1.96*yhat$se.fit,lty=2)