library(Stat2Data)
library(dplyr)
library(ggplot2)
data("AccordPrice")
my_data <- AccordPrice
We examine the relationship between a used Honda Accord’s mileage (in thousands of miles) and its price (in thousands of dollars).
# Scatterplot
ggplot(my_data, aes(x = Mileage, y = Price)) +
geom_point() +
labs(
title = "Used Honda Accord Price vs. Mileage",
x = "Mileage (thousands of miles)",
y = "Price (thousands of dollars)"
)
# Correlation
cor(my_data$Mileage, my_data$Price)
## [1] -0.8489441
The correlation coefficient is \(r = -0.8489441\), indicating a strong negative linear relationship between mileage and price.
Next, we fit a linear regression model with Price as the
response variable (\(y\)) and
Mileage as the explanatory variable (\(x\)).
model <- lm(Price ~ Mileage, data = my_data)
coef(model)
## (Intercept) Mileage
## 20.8096129 -0.1198119
Our regression line equation is: \[\widehat{\text{Price}} = 20.8096129 - 0.1198119 \cdot \text{Mileage}\]
ggplot(my_data, aes(x = Mileage, y = Price)) +
geom_point() +
geom_abline(intercept = 20.8096129, slope = -0.1198119, color = "steelblue") +
labs(
title = "Used Honda Accord Price vs. Mileage with Fitted Line",
x = "Mileage (thousands of miles)",
y = "Price (thousands of dollars)"
)
We inspect the first observation in the dataset:
my_data %>%
select(Mileage, Price) %>%
head(1)
## Mileage Price
## 1 74.9 12
Using the actual values (\(x = 74.9\), \(y = 12\)), we compute the residual by hand:
12 - (-0.1198119 * 74.9 + 20.8096129)
## [1] 0.1642984
Interpretation: This Honda Accord is priced about 0.1643 thousand dollars (or $164.30) above what the regression line predicts for a car with 74.9 thousand miles. The point sits slightly above the regression line.
We add the predicted values and residuals to our dataset and create a residual plot.
my_data <- my_data %>%
mutate(
predicted = fitted(model),
residual = residuals(model)
)
my_data %>%
select(Mileage, Price, predicted, residual) %>%
head()
## Mileage Price predicted residual
## 1 74.9 12.0 11.83570 0.1643021
## 2 53.0 17.9 14.45958 3.4404204
## 3 79.1 15.7 11.33249 4.3675123
## 4 50.1 12.5 14.80703 -2.3070342
## 5 62.0 9.5 13.38127 -3.8812720
## 6 4.8 21.5 20.23452 1.2654845
ggplot(my_data, aes(x = Mileage, y = residual)) +
geom_point(alpha = 0.6) +
geom_hline(yintercept = 0, color = "steelblue") +
labs(
title = "Residual Plot: Honda Accord Price Model",
x = "Mileage (thousands of miles)",
y = "Residual (thousands of dollars)"
)
Interpretation: The residual plot displays a “boring cloud” of points with no clear curved pattern or fanning spread. This tells us that the spread of residuals remains fairly constant across all mileages, confirming that a linear model is a reasonable choice for these data.
summary(model)
##
## Call:
## lm(formula = Price ~ Mileage, data = my_data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -6.5984 -1.8169 -0.4148 1.4502 6.5655
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 20.8096 0.9529 21.84 < 2e-16 ***
## Mileage -0.1198 0.0141 -8.50 3.06e-09 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 3.085 on 28 degrees of freedom
## Multiple R-squared: 0.7207, Adjusted R-squared: 0.7107
## F-statistic: 72.25 on 1 and 28 DF, p-value: 3.055e-09
Interpretations: * \(R^2\): About 72.07% of the variation in Honda Accord prices (in thousands of dollars) is explained by the linear relationship with mileage (in thousands of miles). * Residual Standard Error: When we use mileage (in thousands of miles) to predict a Honda Accord’s price (in thousands of dollars), our prediction is typically off by about 3.085 thousand dollars ($3,085) in either direction.
Finally, we identify the cars that deviate most from our model’s predictions.
# Cars priced much higher than predicted
my_data %>%
select(Mileage, Price, predicted, residual) %>%
arrange(desc(residual)) %>%
head(3)
## Mileage Price predicted residual
## 1 4.8 26.8 20.234515 6.565485
## 2 150.5 7.9 2.777915 5.122085
## 3 20.8 22.8 18.317524 4.482476
# Cars priced much lower than predicted
my_data %>%
select(Mileage, Price, predicted, residual) %>%
arrange(desc(residual)) %>%
tail(3)
## Mileage Price predicted residual
## 28 62.0 9.5 13.38127 -3.881272
## 29 64.1 9.0 13.12967 -4.129667
## 30 89.4 3.5 10.09842 -6.598425