thomasrive
thomasrive

Reputation: 141

How to find min max from lm

I'm trying to figure out a way to find the minimum/maximum from a fitted quadratic model. In this case the minimum.

x.lm <- lm(Y ~ X + I(X^2))

Edit: To clarify, I can already find the minimum y through min(predict(x.lm)). How can I translate this to it's corresponding x value.

Upvotes: 2

Views: 5070

Answers (2)

cdalitz
cdalitz

Reputation: 1277

Although there is already an accepted answer, it has the drawback that it does not yield the minimum or maximum of the fitted curve, but only a random point on the curve that happens to be the minimum among the random sample of predictor values.

As @Roland pointed out, it is easy to compute the actual extremum from the fitted coefficients. Remember that a necessary condition for an extremum is a vanishing derivative, which yields for $y = ax^2 + bx + c$ the point $x = -b/2a$. You can thus find the extremum as follows:

fit <- lm(mpg ~ disp + I(disp^2), data=mtcars) # or: lm(mpg ~ poly(disp,2,raw=T), data=mtcars)
a <- coef(fit)[3]
b <- coef(fit)[2]
-b/(2*a)
# 419.2907

plot(mpg ~ disp, data=mtcars)
mtcars.sorted <- mtcars[order(mtcars$disp),]
lines(mtcars.sorted$disp, predict(fit, newdata=mtcars.sorted), col="red")
abline(v=-b/(2*a), col="blue")

location of minimum of fitted curve

Note that it is important to fit a "raw" polynomial, either with I(...) or with poly(..., raw=TRUE), because otherwise the coefficients would not correspond to the numbers a, b and c of the parabola.

Upvotes: 0

M. Siwik
M. Siwik

Reputation: 497

Check this out. Idea is that you have to take fitted values form x.lm fit

#example data

X <- 1:100 
Y <- 1:100 + rnorm(n = 100, mean = 0, sd = 4)

x.lm <- lm(Y ~ X + I(X^2))

fits <- x.lm$fitted.values #getting fits, you can take residuals,
# and other parameters too

# I guess you are looking for this.
min.fit = min(fits)
max.fit = max(fits)

After another question

df <- cbind(X, Y, fits)
df <- as.data.frame(df)
index <- which.min(df$fits) #very usefull command
row.in.df <- df[index,]

Upvotes: 3

Related Questions