I'm trying to fit a known function to data points, finding the best parameters settings. For that purpose I'm using the optimr
package.
Here's a reproducible example:
packages = c("optimr", "ggplot2", "tidyverse")
lapply(packages, library, character.only=T)
testfun <- function(par, x){
case_when(
x < par[1] ~ par[2]*x,
x >= par[1] ~ par[3] + par[4]*x^2)
}
optfun <- function(par, x, y){
sum((testfun(par, x) - y)^2)
}
optout <- optimr(par = c(20000,0,0,0), optfun, x = ggplot2::midwest$popdensity, y = ggplot2::midwest$poptotal, method = "L-BFGS-B")
ggplot(ggplot2::midwest, aes(x = popdensity, y = poptotal)) +
geom_point() +
stat_function(fun = testfun, args = list(par = optout$par))
I can fit a simple function and the setup will find the best fitting parameters. But par[1]
does not change and simply stays on the initial value when i introduce a piecewise function.
Any help is much appreciated!
Piecewise functions, especially piecewise functions with flat parts, will give optimisers trouble. Optimisers will generally give up on a parameter if the function value doesnt' change for some step size, and might not search far enough to hit the step.
Look for other parameters to optimr
that might widen the search space.