Search code examples
rnonlinear-functionsbest-fit-curve

plot new values for best fit nonlinear curve


I have created the best fit for a non linear function. It seems to be working correctly:

#define a function
fncTtr <- function(n,d) (d/n)*((sqrt(1+2*(n/d))-1))

#fit
dFit <- nls(dData$ttr~fncTtr(dData$n,d),data=dData,start=list(d=25),trace=T)
summary(dFit)

plot(dData$ttr~dData$n,main="Fitted d value",pch=19,)
xl <- seq(min(dData$n),max(dData$n), (max(dData$n) - min(dData$n))/1000)

lines(xl,predict(dFit,newdata=xl,col=blue)

The plot for my observations are coming out correctly. I am having problems to display the best fit curve on my plot. I create the xl independent variable with 1000 values and I want to define the new values using the best fit. When I call the "lines" procedure, I get the error message:

Error in xy.coords(x, y) : 'x' and 'y' lengths differ If I try to execute only the predict function:

a <-predict(dFit,newdata=xl)
str(a)

I can see that xl has 1000 components but "a" has only 16 components. Shouldn't I have the same number of values in a?

data used:

  n    ttr      d
1  35 0.6951 27.739
2  36 0.6925 28.072
3  37 0.6905 28.507
4  38 0.6887 28.946
5  39 0.6790 28.003
6  40 0.6703 27.247
7  41 0.6566 25.735
8  42 0.6605 26.981
9  43 0.6567 27.016
10 44 0.6466 26.026
11 45 0.6531 27.667
12 46 0.6461 27.128
13 47 0.6336 25.751
14 48 0.6225 24.636
15 49 0.6214 24.992
16 50 0.6248 26.011

Solution

  • Ok, I think I found the solution, however I'm not sure I would be able to explain it.
    When calling predict.nls, what you're inputting to argument newdata has to be named according to the variable with which you're predicting (here n) and the name has to match that given in the original call to nls.

    #Here I replaced dData$n with n
    dFit <- nls(ttr~fncTtr(n,d),data=dData,start=list(d=25),trace=T)
    
    plot(dData$ttr~dData$n,main="Fitted d value",pch=19,)
    xl <- seq(min(dData$n),max(dData$n), (max(dData$n) - min(dData$n))/1000)
    
    a <- predict(dFit,newdata=list(n=xl))
    length(a)==length(xl)
    [1] TRUE
    
    lines(xl,a,col="blue")
    

    enter image description here