Setup & Packages

library(Stat2Data)
library(dplyr)
library(ggplot2)

data("AccordPrice")
my_data <- AccordPrice

Step 1: Exploratory Data Analysis & Fitting the Model

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}\]


Step 2: Visualizing the Line & Hand-Calculating a Residual

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.


Step 3: Residual Plot & Diagnostic Checking

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.


Step 4: Model Evaluation (\(R^2\) and Residual Standard Error)

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.


Step 5: Sorting by Residuals

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