Question

In R I use nls to do a nonlinear least-squares fit. How then do I plot the model function using the values of the coefficients that the fit provided?

(Yes, this is a very naive question from an R relative newbie.)

Was it helpful?

Solution

Using the first example from ?nls and following the example I pointed you to line by line achieves the following:

#This is just our data frame
DNase1 <- subset(DNase, Run == 1)
DNase1$lconc <- log(DNase1$conc)
#Fit the model
fm1DNase1 <- nls(density ~ SSlogis(lconc, Asym, xmid, scal), DNase1)

#Plot the original points
# first argument is the x values, second is the y values
plot(DNase1$lconc,DNase1$density)

#This adds to the already created plot a line
# once again, first argument is x values, second is y values
lines(DNase1$lconc,predict(fm1DNase1))

The predict method for a nls argument is automatically returning the fitted y values. Alternatively, you add a step and do

yFitted <- predict(fm1DNase1)

and pass yFitted in the second argument to lines instead. The result looks like this:

enter image description here

Or if you want a "smooth" curve, what you do is to simply repeat this but evaluate the function at more points:

r <- range(DNase1$lconc)
xNew <- seq(r[1],r[2],length.out = 200)
yNew <- predict(fm1DNase1,list(lconc = xNew))

plot(DNase1$lconc,DNase1$density)
lines(xNew,yNew)

OTHER TIPS

coef(x) returns the coefficients for regression results x.

model<-nls(y~a+b*x^k,my.data,list(a=0.,b=1.,k=1))
plot(y~x,my.data)
a<-coef(model)[1]
b<-coef(model)[2]
k<-coef(model)[3]
lines(x<-c(1:10),a+b*x^k,col='red')

For example.

I know what you want (I'm a Scientist). This isn't it, but at least shows how to use 'curve' to plot your fitting function over any range, and the curve will be smooth. Using the same data set as above:

nonlinFit <- nls(density ~ a - b*exp(-c*conc), data = DNase1, start = list(a=1, b=1, c=1) )

fitFnc <- function(x) predict(nonlinFit, list(conc=x))

curve(fitFnc, from=.5, to=10)

or,

curve(fitFnc, from=8.2, to=8.4)

or,

curve(fitFnc, from=.1, to=50) # well outside the data range

or whatever (without setting up a sequence of evaluation points first).

I'm a rudimentary R programmer, so I don't know how to implement (elegantly) something like ReplaceAll ( /. ) in Mathematica that one would use to replace occurrences of the symbolic parameters in the model, with the fitted parameters. This first step works although it looks horrible:

myModel <- "a - b*exp(-c*conc)"

nonlinFit <- nls(as.formula(paste("density ~", myModel)), data = DNase1, start = list(a=1, b=1, c=1) )

It leaves you with a separate 'model' (as a character string), that you might be able to make use of with the fitted parameters ... cleanly (NOT digging out a, b, c) would simply use nonlinFit ... not sure how though.

The function "curve" will plot functions for you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top