Я не совсем уверен, что не так, но я могу заставить его работать, немного переставив вещи. Обратите внимание на комментарий в ?nls
о " Не используйте use nls 'для искусственных данных с нулевым остатком. "; Я добавил немного шума.
## Initialize x1, y1, x2, y2
x1 <- c(1,2)
y1 <- c(10,10)
x2 <- c(3,4,5)
y2 <- c(20,30,40)
## make single x, y vector
x <- c(x1,x2)
set.seed(1001)
## (add a bit of noise to avoid zero-residual artificiality)
y <- c(y1,y2)+rnorm(5,sd=0.01)
g <- c(TRUE,TRUE,FALSE,FALSE,FALSE) ## specify identities of points
## particular changes:
## * you have lower=upper=2 for x0. Did you want 2<x0<3?
## * specified data argument explicitly (allows use of predict() etc.)
## * changed name from 'q' to 'fit1' (avoid R built-in function)
fit1 <- nls(y ~ ifelse(g,m1,m1+delta_m)*(x - x0) + y0,
start = c(m1 = -1, delta_m = 2, y0 = 0, x0 = 2),
algorithm = "port",
lower = c(m1 = -Inf, delta_m = 0, y0 = -Inf, x0 = 2),
upper = c(m1 = Inf, delta_m = Inf, y0 = Inf, x0 = 3),
data=data.frame(x,y))
#Plot the original 'data'
plot(x,y,col=rep(c("red","blue"),c(2,3)),
xlim=c(1,5),ylim=c(0,50))
## add predicted values
xvec <- seq(1,5,length.out=101)
lines(xvec,predict(fit1,newdata=data.frame(x=xvec)))
edit : основано на ifelse
предложении на точечной идентичности, а не на позиции x
edit : изменен, чтобы требовать, чтобы второй уклон был> первым уклоном
С другой стороны, я думаю, что проблема выше - , вероятно из-за использования отдельных векторов для x1
и x2
выше, а не одного вектора x
: я подозреваю, что эти был воспроизведен R, чтобы соответствовать вектору g
, что могло бы испортить ситуацию. Например, этот урезанный пример:
g <- c(TRUE, TRUE, FALSE, FALSE, FALSE)
ifelse(g,x1,x2)
## [1] 1 2 5 3 4
показывает, что x2
расширяется до (3 4 5 3 4)
перед использованием в предложении ifelse
. Самое страшное то, что обычно выдается предупреждение, например:
> x2 + 1:5
[1] 4 6 8 7 9
Warning message:
In x2 + 1:5 :
longer object length is not a multiple of shorter object length
но в этом случае предупреждения нет ...