简体   繁体   中英

Prediction from Nonlinear Least Squares Fits in R

I'm trying to get some coeficients with nls and some basic data to be able to transform rssi in distance.

So far I've been able to get the fit from 'nls' function but I'm unable to use the 'predict' function to see if the fit is correct. Maybe I'm just misunderstanding something....

This is my code:

ydata = c(0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2)
xdata = c(-57, -57, -60, -65, -66, -68, -70, -73)
xdataratio <- sapply(xdata, function(e){return(e/-59)})

plot(ydata, xdata, pch=19)

p1 = 0.1
p2 = 1
p3 = 1

nlsFunction <- function(x, a, b, c) { a * 10^(b*x + c)}
propModel <- function(rssi, a, b, c) {(log(rssi/a) - c) / b}
powerFunction <- function(x, b0, b1, b2) {b0 + b1*(x^b2)}

fit = nls(ydata ~ powerFunction(xdataratio, p1, p2, p3), start=list(p1=p1, p2=p2, p3=p3))

summary(fit)

new = data.frame(xdata = seq(min(xdata), max(xdata), len=200))      
lines(new$xdata, predict(fit, newdata=new))

But, in the last line, I get a logic error:

Error in xy.coords(x, y, xlabel, ylabel, log) : 'x' and 'y' lengths differ

The problem is that the predict function is returning just 8 results, while the new$xdata is of length 200. Any help on using or understanding the predict function in this scenario?

Edit: I have changed the code to this as suggested (maybe I've understood it wrong..). Now the problem is that the predict is always returning NAN values.

ydata = c(0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2)
xdata = c(-57, -57, -60, -65, -66, -68, -70, -73)
xdataratio <- xdata/-59

data = data.frame(ydata=ydata, xdata=xdataratio)

plot(ydata, xdata, pch=19)

p1 = 0
p2 = 1
p3 = 2

powerFunction <- function(x, b0, b1, b2) {b0 + b1*(x^b2)}

new = data.frame(xdata = seq(min(xdata), max(xdata), len=200))
fit = nls(ydata ~ powerFunction(xdata, p1, p2, p3), start=list(p1=p1, p2=p2, p3=p3), data=data, trace=T)
lines(new$xdata, predict(fit, newdata=new))

Working

This is the final working code. The problem was with the data in new (I wasn't using same type of data)

ydata = c(0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2)
xdata = c(-57, -57, -60, -65, -66, -68, -70, -73)
xdataratio <- xdata/-59 #sapply(xdata, function(e){return(e/-59)})

data = data.frame(xdata=xdataratio)

plot(ydata, xdata, pch=19)

p1 = 0
p2 = 1
p3 = 2

powerFunction <- function(x, b0, b1, b2) {b0 + b1*(x^b2)}

new = data.frame(xdata = seq(min(xdata), max(xdata), len=200)/-59)
fit = nls(ydata ~ powerFunction(xdata, p1, p2, p3), start=list(p1=p1, p2=p2, p3=p3), data=data, trace=T)

summary(fit)

plot(type="lines",new$xdata, predict(fit, newdata=new))

This is the final working code. The problem was with the data in new (I wasn't using same type of data)

ydata = c(0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2)
xdata = c(-57, -57, -60, -65, -66, -68, -70, -73)
xdataratio <- xdata/-59 #sapply(xdata, function(e){return(e/-59)})

data = data.frame(xdata=xdataratio)

plot(ydata, xdata, pch=19)

p1 = 0
p2 = 1
p3 = 2

powerFunction <- function(x, b0, b1, b2) {b0 + b1*(x^b2)}

new = data.frame(xdata = seq(min(xdata), max(xdata), len=200)/-59)
fit = nls(ydata ~ powerFunction(xdata, p1, p2, p3), start=list(p1=p1, p2=p2, p3=p3), data=data, trace=T)

summary(fit)

plot(type="lines",new$xdata, predict(fit, newdata=new))

As pointed by @Roland, this plot seems better:

plot(distance ~ ratio, pch=19, data=data)
curve(predict(fit, newdata = data.frame(ratio = x)), add=TRUE)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM