Skip to content

Instantly share code, notes, and snippets.

@tomhopper
Last active August 29, 2023 16:46
Show Gist options
  • Save tomhopper/12103738e03b6a256cc629477787e68d to your computer and use it in GitHub Desktop.
Save tomhopper/12103738e03b6a256cc629477787e68d to your computer and use it in GitHub Desktop.
Example of using nlsLM to fit an s-curve to data
# Based on a post at \url{http://www.walkingrandomly.com/?p=5254}
library(dplyr)
library(ggplot2)
library(minpack.lm)
# The data to fit
my_df <- data_frame(x = c(0,15,45,75,105,135,165,195,225,255,285,315),
y = c(0,0,0,4.5,19.7,39.5,59.2,77.1,93.6,98.7,100,100))
# EDA to see the trend
ggplot(my_df, aes(x = x, y = y)) + geom_point()
# Set initial values for the parameters
p1 <- 100
p2 <- 0
p3 <- 175
p4 <- .01
#my_fn <- my_df$y ~ p1 / (1 + exp(-my_df$x)) + p2
# Fit the data with a sigmoid function
fit_nls <- nlsLM(formula = y ~ p1 / (1 + exp(-x * p4 + p3)) + p2,
data = my_df,
control = nls.lm.control(ftol = 1e-10, ptol = 1e-10),
start = list(p1 = p1, p2 = p2, p3 = p3, p4 = p4),
lower = c(p1 = -Inf, p2 = 0, p3 = -Inf, p4 = -Inf),
upper = c(p1 = 100, p2 = Inf, p3 = Inf, p4 = Inf))
summary(fit_nls)
# Create a data set of fitted data
new_df <- data_frame(x = seq(min(my_df$x), max(my_df$x), length.out = 10*nrow(my_df)))
new_df$y = predict(fit_nls, new_df)
# Plot both original data and the fitted curve
ggplot() +
geom_line(data = new_df) +
geom_point(data = my_df) +
aes(x = x, y = y)
@kjfuller06
Copy link

Thanks for reporting that. I think something must have changed in minpack.lm. I'll update when I figure it out.

Any update on this? I'm running into the same error with my own data.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment