Lesson 11 of 17 · Week 05 · Tue Oct 27

Regression in Practice

Questions

Objectives

A question worth a line

Do people in richer countries live longer? Look at one year of gm:

library(ggplot2)
gm07 <- gm[gm$year == 2007, ]
ggplot(gm07, aes(x = gdpPercap, y = lifeExp)) +
  geom_point() +
  scale_x_log10()

On a log scale for GDP, the points fall roughly along a straight line. A linear regression finds the best-fitting line and gives you numbers to describe it: how steep it is, and how closely the points follow it. We'll use log10(gdpPercap) as the predictor, because each step of 1 on that scale is a ten-fold increase in income.

This lesson was written for this course; it has no Carpentries counterpart.

Fitting a model with lm()

fit <- lm(lifeExp ~ log10(gdpPercap), data = gm07)
fit

The formula y ~ x reads “y explained by x”: the response goes on the left of the ~, the predictor on the right. data = says where to find those columns. The result, fit, is a model object: a list holding the estimates, the fitted values, the residuals and more (names(fit)).

Reading the coefficients

coef(fit)
#      (Intercept) log10(gdpPercap)
#            a                b
b <- coef(fit)[2]        # the slope
a <- coef(fit)[1]        # the intercept
a + b * log10(5000)      # predicted life expectancy at $5,000 per person
predict(fit, newdata = data.frame(gdpPercap = 5000))   # the same, with predict()

Slope: for each ten-fold increase in GDP per capita, predicted life expectancy is b years higher. Intercept: the prediction when log10(gdpPercap) is 0, i.e. at $1 per person. That's far outside the data, so on its own it doesn't mean much; it's there to position the line.

Reading summary()

summary(fit)
summary(fit)$r.squared           # R-squared
summary(fit)$coefficients        # estimates, std. errors, t values, p-values

From the output, read three things:

We won't go further into inference (standard errors, confidence intervals, assumptions) in this course. Just read these three numbers carefully.

Plotting the fit

ggplot(gm07, aes(x = gdpPercap, y = lifeExp)) +
  geom_point() +
  scale_x_log10() +
  geom_smooth(method = "lm", se = FALSE)

Because the x-axis is already on a log scale, geom_smooth(method = "lm") fits the same line as lm(lifeExp ~ log10(gdpPercap)).

Residuals: what the line misses

gm07$fitted <- fitted(fit)
gm07$resid  <- residuals(fit)          # observed minus fitted
gm07[order(gm07$resid), c("country", "lifeExp", "fitted", "resid")]
ggplot(gm07, aes(x = fitted, y = resid)) + geom_point() + geom_hline(yintercept = 0)

A residual is how far a point sits above (positive) or below (negative) the line. Large residuals are often the most interesting part of an analysis. Why would a country live much shorter lives than its income predicts? In the residual plot, you hope to see a shapeless cloud around zero. A curve or a funnel means the straight line is missing something.

A line is not a cause. Regression describes an association in these data. Income, health systems, education and history are all tangled together. The model can't tell you that raising GDP will raise life expectancy.

Exercises

Each exercise gives you up to 10 checked attempts. Use Run as many times as you like to experiment first, then click Check answer when you're ready. Your exercises use numbers/subsets unique to you, so answers won't match a classmate's exactly.

Exercise 1 — Fit your first model

0 / 10 attempts used

Click Run to see your year, yr. Make gm_y, the rows of gm from that year, and fit fit: a linear model of life expectancy explained by log10(gdpPercap), using gm_y. Print fit.

Pasting isn't accepted here — please type your answer so it reflects your own work.

      

Exercise 2 — Slope, intercept, prediction

0 / 10 attempts used

fit (your model from Exercise 1) is ready. Using coef(fit), not typed-in numbers, store the slope in slope, the intercept in intercept, and in pred the predicted life expectancy for a country with a GDP per capita of g (click Run to see it).

Then say to yourself, in a sentence, what the slope means.

Pasting isn't accepted here — please type your answer so it reflects your own work.

      

Exercise 3 — Read the summary

0 / 10 attempts used

Run summary(fit) and find the slope's p-value and the R-squared. Store them by extracting them from the summary, not by typing: r2 from summary(fit)$r.squared, and p_slope from the right row and column of summary(fit)$coefficients. Finally, set share to the percentage of the variation in life expectancy the model accounts for.

Pasting isn't accepted here — please type your answer so it reflects your own work.

      

Exercise 4 — Plot the fitted line

0 / 10 attempts used

Make p_fit: a scatterplot of gm_y with GDP per capita on a log-scaled x-axis and life expectancy on y, plus the fitted straight line from geom_smooth().

Pasting isn't accepted here — please type your answer so it reflects your own work.

      

Exercise 5 — Who is furthest below the line?

0 / 10 attempts used

Add a column resid to gm_y holding the model's residuals. Then store in below the name of the country that lives shortest lives relative to what its income predicts, as text. Look it up afterwards: why might that be?

Pasting isn't accepted here — please type your answer so it reflects your own work.

      

Exercise 6 — Does the log help?

0 / 10 attempts used

Fit a second model, fit_raw, using gdpPercap itself (no log) as the predictor, on the same gm_y. Compare the two R-squared values and set better to "log" or "raw" for the model that accounts for more variation. Plot both to see why.

Pasting isn't accepted here — please type your answer so it reflects your own work.

      

Key Points

Proof of completion

Once you've attempted every exercise above, download a PDF summary of your work on this lesson — your name, the exercises you passed, attempt counts, timing, and your final code for each.