2026-10-18

Question

Does a car’s weight predict its fuel efficiency?

Data

head(mtcars[, c("mpg", "wt")])
##                    mpg    wt
## Mazda RX4         21.0 2.620
## Mazda RX4 Wag     21.0 2.875
## Datsun 710        22.8 2.320
## Hornet 4 Drive    21.4 3.215
## Hornet Sportabout 18.7 3.440
## Valiant           18.1 3.460

It seems, looking at the data, that a car’s fuel efficiency generally decreases as its weight increases.

Statistical Idea

Linear regression fits a line to predict mpg from weight. Least squares picks the line with the smallest total squared distance to the points. The slope is how much mpg changes per extra 1000 lbs.

Math: Model

\[Y_i = \beta_0 + \beta_1 x_i + \varepsilon_i\] Each car’s mpg is a starting value plus slope times weight, plus random error.

Math: Slope Estimate

\[\hat{\beta}_1 = \frac{\sum (x_i-\bar{x})(y_i-\bar{y})}{\sum (x_i-\bar{x})^2}\] The top shows how weight and mpg move together. The bottom is how spread out the weights are. Their ratio is the slope.

R Code

fit <- lm(mpg ~ wt, data = mtcars)

lm() fits the regression line. mpg ~ wt means “predict mpg from weight.”

Regression Output

print(summary(fit), digits = 3)
## 
## Call:
## lm(formula = mpg ~ wt, data = mtcars)
## 
## Residuals:
##    Min     1Q Median     3Q    Max 
## -4.543 -2.365 -0.125  1.410  6.873 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   37.285      1.878   19.86  < 2e-16 ***
## wt            -5.344      0.559   -9.56  1.3e-10 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 3.05 on 30 degrees of freedom
## Multiple R-squared:  0.753,  Adjusted R-squared:  0.745 
## F-statistic: 91.4 on 1 and 30 DF,  p-value: 1.29e-10

ggplot2: Scatterplot

ggplot(mtcars, aes(wt, mpg)) + geom_point() + geom_smooth(method = "lm")
## `geom_smooth()` using formula = 'y ~ x'

Heavier cars get fewer mpg, and most points sit close to the line.

ggplot2: Residuals

ggplot(mtcars, aes(fitted(fit), resid(fit))) + geom_point() + geom_hline(yintercept = 0)

A residual is how far a car is from the line. The points scatter on both sides of zero with no clear pattern, so a straight line is a reasonable fit.

Plotly: Weight, Horsepower, MPG

plot_ly(mtcars, x = ~wt, y = ~hp, z = ~mpg,
        type = "scatter3d", mode = "markers")

Heavy cars also tend to have more horsepower, so I added it as a third variable. Rotate the plot to explore.

What Did We Learn?

  • Each extra 1000 lbs goes with about 5.3 fewer mpg.
  • Weight explains about 75% of the variation in mpg (R² = 0.75).
  • The relationship is very unlikely to be chance (p = 1.3e-10).
  • Limitation: only 32 cars, and correlation is not causation.