Chapter 13 uses dummy coding throughout, and says so: a categorical predictor becomes a set of 0/1 indicators, the intercept is the reference group’s mean, and each coefficient is a difference from that reference.
That is the sociology convention, and this book follows it. But it is not the only scheme, and you will meet others in print, particularly in psychology, where the same model is routinely written a different way. This appendix covers the main alternative, so that a table coded that way does not look like a different analysis.
Let’s look at Southern and non-Southern states in 1977 and compare them on life expectancy.
state.x77_with_names <-as_tibble(state.x77,rownames ="state")states <-bind_cols(state.x77_with_names,region = state.division) |># both are in base R janitor::clean_names() |># lower case and underscoremutate(south =as.integer( # make a south dummystr_detect(as.character(region),"South")))
Warning in FUN(X[[i]], ...): unable to translate '<U+00C4>' to native encoding
Warning in FUN(X[[i]], ...): unable to translate '<U+00D6>' to native encoding
Warning in FUN(X[[i]], ...): unable to translate '<U+00DC>' to native encoding
Warning in FUN(X[[i]], ...): unable to translate '<U+00E4>' to native encoding
Warning in FUN(X[[i]], ...): unable to translate '<U+00F6>' to native encoding
Warning in FUN(X[[i]], ...): unable to translate '<U+00FC>' to native encoding
Warning in FUN(X[[i]], ...): unable to translate '<U+00DF>' to native encoding
Warning in FUN(X[[i]], ...): unable to translate '<U+00C6>' to native encoding
Warning in FUN(X[[i]], ...): unable to translate '<U+00E6>' to native encoding
Warning in FUN(X[[i]], ...): unable to translate '<U+00D8>' to native encoding
Warning in FUN(X[[i]], ...): unable to translate '<U+00F8>' to native encoding
Warning in FUN(X[[i]], ...): unable to translate '<U+00C5>' to native encoding
Warning in FUN(X[[i]], ...): unable to translate '<U+00E5>' to native encoding
states |>group_by(south) |>summarize(mean =mean(life_exp), n =n())
# A tibble: 2 x 3
south mean n
<int> <dbl> <int>
1 0 71.4 34
2 1 69.7 16
D.1 Two approaches to coding a predictor
The coding of south above is called dummy coding or reference coding and is by far the most common in sociology. But sometimes you will see effect coding (also called deviation or contrast coding) that codes the predictor (-1, 1) instead of (0, 1).
ma <-lm(life_exp ~1+ south, data = states)states <- states |>mutate(south_eff =if_else(south ==1, 1, -1))ma_effect <-lm(life_exp ~ south_eff, data = states)
With effect coding, the intercept is the grand mean, or the overall mean you’d expect if both groups were the same size. And \(b_1\) is half the difference between the two groups.
Both of those are worth checking:
group_means <- states |>group_by(south) |>summarize(m =mean(life_exp)) |>pull(m)c(intercept =unname(coef(ma_effect)[1]),unweighted_average =mean(group_means),overall_mean =mean(states$life_exp))
Same \(R^2\), same fitted values, same residuals, same F test. Only the parameterization differs, the same point made in Chapter 13 about relevel(). Changing how you write a model down does not change the model.
D.3 More than two groups
With \(k\) groups, effect coding generalizes to coding each category’s departure from the unweighted grand mean, which is what the mean would be if all groups were of equal size. In R the scheme is contr.sum().
states <- states |>mutate(reg4 =factor(state.region))states |>group_by(reg4) |>summarize(mean =mean(life_exp), n =n())
# A tibble: 4 x 3
reg4 mean n
<fct> <dbl> <int>
1 Northeast 71.3 9
2 South 69.7 16
3 North Central 71.8 12
4 West 71.2 13
contrasts(states$reg4) <-contr.sum(4)m4 <-lm(life_exp ~ reg4, data = states)round(coef(m4), 3)
The intercept is the unweighted grand mean, and each of the three coefficients is one region’s deviation from it:
region_means <- states |>group_by(reg4) |>summarize(m =mean(life_exp)) |>pull(m)c(intercept =unname(coef(m4)[1]), unweighted_grand_mean =mean(region_means))
intercept unweighted_grand_mean
70.99299 70.99299
round(region_means -mean(region_means), 3)
[1] 0.271 -1.287 0.774 0.242
Three coefficients for four groups, as always. The fourth deviation is not printed because it is not free: the deviations have to sum to zero, so the last one is minus the sum of the others.
printed1 printed2 printed3 implied_fourth total
0.2714503 -1.2867441 0.7736725 0.2416213 0.0000000
You can see these estimates sum to zero. That constraint is what makes the scheme deviation coding: every group is described relative to a common center rather than to one chosen group.
NoteWhen you will meet it
Effect coding is standard in the experimental psychology tradition, where designs are often balanced (equal group sizes) and the grand mean is the natural baseline. In a balanced design the unweighted and weighted averages coincide, so the intercept is simply “the mean,” and each coefficient reads as a deviation from it.
In observational sociology, groups are rarely balanced and there is usually a substantively natural reference category: no college, unmarried, non-South. Dummy coding says what you want to say, and it says it in units a reader can check against a table of group means.
That is why this book uses dummy coding. Effect coding is here so that when you read a table with an intercept that does not match any group’s mean and coefficients that look half the size you expect, you know what you are looking at.
With 16 southern and 34 other states, the effect-coded intercept 70.568 is not the mean life expectancy of American states. That is 70.879. It is the average of the two group means, which gives a state in a small group more weight than a state in a large one.
Reported carelessly, that is a real error. If you use effect coding, say that the intercept is the unweighted grand mean and not the sample mean.