If you use a factor effects model (with an intercept), then you will have a baseline group (the intercept), and all other coefficients except the covariate will be comparisons to that baseline. As an example,
> d.f <- data.frame(bird = gl(2,8), treatment = rep(gl(2,4),2), covariate = rnorm(16))
> d.f
bird treatment covariate
1 1 1 0.81212716
2 1 1 0.50826573
3 1 1 -1.42323759
4 1 1 0.53879638
5 1 2 -1.60911574
6 1 2 0.01093034
7 1 2 0.30382950
8 1 2 -0.05913059
9 2 1 0.40958148
10 2 1 0.82431947
11 2 1 0.20903198
12 2 1 1.72899120
13 2 2 -0.49035449
14 2 2 -0.38955983
15 2 2 -0.78778822
16 2 2 -0.52687839
> model.matrix(~bird * treatment + covariate, d.f)
(Intercept) bird2 treatment2 covariate bird2:treatment2
1 1 0 0 0.81212716 0
2 1 0 0 0.50826573 0
3 1 0 0 -1.42323759 0
4 1 0 0 0.53879638 0
5 1 0 1 -1.60911574 0
6 1 0 1 0.01093034 0
7 1 0 1 0.30382950 0
8 1 0 1 -0.05913059 0
9 1 1 0 0.40958148 0
10 1 1 0 0.82431947 0
11 1 1 0 0.20903198 0
12 1 1 0 1.72899120 0
13 1 1 1 -0.49035449 1
14 1 1 1 -0.38955983 1
15 1 1 1 -0.78778822 1
16 1 1 1 -0.52687839 1
attr(,"assign")
[1] 0 1 2 3 4
attr(,"contrasts")
attr(,"contrasts")$bird
[1] "contr.treatment"
attr(,"contrasts")$treatment
[1] "contr.treatment"
The intercept in this case is bird1, treatment1. And bird2 is bird2, treatment1 - bird1, treatment1 (where bird1 is the first type of bird, not the first bird). The treatment2 coefficient 'adjusts out' the difference between the two treatments, so the bird2 coefficient is the difference between bird types, adjusted for treatment and the coefficient. The treatment2 coefficient can be interpreted similarly. But neither of the main effects can be interpreted in the context of a significant interaction term, so technically you should filter out the genes with significant interactions prior to testing for any main effect.
Also, you haven't specified any contrasts. A contrast is a linear combination where the coefficients sum to zero, and your coefficients sum to 1.5.
It's often easier to fit a cell means model and then make whatever comparisons you would like.
> d.f$combo <- with(d.f, paste(bird, treatment, sep = "_"))
> d.f
bird treatment covariate combo
1 1 1 0.81212716 1_1
2 1 1 0.50826573 1_1
3 1 1 -1.42323759 1_1
4 1 1 0.53879638 1_1
5 1 2 -1.60911574 1_2
6 1 2 0.01093034 1_2
7 1 2 0.30382950 1_2
8 1 2 -0.05913059 1_2
9 2 1 0.40958148 2_1
10 2 1 0.82431947 2_1
11 2 1 0.20903198 2_1
12 2 1 1.72899120 2_1
13 2 2 -0.49035449 2_2
14 2 2 -0.38955983 2_2
15 2 2 -0.78778822 2_2
16 2 2 -0.52687839 2_2
> model.matrix(~ 0 + combo + covariate, d.f)
combo1_1 combo1_2 combo2_1 combo2_2 covariate
1 1 0 0 0 0.81212716
2 1 0 0 0 0.50826573
3 1 0 0 0 -1.42323759
4 1 0 0 0 0.53879638
5 0 1 0 0 -1.60911574
6 0 1 0 0 0.01093034
7 0 1 0 0 0.30382950
8 0 1 0 0 -0.05913059
9 0 0 1 0 0.40958148
10 0 0 1 0 0.82431947
11 0 0 1 0 0.20903198
12 0 0 1 0 1.72899120
13 0 0 0 1 -0.49035449
14 0 0 0 1 -0.38955983
15 0 0 0 1 -0.78778822
16 0 0 0 1 -0.52687839
attr(,"assign")
[1] 1 1 1 1 2
attr(,"contrasts")
attr(,"contrasts")$combo
[1] "contr.treatment"
And now each coefficient simply computes the mean of each bird type and treatment combination, and you can make whatever comparisons you would like (e.g. combo1_1 - combo1_2 is the treatment difference for bird species 1, and the contrast would be c(1,-1,0,0,0)
Thank you so much for taking the time and for the detailed explanation!
I was wondering, in your numeric contrast of c(1, -1, 0,0,0), does that account for the covariate as well? I see that you put a 0 and wanted to know if it needed to be changed to the difference of averages? I am particularly interested in understanding how (continuous) covariates are treated.
Also, looking back at your original matrix (and if I understand this correctly), if I wanted to test whether there were a main effect in gene expression between the bird eggs (without including the effect of treatment) while accounting for the covariate, would it just be c(1, 0, 0, whatever the average for the covariate is). Thanks!
The covariate is accounted for when you fit the model, so you don't need to do anything with it at the contrast step.
You don't need a contrast to test for significance of a coefficient that itself is a contrast (everything but the intercept and the covariate in the first model is inherently a contrast). You could compute that contrast using
c(0,1,0,0,0)
, but that's the same as just testing the second coefficient.