Reputation: 78
When I fit my data using geom_smooth nls, I get a really nice fit. But if I use the stand alone nls function to fit my data using the same equation and starting values, I get a much poorer fit. I want to extract fit parameters so really need the standalone nls to generate the same fit as the geom_smooth nls.
Any suggestion/hint at what might be going on?
df <- data.frame("x" = c(4.63794469, 1.54525711, 0.51508570, 0.17169523, 0.05737664, 5.11623138, 1.70461130, 0.56820377, 0.18940126, 0.06329358, 0.02109786),
"y" = c(0.1460101, 0.7081954, 0.9619413, 1.0192286, 1.0188301, 0.3114495, 0.7602488, 0.8205661, 0.9741323, 1.0922553, 1.1130464))
fit <- nls(data = df, y ~ (1/(1 + exp(-b*x + c))), start = list(b=1, c=0))
df$stand_alone_fit <- predict(fit, df)
df %>% ggplot() +
geom_point(aes(x = x, y = y)) +
scale_x_log10() +
ylim(0,1.2) +
geom_smooth(aes(x = x, y = y), method = "nls", se = FALSE,
method.args = list(formula = y ~ (1/(1 + exp(-b*x + c))), start = list(b= 1, c=0))) +
geom_line(aes(x = x, y = stand_alone_fit), color = "red") +
labs(title = "Blue: geom_smooth nls fit\nRed: stand alone nls fit")
Upvotes: 1
Views: 423
Reputation: 24129
Two issues here, first the prediction (red line) is only performed at for the x points cause the curve to look boxy and not smooth.
Second and the reason for the question. The two fitted curves are not equal is because there is transformation on the x axis due to this line scale_x_log10()
so the nls function inside the geom_smooth is performing a different fit than the standalone fit.
See what happens when the x-axis transformation is removed. (the green line is a finer prediction from the external fit).
df <- data.frame("x" = c(4.63794469, 1.54525711, 0.51508570, 0.17169523, 0.05737664, 5.11623138, 1.70461130, 0.56820377, 0.18940126, 0.06329358, 0.02109786),
"y" = c(0.1460101, 0.7081954, 0.9619413, 1.0192286, 1.0188301, 0.3114495, 0.7602488, 0.8205661, 0.9741323, 1.0922553, 1.1130464))
fit <- nls(data = df, y ~ (1/(1 + exp(-b*x + c))), start = list(b=0, c=0))
df$stand_alone_fit <- predict(fit, df)
#finer resolution (green line)
new <- data.frame(x=seq(0.02, 5.1, 0.1))
new$y <-predict(fit, new)
df %>% ggplot() +
geom_point(aes(x = x, y = y)) +
# scale_x_log10() +
ylim(0,1.2) +
geom_smooth(aes(x = x, y = y), method = "nls", se = FALSE,
method.args = list(formula = y ~ (1/(1 + exp(-b*x + c))), start = list(b=0, c=0))) +
geom_line(aes(x = x, y = stand_alone_fit), color = "red") +
geom_line(data=new, aes(x, y), color="green") +
labs(title = "Blue: geom_smooth nls fit\nRed: stand alone nls fit")
Or use this in your original ggplot definition: method.args = list(formula = y ~ (1/(1 + exp(-b*10^(x) + 2*c))), start = list(b=-1, c=-3)))
Upvotes: 3