aov() error term in R: what's the difference bw Error(id) and Error(id/timevar) specification?

NeverTim picture NeverTim · May 28, 2016 · Viewed 10.7k times · Source

What is the difference between the aov(depvar~timevar+Error(id)) and the aov(depvar~timevar+Error(id/timevar)) formula specifications? These two variants produce slightly different results.

The same question was once asked here: https://stats.stackexchange.com/questions/60108/how-to-write-the-error-term-in-repeated-measures-anova-in-r However, I'd like to repeat it with a more appropriate example.

Here is an example that I created:

var=rep(NA,180)
id=rep(1:20,each=180/20)
group=rep(rep(1:2,each=9),180/(9*2))
time1=rep(rep(1:3,each=3),180/(3*3))
time2=rep(c(8,15,20),180/3)

var[group==1&time1==1&time2==8]=runif(10,105,115)
var[group==2&time1==1&time2==8]=runif(10,105,115)
var[group==1&time1==1&time2==15]=runif(10,95,105)
var[group==2&time1==1&time2==15]=runif(10,95,105)
var[group==1&time1==1&time2==20]=runif(10,85,95)
var[group==2&time1==1&time2==20]=runif(10,85,95)

var[group==1&time1==2&time2==8]=runif(10,95,105)
var[group==2&time1==2&time2==8]=runif(10,95,105)
var[group==1&time1==2&time2==15]=runif(10,85,95)
var[group==2&time1==2&time2==15]=runif(10,75,85)
var[group==1&time1==2&time2==20]=runif(10,75,85)
var[group==2&time1==2&time2==20]=runif(10,65,75)

var[group==1&time1==3&time2==8]=runif(10,95,105)
var[group==2&time1==3&time2==8]=runif(10,95,105)
var[group==1&time1==3&time2==15]=runif(10,85,95)
var[group==2&time1==3&time2==15]=runif(10,75,85)
var[group==1&time1==3&time2==20]=runif(10,75,85)
var[group==2&time1==3&time2==20]=runif(10,65,75)

df=data.frame(id,var,group,time1,time2)
df$id=factor(df$id)
df$group=factor(df$group)
df$time1=factor(df$time1)
df$time2=factor(df$time2)

Performing aov() on this gets slightly different results depending on Error() term specification:

Just for one time term:

> summary(aov(var~time1+Error(id),data=df))
Error: id
      Df Sum Sq Mean Sq F value Pr(>F)
      Residuals 19  958.4   50.44               
Error: Within
       Df Sum Sq Mean Sq F value   Pr(>F)    
       time1       2   7538    3769   30.41 6.72e-12 ***
       Residuals 158  19584     124         

> summary(aov(var~time1+Error(id/time1),data=df))
Error: id
      Df Sum Sq Mean Sq F value Pr(>F)
      Residuals 19  958.4   50.44               
Error: id:time1
      Df Sum Sq Mean Sq F value Pr(>F)    
      time1      2   7538    3769   211.5 <2e-16 ***
      Residuals 38    677      18                   
      ---
     Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Error: Within
       Df Sum Sq Mean Sq F value Pr(>F)
       Residuals 120  18907   157.6    

Or for both time terms (don't type output here for the sake of space, your may check it on your own):

summary(aov(var~group*time1*time2+Error(id/(group*time1*time2)),data=df)) 
summary(aov(var~group*time1*time2+Error(id),data=df)) 

Why does it happen? Which variant is correct?

Answer

Eric Leung picture Eric Leung · Mar 8, 2017

Here's a blog post that'll help break down what each means under the "Random Effects in Classical ANOVA" section.

From the blog, here's a summary for what "dividing" in the Error term means.

aov(Y ~ Error(A), data=d)               # Lone random effect
aov(Y ~ B + Error(A/B), data=d)         # A random, B fixed, B nested within A
aov(Y ~ (B*X) + Error(A/(B*X)), data=d) # B and X interact within levels of A

So from your question,

aov(depvar~timevar+Error(id/timevar))

means you have a random effect from id but then fix timevar with timevar nested within id levels versus

aov(depvar~timevar+Error(id))

which is just taking id as the random effects with no constraint on other variables.

Source: http://conjugateprior.org/2013/01/formulae-in-r-anova/

This might prove useful as well, which is some code going over analysis of variance that has some recommendations on learning ANOVA.