I might recommend using a mixed model approach to this.
mat <- data.frame(data=c(12.5,11,13,11.4),
row=factor(rep(1:2,2)),
col=factor(rep(1:2,each=2)),
car=c("B","A","A","B"))
I'm using lmerTest
because it will more easily provide you with (approximate) p-values
By default anova()
uses the Satterthwaite approximation, or you can tell it to use the more accurate Kenward-Roger approximation. In either case you can see that the denominator df are exactly, or nearly zero, and the p-value is either missing or very close to 1, indicating that your model doesn't make sense (i.e. even using the mixed model it's overparameterized).
library("lmerTest")
anova(m1 <- lmer(data~car+(1|row)+(1|col),data=mat))
anova(m1,ddf="Kenward-Roger")
## Sum Sq Mean Sq NumDF DenDF F.value Pr(>F)
## car 0.0025 0.0025 1 9.6578e-06 2.0019 0.9999
Try for a bigger design:
set.seed(101)
mat2 <- data.frame(data=rnorm(36),
row=gl(6,6),
col=gl(6,1,36),
car=sample(LETTERS[1:2],size=36,replace=TRUE))
m2A <- lm(data~car+row+col,data=mat2)
anova(m2A)
## (excerpt)
## Df Sum Sq Mean Sq F value Pr(>F)
## car 1 1.2571 1.25709 1.6515 0.211
m2B <- lmer(data~car+(1|row)+(1|col),data=mat2)
anova(m2B)
## Sum Sq Mean Sq NumDF DenDF F.value Pr(>F)
## car 1.178 1.178 1 17.098 1.56 0.2285
anova(m2B,ddf="Kenward-Roger")
## Sum Sq Mean Sq NumDF DenDF F.value Pr(>F)
## car 1.178 1.178 1 17.005 1.1029 0.3083
It surprises me a little bit that the lm
and lmerTest
answers are so far apart here -- I would have thought this was an example where there was a well-formulated "classic" answer -- but I'm not sure. Might be worth following up on CrossValidated or Google.