In this analysis, we explore whether we can price a used Honda Accord just by reading its odometer. Mileage serves as our explanatory variable (\(x\)), and price serves as our response variable (\(y\)).
library(Stat2Data)
library(dplyr)
library(ggplot2)
data(AccordPrice)
my_data <- AccordPrice
# Scatterplot of Price vs. Mileage
ggplot(my_data, aes(x = Mileage, y = Price)) +
geom_point(alpha = 0.6) +
labs(
title = "Honda Accord Price vs. Mileage",
x = "Mileage (thousands of miles)",
y = "Price (thousands of dollars)"
)
# Compute correlation
cor_value <- cor(my_data$Mileage, my_data$Price)
print(cor_value)
## [1] -0.8489441
The correlation coefficient is \(r = -0.84\).
Next, we fit a linear model to our data to find the slope and intercept.
model <- lm(Price ~ Mileage, data = my_data)
coef(model)
## (Intercept) Mileage
## 20.8096129 -0.1198119
The values obtained are: - \(r = -0.84\) - Slope = \(-0.119\) - Intercept = \(20\)
The negative sign of the slope matches the negative sign of \(r\), as expected.
To understand how far off our line is for a specific car, we add the fitted line to our scatterplot and inspect the first row of our dataset.
# Scatterplot with fitted line
ggplot(my_data, aes(x = Mileage, y = Price)) +
geom_point(alpha = 0.6) +
geom_abline(intercept = 20, slope = -0.119, color = "steelblue", linewidth = 1) +
labs(
title = "Honda Accord Price vs. Mileage with Fitted Line",
x = "Mileage (thousands of miles)",
y = "Price (thousands of dollars)"
)
# Inspect first row of data
my_data %>% select(Mileage, Price) %>% head(1)
## Mileage Price
## 1 74.9 12
For the first car in the dataset, the actual price is $12,000. Evaluating the residual manually shows that the point is above the line by about \(0.2\) thousand dollars ($200).
To check whether a straight line is appropriate for these data, we compute the predicted values and residuals for all data points and construct a residual plot.
# Add predicted values and residuals
my_data <- my_data %>%
mutate(predicted = fitted(model), residual = residuals(model))
# View columns
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
# Residual plot
ggplot(my_data, aes(x = Mileage, y = residual)) +
geom_point(alpha = 0.6) +
geom_hline(yintercept = 0, color = "steelblue", linewidth = 1) +
labs(
title = "Residual Plot for Honda Accord Price",
x = "Mileage (thousands of miles)",
y = "Residual (thousands of dollars)"
)
The residual plot appears boring (a random cloud of points centered around zero with no distinct pattern), which indicates that using a straight line model is appropriate for these data.
Finally, we examine the summary output of our linear model to evaluate overall fit and 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
Based on the model summary: - R-squared: Approximately 72% of the variation in price is explained by mileage. - Residual standard error: Measures the typical distance that data points fall from the regression line, in the units of thousands of dollars.