1

I'm trying to fit data with nls() function where the nature of data gives me bounds for one coefficient and for sum of two coefficients. Let me introduce short example to see where is the problem. I want parameter b1 to be between 0 and 1 and I want sum of parameters b1 and b2 to be between 0 and 1 as well.

set.seed(123)

# example where everything is OK
x <- 1:200
g <- rbinom(200, 1, 0.5)
y <- 3 + (0.7 + 0.2 * g) * x 
yeps <- y + rnorm(length(y), sd = 0.1)  

# both parameter b1 and sum of parameters b1 and b2 are between 0 and 1
nls(yeps ~ a + (b1 + b2 * g) * x, start = list(a = 0.12345, b1 = 0.54321, b2 = 0.4213))

# using more extreme values
x <- 1:200
g <- rbinom(200, 1, 0.5)
y <- 3 + (0.9 - 0.99 * g) * x 
yeps <- y + rnorm(length(y), sd = 15) 

# b1 is OK, but b1 + b2 < 0
nls(yeps ~ a + (b1 + b2 * g) * x, 
    start = list(a = 0.12345, b1 = 0.54321, b2 = 0.4213))

# trying constraints, not good, sum is still out of range
nls(yeps ~ a + (b1 + b2 * g) * x, 
    start = list(a = 0.12345, b1 = 0.54321, b2 = 0.4213),
    lower = list(a = -Inf, b1 = 0, b2 = -1),
    upper = list(a = Inf, b1 = 1, b2 = 1),
    algorithm = "port")

What I'm looking for is something like that (does not work):

nls(yeps ~ a + (b1 + b2 * g) * x, 
    start = list(a = 0.12345, b1 = 0.54321, b2 = 0.4213),
    lower = list(a = -Inf, b1 = 0, b2 = -b1),
    upper = list(a = Inf, b1 = 1, b2 = 1 - b1),
    algorithm = "port")

Is it possible to set constraints with other parameters in nls() function? Thanks for any suggestions!

Adela
  • 1,757
  • 19
  • 37
  • Have a look on this [question](http://stackoverflow.com/q/11589139/707145). – MYaseen208 Feb 20 '17 at 09:07
  • Thanks for hint. However, I'm not sure if `ifelse` is good approach in `nls` function, see e.g. http://stats.stackexchange.com/questions/14561/specifying-parameter-constraints-in-nls – Adela Feb 20 '17 at 09:23
  • Anyway, how does this approach differ from fitting two models for - each `g` group? – Adela Feb 20 '17 at 09:25

1 Answers1

2

Let B2 = b1+b2 so b2 = B2-b1 and substituting B2-b1 for b2 we get a problem in terms of a, b1 and B2 of which the latter two are between 0 and 1 so:

fm <- nls(yeps ~ a + (b1 + (B2-b1) * g) * x, lower = c(-Inf, 0, 0), upper = c(Inf, 1, 1),
    start = list(a = 0.1, b1 = 0.5, B2 = 0.1), alg = "port")

giving the following (hence b2 = B2 - b1 = 0 - 0.9788 = -0.9788)

> fm
Nonlinear regression model
  model: yeps ~ a + (b1 + (B2 - b1) * g) * x
   data: parent.frame()
      a      b1      B2 
-5.3699  0.9788  0.0000 
 residual sum-of-squares: 42143

Algorithm "port", convergence message: both X-convergence and relative convergence (5)

and plotting:

plot(yeps ~ x)
points(fitted(fm) ~ x, pch = 20, col = "red")

screenshot

G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341