I have a data set where I want to compare different treatments with a certain baseline. So I basically have a linear model (ANOVA) like this:

outcome = b_0 + sum_i(b_i * x_i)

with b_i the fitted parameters and x_i dummy variables or contrasts. Now I have two ways I can code my dummy variables:

1) default dummy coding

for treatment k: x_k = 1, x_i = 0 for i!=k

for baseline: x_i = 0 for all i

in this way, I obtain:

b_0 = mean(outcome(control))

b_i = mean(outcome(treatment_i)) - mean(outcome(control))

2) (non-orthogonal) contrasts to explicitly compare treatments with baseline

for treatment k: x_k = 1, x_i = 0 for i!=k

for baseline: x_i = -1 for all i

in this way, I obtain:

b_0 = mean(outcome(all)) = "grand mean"

b_i = mean(outcome(treatment_i)) - "grand mean"

So, although I expected the second coding to be the one that explicitly compares treatments with the baseline (by having a "-1,1" contrast for each treatment) [*], it actually compares treatments with the grand mean, which I don't want.

I see that I will have to use option 1), but I am confused by the fact that the contrasts actually don't do what I expect them to do. So what is wrong with my reasoning in option 2)?

[*] (edit to clear things up a bit): This reasoning was coming from the book "Discovering Statistics Using R" from Andy Field. There, he gave a nice recipe to define "contrasts" using weights:

  • Rule 1: Choose sensible comparisons. Remember that you want to compare only two chunks of variation and that if a group is singled out in one comparison, that group should be excluded from any subsequent contrasts.

  • Rule 2: Groups coded with positive weights will be compared against groups coded with negative weights. So, assign one chunk of variation positive weights and the opposite chunk negative weights.

  • Rule 3: The sum of weights for a comparison should be zero. If you add up the weights for a given contrast the result should be zero.

  • Rule 4: If a group is not involved in a comparison, automatically assign it a weight of 0. If we give a group a weight of 0 then this eliminates that group from all calculations.

  • Rule 5: For a given contrast, the weights assigned to the group(s) in one chunk of variation should be equal to the number of groups in the opposite chunk of variation.

A bit further in the book, he explains that non-orthogonal comparisons can also be done with the same recipe, but by simply disobeying rule 1 in the recipe above.

  • $\begingroup$ What you call "contrasts" is deviation type contrasts. You might want to use simple contrasts if you want b0 to represent grand mean but bi to represent mean_i - mean_ref. stats.stackexchange.com/a/221868/3277 $\endgroup$
    – ttnphns
    Commented Sep 22, 2018 at 6:46

1 Answer 1


(I am answering my own question here.)

My confusion was a result of the very ill-defined concept of contrasts or contrast matrices. The very nice answer of @ttnphns here could clear everything up for me.

So, apparently the recipe of Andy Field works only for orthogonal contrasts; if you use it to define non-orthogonal contrasts, you won't get what you expect.

How does the dummy coding work and how to get to the interpretation of b coefficents?

Consider a one-way ANOVA which models an outcome y as function of a factor A with K levels:

y ~ A

Equivalently, we can consider a regression model with k-1 dummy or contrast variables x_i (as defined in the question):

observation n of N: y(n) = b_{0} + b_{1}*x_{1}(n) + ... + b_{k-1} *x_{K-1}(n) + error

We can combine all N observations in one matrix description, which we can solve to get the fitted b coefficients:

Y = X*b ( + error)

with Y a column with N observations, b a column of K fitted parameters (the first one being the offset), and X a "K x N"-matrix, with the first column being 1's (corresponding to the offset). This can be solved to obtain the fitted b parameters:

b = (X^T * X)^(-1) * X^T *Y

Now we can summarize this description by using the mean (as calculated by the model) for each level:

Y_mean = C*b

with Y_mean a column for the K observed groups. C is now a "K x K"-matrix; the first column is still a column of 1's. For example, one row for group k:

Y_mean(k) = b_{0} + b_{1}*x_{1}(k) + ... + b_{k-1} *x_{K-1}(k) 

(no more error because this is the mean as fitted by the model)

This matrix C can be called a "contrast coding matrix". It tells you the values of the dummy variables for each level of the factor A. The last K-1 columns (the first column is always a column of 1's) is what you enter in R as the "contrast matrix".

Now, this C is invertible, such that we obtain (this corresponds to the calculation of the b coefficients as a function of group means as it done in your book):

b = C^(-1) * Y_mean = L * Y_mean 

This matrix L can be called the "contrast coefficient matrix". It gives you an interpretation of the b coefficients as a function of the group means. This means that we have to look at this matrix L, and not at the contrast coding matrix, when we want to interpret what our contrasts are doing.

So why can you sometimes use the dummy$^1$ variables themselves (matrix C) to interpret the b coefficients?

If your matrix C consists of orthogonal columns, the inverse of this matrix C will have rows that are proportional to the rows of the transpose of this matrix C. Or in other words, the rows of matrix L are proportional to the columns of matrix C if C consists of orthogonal columns. This means that C can also be used to interpret the meaning of the contrast variables, but only if the contrasts are orthogonal.

$^1$ I'm using here word "dummy" in wide sense, i.e. any contrast variable type, not just indicator (or one-hot) type.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.