Search code examples
rggplot2modelpredictnls

R prediction of filler values (needed to generate smoothed curve from model)


I am trying to use predict() filler values (the rows contain x values and y values as NaN) to fill in the prediction curve in a plot that includes the data. The idea is to get a smoother prediction curve than just by using the data x values. However, predict() is returning funky values that do seem to not be a y calculation based on the x value. The questions are:

  • What is wrong with the prediction calculation.
  • How do I set the dataframe or change the code to get the smoothed line.

This is what the output looks like (note the dips for the erroneously predicted y values): erroneously predicted values for least squares non-linear regression

Here is the code that yields the gruesome result:

library(ggplot2)
library(nlme)

# generate test data frame
x = c(0, 5, 100, 1000, 50, 200, 300, 500)
y = c(0, 3, 5, 6, NaN, NaN, NaN, NaN)
df=data.frame(x,y)


# a log model to fit the data
lF <- formula(y ~ Ymax-(Ymax-Y0)*exp(-k*x))

# nonlinear regression
model <- nls(lF, data=df,
             start=list(Ymax=3.0, k=0.01, Y0=0.3),
             na.action = na.omit)

# print out the model resutls
summary(model)

# Derive predicted lines
df$pred <- predict(model)

# plot the data and three models
ggplot(df, aes(x=x, y=y))+
     geom_point() +
     geom_line(aes(y=pred))

Solution

  • If you specificy the argument newdata=df in the prediction command, you get:

    df$pred <- predict(model, newdata=df)
    
    ggplot(df, aes(x=x, y=y))+
         geom_point(color="red", size=3) +
         geom_line(aes(y=pred), size=1) +
         theme_bw()
    

    enter image description here

    If you want to draw a smooth line from the model, you need to define a suitable sequence of x values:

    df2 <- data.frame(x=c(seq(0,1,0.001),1:1000))
    df2$pred <- predict(model, newdata=df2)
    
    ggplot(df, aes(x=x, y=y))+
         geom_point(color="red", size=3) +
         geom_line(data=df2, aes(x=x, y=pred), color="blue", size=1) +
         theme_bw()
    

    enter image description here