I have fit a polynomial model to some data and I would like to extract the formula from that model in order to find its maximum. I am able to extract a formula from the lm object as a string, but I am having trouble creating a new function from that string that will work with the optimize function.
## function for generating data
f1 = function(x) 1 + x^2 - x^3
## random variable from normal distribution
yran = rnorm(500, 1, .025)
## create data by fitting function f to x points times the random variable
dt = data.frame(x = seq(.01, 1, .01) * yran,
y = f1(seq(.01, 1, .01))*yran)
## sort data frame by x
dt = dt[order(dt$x, decreasing = FALSE), ]
## plot the generated data
plot(dt, ylim = c(.9, 1.24))
## create a polynomial model
fit3 = lm(y ~ poly(x, 3), dt)
## plot the models over the data
lines(x = dt$x, predict(fit3, data.frame(x = dt$x)), col = "red", lwd = 2)
## fit the original model for comparison
lines(x = dt$x, f1(dt$x), lwd = 2, lty = 2)
The function I have created just extracts the coefficients and pastes together the formula. My challenge is being able to create a function from model string.
ext.mdl = function(lm) {
int = paste(lm$coefficients[[1]][[1]])
coef = paste(lm$coefficients[2:length(lm[[1]])])
out = as.character()
for (i in 1:length(coef)) {
out = paste(out, coef[i], "*x^", i, " + ", sep = "")
}
out = gsub('.{3}$', '', out)
out = paste(int, '+', out)
return(out)
}
> ext.mdl(fit3)
[1] "1.08475891509144 + 0.599668223720749*x^1
> + -0.822484955777266*x^2 + -0.377150292824362*x^3"
Ideally I would like to be able to assign a new function to whatever is extracted from ext.mdl() so I can use optimize() to find the maximum in the function. Ultimately I need to be able to pass "function(x) [model string]" to optimize.
> optimize(function(x) 1.08475891509144 + 0.599668223720749*x^1
+ + -0.822484955777266*x^2 + -0.377150292824362*x^3,
+ interval = c(0,1), maximum = TRUE)
$maximum
[1] 0.3018792
$objective
[1] 1.180457
Any ideas?
#parse the string and then evaluate the expression
optimize(function(x) eval(parse(text=ext.mdl(fit3))),
interval = c(0,1), maximum = TRUE)
$maximum
[1] 0.3007581
$objective
[1] 1.179404
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With