Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatic curve fitting in R

Is there any package that automatically fits a curve using many simple models?
By simple models I mean:

  • ax+b
  • ax^2+bx+c
  • a*log(x) + b
  • a*x^n+b
  • ax/(1+bx)
  • ax^n/(1+bx^n)
  • ...

The best would be to have a function that takes two vector parameters X and Y and returns a list of fitted simple models with their SSE.

like image 213
Tomek Tarczynski Avatar asked Jul 05 '12 19:07

Tomek Tarczynski


3 Answers

Try this. rhs is a character vector of right sides and x and y are the data. It constructs the formula fo for each and then extracts the parameters and sets each to 1 for the starting value. Finally it runs nls and returns the SSEs sorted so that the result is a vector of SSE's named via the right hand sides. If verbose=TRUE (which it is by default) then it also displays the output from each fit.

sse <- function(rhs, x, y) sort(sapply(rhs, function(rhs, x, y, verbose = TRUE) {
    fo <- as.formula(paste("y", rhs, sep = "~"))
    nms <- setdiff(all.vars(fo), c("x", "y"))
    start <- as.list(setNames(rep(1, length(nms)), nms))
    fm <- nls(fo, data.frame(x, y), start = start)
    if (verbose) { print(fm); cat("---\n") }
    deviance(fm)
}, x = x, y = y))

## test

set.seed(123)
x <- 1:10
y <- rnorm(10, x)

# modify to suit
rhs <- c("a*x+b", "a*x*x+b*x+c")

sse(rhs, x, y)
like image 135
G. Grothendieck Avatar answered Sep 28 '22 17:09

G. Grothendieck


You could also look at packages providing functions to evaluate fractional polynomials. So far, these appear to be mboost (with the function FP) and mfp (with the function mfp). Although I haven't tried the packages, the theory behind them fits what you're after.

The mfp package was described in R-News in 2005.

Two references that might be of interest are

Royston P, Altman D (1994) Regression using fractional polynomials of continuous covariates. Appl Stat. 3: 429–467.

Sauerbrei W, Royston P (1999) Building multivariable prognostic and diagnostic models: transformation of the predictors by using fractional polynomials. Journal of the Royal Statistical Society (Series A) 162: 71–94.

like image 23
BenBarnes Avatar answered Sep 28 '22 17:09

BenBarnes


You can fit a Regression Splines and find a good fit by manually adjusting the degrees of freedom a few times. Try the following function:

spline.fit <- function(x, y, df=5) {
  ## INPUT: x, y are two vectors (predictor and response);
  ##        df is the number of spline basis.  Increase "df" to fit more adaptively to the data.
  require(splines) # available as default R Package.
  bx <- bs(x, df)  # B-spline basis matrix as New Predictors (dimension is "length(x)" by "df")
  f <- lm(y ~ bx)  # Linear Regression on Spline Basis (that is, "df" number of new predictors)
  fy <- fitted(f)  # Fitted Response
  plot(x, y); lines(x, fy, col="blue", lwd=2) # Make a plot to show the fit.
  invisible(list(x=bx, y=fy, f=f))    # Return the Basis (new predictors), Fitted Y, Regression
}

if (F) {                                # Unit Test
  spline.fit(1:100, rnorm(100))
  spline.fit(1:100, rnorm(100), df=20)
}
like image 41
Feiming Chen Avatar answered Sep 28 '22 18:09

Feiming Chen