Search code examples
rgenericsparameterscurve-fittingdata-fitting

Fit model with custom function and parameters


I want to use robust non-linear regression in R to fit some data (nlrob). However, I think this question should be valid also for non-robust and/or linear methods.

I wrote a custom function that return the value of the dependent variable as a function of the independent variable plus some extra parameters. My problem is that, for each "case", I can have different number of extra parameters. How can I encode that?

Exemple:

case 1

 nlrob(y ~ f(x, p,p1),data = data1, start = c(p1 = 0 ))

case 2

nlrob(y ~ f(x,p, p1,p2,p3),data = data2, start = c(p1 = 0,p2 = 0,p3 = 0 ))

How should I write function f such that it can received and parse x, p, and a arbitrary of p*? How to write the nlrob line in order for this to work? In another words, how to write the generic lines of the calls to nlrob and function f for arbitrary number of parameters?


Solution

  • The coefficients can be a vector. For example, here the p argument of f can be of length 1 or 2:

    f <- function(x, p) if (length(p) == 1) p * x else p[1] * x + p[2]
    nlrob(demand ~ f(Time, p), BOD, start = list(p = 1))
    nlrob(demand ~ f(Time, p), BOD, start = list(p = 1:2)) 
    

    Added:

    To use with method = "tau", say, define upper and lower instead of start:

    # lower <- 0; upper <- 10
    lower <- c(0, 0); upper <- c(10, 10)
    
    nms <- paste0("p", seq_along(upper))
    names(lower) <- names(upper) <- nms
    f <- function(x, ...) {
       with(list(...), if (...length() == 1) p1 * x else p1 * x + p2)
    }   
    fo <- sprintf("demand ~ f(Time, %s)", toString(paste(nms, "=", nms)))
    nlrob(fo, data = BOD, lower = lower, upper = upper, method = "tau")