简体   繁体   中英

Plotting nonlinear regression in R

I am new to R and have been trying to fit a nonlinear model to some data, unsuccessfully though. In the end I added a polynomial trendline in Excel and tried to plot the function I got - for some reason the function doesn't fit my data in R. I tried the simple geom_smooth, but achieved a "bulky" line, I want a smooth one. I have 6 samples in one plot, here is the data for one of them, including the function obtained by Excel and my attempt to plot it. I am sure there is a better way - I also need to get the function of the fit in an output.

datax <- c(0, 21.3, 30, 46.3, 72)
datay <- c(0, 0.008723333, 0.016253333, 0.039896667, 0.079893333)
data <- data.frame(datax, datay)
x <- seq(0, 0.01, length.out = 72)
poly.fit <- function(x) 1E-5*x^2+0.0002*x
ggplot(data, aes(x=datax, y=datay)) +
  geom_point() +
  stat_function(fun=poly.fit)

Well, that function does not perfectly fit the data. After running the code and poly.fit(46.3) it returns 0.0306969 which is not .03989

The problem lies in the equation itself. If you did want to create a function in R that did match the data perfectly, there is a principle called polynomial interpolation that pretty much states that you need as many points as terms in the model if you want to fit it perfectly. So, if you would like to match the points, you can use:

 m <- lm(datay ~ poly(datax,4))   # poly() fits the polynomial with 4+1 terms
 summary(m)                       # displays coefficients

Once you get the coefficients, you can recreate the function as you did before, and that should fit the the line to match your points perfectly (as long as you fit enough polynomial terms!).

EDIT: here is an example of reproducible code that displays what you want

library(ggplot2)
datax <- c(0, 21.3, 30, 46.3, 72)
datay <- c(0, 0.008723333, 0.016253333, 0.039896667, 0.079893333)
data <- data.frame(datax, datay)

# This is another approach to the fitting using I()
m <- lm(datay ~ datax + I(datax^2) + I(datax^3) + I(datax^4))

x <- seq(0, 72, by = .1)
poly.fit = function(x){       
    as.numeric(m$coefficients[1]) +
    as.numeric(m$coefficients[2])*x +
    as.numeric(m$coefficients[3])*x^2 + 
    as.numeric(m$coefficients[4])*x^3 + 
    as.numeric(m$coefficients[5])*x^4
}  #This way you dont have to copy and paste coefficients

ggplot(data, aes(x=datax, y=datay)) +
  geom_point() +
  stat_function(fun=poly.fit)

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