After many years of learning about contrasts in linear models I am curious about the relative usefulness of deviation coding, as it is defined by this website. I would appreciate someone filling me in on a few things. Here is a data simulation exercise to highlight the source of my confusion. I want to simulate data where there is one two-level categorical predictor (group
) and one continuous predictor (pred
). I have programmed in between-group differences in the relationship of both predictors to the outcome variable (outcome
).
# toy data
set.seed(0001)
# two variables with a .7 correlation, where mean of outcome variable is 0
mu1 <- c(0,0)
Sigma1 <- matrix(.7, nrow=2, ncol=2) + diag(2)*.3
rawvars1 <- as.data.frame(MASS::mvrnorm(n=100, mu=mu1, Sigma=Sigma1))
names(rawvars1) <- c("pred", "outcome")
# two variables with a .3 correlation where mean of outcome variable is 4
mu2 <- c(0,4)
Sigma2 <- matrix(.3, nrow = 2, ncol = 2) + diag(2)*.7
rawvars2 <- as.data.frame(MASS::mvrnorm(n=100, mu=mu2, Sigma=Sigma2))
names(rawvars2) <- c("pred", "outcome")
# bind dataframes and add a grouping variable
df <- rbind(rawvars1, rawvars2)
df$group <- factor(rep(letters[1:2], each = 100))
Let's check that we did what we intended to by getting the pred-outcome
correlations at each level of group
by(df, df$group, function (i) cor.test(i$outcome, i$pred))
Good. Correlations of r = .666 in group a
and r = .3 in group b
. Very close to the correlations we programmed into the two datasets before we bound them. What about the means of the outcomes?
tapply(df$outcome, df$group, mean)
Means of ~0 for the outcome in group a
and ~4 in group b
. So our dataframe behaves like we told it to. Now let's try regression with different coding scheme
Treatment coding
lm(outcome ~ pred*group, df, contrasts = list(group = c(0,1)))
# Coefficients:
# (Intercept) pred group1 pred:group1
# 0.009227 0.665201 4.047715 -0.288114
Ok so here the intercept is the mean of the outcome in group a
, which is about 0. Next the pred
coefficient is the amount thatpred
predicts the outcome in group a
only, about the same as the correlation we extracted earlier, so good. Next, the group1
coefficient is the difference in mean outcome value (i.e. intercept) between group b
compared to group a
. Once again this is right, a predicted difference of ~4. Lastly the pred:group1
coefficient is the difference in slope between group b
and group a
= .665 + -.288 = .377, which, once again is about what the correlation was between the predictor and outcome in group b
. This coding scheme has retrieved the parameters accurately. Next simple coding
Simple coding
lm(outcome ~ pred*group, df, contrasts = list(group = c(-.5,.5)))
# Coefficients:
# (Intercept) pred group1 pred:group1
# 2.0331 0.5211 4.0477 -0.2881
Here the intercept should be the grand mean
mean(df$outcome)
[1] 2.070099
...close enough. And the pred
coefficient should be the slope/correlation averaged across groups
mean(c(.665, .377))
[1] 0.521
The group
coefficient is also correct, a mean difference of four, and the pred:group1
coefficient once again is the difference in slope between groups: -2.88. Like treatment coding, simple coding gives us accurate information. Its incremental benefit over treatment coding is that it yields something like a 'main effect' contrast, the pred
coefficient, which is the amount that the pred
predictor predicts the outcome, averaged across groups.
Deviation coding
lm(outcome ~ pred*group, df, contrasts = list(group = c(-1,1)))
# Coefficients:
# (Intercept) pred group1 pred:group1
# 2.0331 0.5211 2.0239 -0.1441
I am confused about what the coefficients are giving us here. Here the intercept is once again the grand mean, the pred
coefficient is the slope averaged across groups, but the coefficients for the group1
and pred:group1
are exactly half what they are in under the simple coding scheme
So is the group
coefficient simply half of the real difference between groups, half of the coefficient obtained by the simple coding scheme, i.e. incorrect?
2 * 2.0239
[1] 4.0478
Or is it the difference between the group b
mean outcome and the grand mean?
2.0331 + 2.0239
[1] 4.057 # not quite right but close
And what is the pred:group1
coefficient, if not mistaken?
And how does any of this relate to type-1 and type-3 sums of squares? The deviation coding is what we get if we specify options(contrasts = c("contr.sum", "contr.poly))
, which is supposed to be type-3 (a la SPSS default coding). But it doesn't retrieve the correct parameters, unless I am mistaken and interpreting the regression output incorrectly.
group1
coefficient from the regression with deviation coding is the result of the comparison of the groupb
mean (4.054) to the mean of the cell means for groupa
and groupb
[(0.086 +4.054)/2 = 2.070], which is 4.054 - 2.070 = 1.984. Quite close to thegroup1
coefficient in the deviation coding scheme (2.0239). Am I interpreting this correctly? And if so, what does thepred:group1
coefficient represent? $\endgroup$