I gradi di libertà in lmerTest :: anova sono corretti? Sono molto diversi da RM-ANOVA


10

Sto analizzando i risultati di un esperimento sul tempo di reazione in R.

Ho eseguito una misurazione ripetuta ANOVA (1 fattore entro soggetto con 2 livelli e 1 fattore tra soggetto con 2 livelli). Ho eseguito un modello misto lineare simile e volevo riassumere i risultati più bassi sotto forma di tabella ANOVA utilizzando lmerTest::anova.

Non fraintendetemi: non mi aspettavo risultati identici, tuttavia non sono sicuro dei gradi di libertà nei lmerTest::anovarisultati. Mi sembra che rifletta piuttosto un ANOVA senza aggregazione a livello di soggetto.

Sono consapevole del fatto che il calcolo dei gradi di libertà nei modelli a effetti misti è complicato, ma lmerTest::anovaè menzionato come una possibile soluzione ?pvaluesnell'argomento aggiornato ( lme4pacchetto).

Questo calcolo è corretto? I risultati di lmerTest::anovariflettono correttamente il modello specificato?

Aggiornamento: ho aumentato le differenze individuali. I gradi di libertà lmerTest::anovasono più diversi dalla semplice anova, ma non sono ancora sicuro del perché siano così grandi per il fattore / interazione all'interno del soggetto.

# mini example with ANT dataset from ez package
library(ez); library(lme4); library(lmerTest)

# repeated measures ANOVA with ez package
data(ANT)
ANT.2 <- subset(ANT, !error)
# update: make individual differences larger
baseline.shift <- rnorm(length(unique(ANT.2$subnum)), 0, 50)
ANT.2$rt <- ANT.2$rt + baseline.shift[as.numeric(ANT.2$subnum)]

anova.ez <- ezANOVA(data = ANT.2, dv = .(rt), wid = .(subnum), 
  within = .(direction), between = .(group))
anova.ez

# similarly with lmer and lmerTest::anova
model <- lmer(rt ~ group * direction + (1 | subnum), data = ANT.2)
lmerTest::anova(model)

# simple ANOVA on all available data
m <- lm(rt ~ group * direction, data = ANT.2)
anova(m)

Risultati del codice sopra [ aggiornato ]:

anova.ez

$ ANOVA

           Effect DFn DFd         F          p p<.05          ges
2           group   1  18 2.6854464 0.11862957       0.1294475137
3       direction   1  18 0.9160571 0.35119193       0.0001690471
4 group:direction   1  18 4.9169156 0.03970473     * 0.0009066868

lmerTest :: anova (modello)

Analysis of Variance Table of type 3  with  Satterthwaite 
approximation for degrees of freedom
                Df Sum Sq Mean Sq F value Denom Pr(>F)
group            1  13293   13293  2.6830    18 0.1188
direction        1   1946    1946  0.3935  5169 0.5305
group:direction  1  11563   11563  2.3321  5169 0.1268

anova (m)

Analysis of Variance Table

Response: rt
                  Df   Sum Sq Mean Sq  F value Pr(>F)    
group              1  1791568 1791568 242.3094 <2e-16 ***
direction          1      728     728   0.0985 0.7537    
group:direction    1    12024   12024   1.6262 0.2023    
Residuals       5187 38351225    7394                    
---
Signif. codes:  0***0.001**0.01*0.05 ‘.’ 0.1 ‘ ’ 1

Risposte:


13

Io penso che lmerTeststa ottenendo nel modo giusto e ezanovasta ottenendo sbagliato in questo caso.

  • i risultati sono in lmerTestaccordo con la mia intuizione / comprensione
  • due diversi calcoli in lmerTest(Satterthwaite e Kenward-Roger) concordano
  • sono anche d'accordo con nlme::lme
  • quando lo eseguo, ezanovadà un avviso, che non capisco del tutto, ma che non dovrebbe essere ignorato ...

Esempio di riesecuzione:

library(ez); library(lmerTest); library(nlme)
data(ANT)
ANT.2 <- subset(ANT, !error)
set.seed(101)  ## for reproducibility
baseline.shift <- rnorm(length(unique(ANT.2$subnum)), 0, 50)
ANT.2$rt <- ANT.2$rt + baseline.shift[as.numeric(ANT.2$subnum)]

Capire il design sperimentale

with(ANT.2,table(subnum,group,direction))

Quindi sembra che gli individui ( subnum) siano collocati in entrambi i gruppi di controllo o di trattamento, e ciascuno è testato per entrambe le direzioni - cioè la direzione può essere testata all'interno degli individui (il denominatore df è grande), ma il gruppo e il gruppo: la direzione può essere testata solo tra individui

(anova.ez <- ezANOVA(data = ANT.2, dv = .(rt), wid = .(subnum), 
    within = .(direction), between = .(group)))
## $ANOVA
##            Effect DFn DFd         F          p p<.05          ges
## 2           group   1  18 2.4290721 0.13651174       0.1183150147
## 3       direction   1  18 0.9160571 0.35119193       0.0002852171
## 4 group:direction   1  18 4.9169156 0.03970473     * 0.0015289914

Qui ottengo che Warning: collapsing data to cell means. *IF* the requested effects are a subset of the full design, you must use the "within_full" argument, else results may be inaccurate. il denominatore DF abbia un aspetto un po 'funky (tutti uguali a 18): penso che dovrebbero essere più grandi per direzione e gruppo: direzione, che può essere testato in modo indipendente (ma sarebbe più piccolo se aggiunto (direction|subnum)al modello)?

# similarly with lmer and lmerTest::anova
model <- lmer(rt ~ group * direction + (1 | subnum), data = ANT.2)
lmerTest::anova(model)
##                 Df  Sum Sq Mean Sq F value Denom Pr(>F)
## group            1 12065.7 12065.7  2.4310    18 0.1364
## direction        1  1952.2  1952.2  0.3948  5169 0.5298
## group:direction  1 11552.2 11552.2  2.3299  5169 0.1270

la Dfcolonna qui si riferisce al numeratore df, Denom(penultimo) indica il denominatore stimato df; sono d'accordo con l'intuizione classica. Ancora più importante, otteniamo anche risposte diverse per i valori F ...

Possiamo anche ricontrollare con Kenward-Roger ( molto lento perché comporta il rimontaggio del modello più volte)

lmerTest::anova(model,ddf="Kenward-Roger")

I risultati sono identici

Per questo esempio lme(dal nlmepacchetto) fa davvero un ottimo lavoro indovinando l'appropriato denominatore df (i valori F e p sono leggermente diversi):

model3 <- lme(rt ~ group * direction, random=~1|subnum, data = ANT.2)
anova(model3)[-1,]
##                 numDF denDF   F-value p-value
## group               1    18 2.4334314  0.1362
## direction           1  5169 0.3937316  0.5304
## group:direction     1  5169 2.3298847  0.1270

Se inserisco un'interazione tra directione subnumil df per directione group:directionsono molto più piccolo (avrei pensato che sarebbero stati 18, ma forse sto sbagliando qualcosa):

model2 <- lmer(rt ~ group * direction + (direction | subnum), data = ANT.2)
lmerTest::anova(model2)
##                 Df  Sum Sq Mean Sq F value   Denom Pr(>F)
## group            1 20334.7 20334.7  2.4302  17.995 0.1364
## direction        1  1804.3  1804.3  0.3649 124.784 0.5469
## group:direction  1 10616.6 10616.6  2.1418 124.784 0.1459

Grazie @Ben Bolker per la tua risposta. Rifletterò sui tuoi commenti e farò qualche altro esperimento. Comprendo l' ezAnovaavvertimento in quanto non dovresti eseguire 2x2 anova se in realtà i tuoi dati provengono dal design 2x2x2.
Jiri Lukavsky,

1
Forse l'avvertimento che ne deriva ezpotrebbe essere riformulato; in realtà ha due parti che sono importanti: (1) che i dati vengono aggregati e (2) elementi sui progetti parziali. Il numero 1 è più pertinente alla discrepanza in quanto spiega che per eseguire un'anova tradizionale senza effetti misti, è necessario aggregare i dati in un'unica osservazione per cella del progetto. In questo caso, vogliamo un'osservazione per soggetto per livello della variabile "direction" (mantenendo le etichette di gruppo per i soggetti). ezANOVA lo calcola automaticamente.
Mike Lawrence,

+1 ma non sono sicuro che ezanova abbia sbagliato. Ho corso summary(aov(rt ~ group*direction + Error(subnum/direction), data=ANT.2))e dà 16 (?) Dfs per groupe 18 per directione group:direction. Il fatto che ci siano ~ 125 osservazioni per combinazione gruppo / direzione è praticamente irrilevante per RM-ANOVA, vedi ad esempio la mia domanda stats.stackexchange.com/questions/286280 : la direzione è testata, per così dire, contro il soggetto- interazione di direzione.
amoeba,

Ben, a seguito del mio precedente commento: in realtà è quello che intendevi con "Avrei pensato che avrebbero avuto 18 anni, ma forse sto sbagliando qualcosa"? In tal caso, siamo d'accordo. Ma ancora una volta, 18 è d'accordo con RM-ANOVA e non è d'accordo con lmerTestqueste stime ~ 125 dfs.
amoeba,

1
Aggiornamento a quanto sopra: lmerTest::anova(model2, ddf="Kenward-Roger")restituisce 18.000 df per groupe 17.987df per gli altri due fattori, che è in eccellente accordo con RM-ANOVA (come da ezAnova). La mia conclusione è che l'approssimazione di Satterthwaite fallisce model2per qualche motivo.
ameba,

10

Sono generalmente d'accordo con l'analisi di Ben, ma lasciatemi aggiungere un paio di osservazioni e un po 'di intuizione.

Innanzitutto, i risultati complessivi:

  1. I risultati dei test con il metodo Satterthwaite sono corretti
  2. Anche il metodo Kenward-Roger è corretto e concorda con Satterthwaite

Ben delinea il progetto in cui subnumè nidificato nel groupmentre direction e group:directionsono incrociata con subnum. Ciò significa che il termine di errore naturale (vale a dire il cosiddetto "strato di errore racchiuso") groupè subnummentre mentre lo strato di errore racchiuso negli altri termini (incluso subnum) sono i residui.

Questa struttura può essere rappresentata in un cosiddetto diagramma fattoriale:

names <- c(expression("[I]"[5169]^{5191}),
           expression("[subnum]"[18]^{20}), expression(grp:dir[1]^{4}),
           expression(dir[1]^{2}), expression(grp[1]^{2}), expression(0[1]^{1}))
x <- c(2, 4, 4, 6, 6, 8)
y <- c(5, 7, 5, 3, 7, 5)
plot(NA, NA, xlim=c(2, 8), ylim=c(2, 8), type="n", axes=F, xlab="", ylab="")
text(x, y, names) # Add text according to ’names’ vector
# Define coordinates for start (x0, y0) and end (x1, y1) of arrows:
x0 <- c(1.8, 1.8, 4.2, 4.2, 4.2, 6, 6) + .5
y0 <- c(5, 5, 7, 5, 5, 3, 7)
x1 <- c(2.7, 2.7, 5, 5, 5, 7.2, 7.2) + .5
y1 <- c(5, 7, 7, 3, 7, 5, 5)
arrows(x0, y0, x1, y1, length=0.1)

Diagramma della struttura del fattore

Qui i termini casuali sono racchiusi tra parentesi, 0rappresenta la media generale (o intercetta), [I]rappresenta il termine di errore, i numeri del super-script sono il numero di livelli e i numeri del sub-script sono il numero di gradi di libertà che assumono un disegno equilibrato. Il diagramma indica che il termine di errore naturale (che racchiude lo strato di errore) per groupè subnume che il numeratore df per subnum, che equivale al denominatore df per group, è 18: 20 meno 1 df per groupe 1 df per la media complessiva. Un'introduzione più completa ai diagrammi della struttura dei fattori è disponibile nel capitolo 2 qui: https://02429.compute.dtu.dk/eBook .

Se i dati fossero esattamente bilanciati saremmo in grado di costruire i test F da una decomposizione SSQ come fornito da anova.lm. Poiché il set di dati è molto bilanciato, possiamo ottenere test F approssimativi come segue:

ANT.2 <- subset(ANT, !error)
set.seed(101)
baseline.shift <- rnorm(length(unique(ANT.2$subnum)), 0, 50)
ANT.2$rt <- ANT.2$rt + baseline.shift[as.numeric(ANT.2$subnum)]
fm <- lm(rt ~ group * direction + subnum, data=ANT.2)
(an <- anova(fm))
Analysis of Variance Table

Response: rt
                  Df   Sum Sq Mean Sq  F value Pr(>F)    
group              1   994365  994365 200.5461 <2e-16 ***
direction          1     1568    1568   0.3163 0.5739    
subnum            18  7576606  420923  84.8927 <2e-16 ***
group:direction    1    11561   11561   2.3316 0.1268    
Residuals       5169 25629383    4958                    
---
Signif. codes:  0***0.001**0.01*0.05 ‘.’ 0.1 ‘ ’ 1

Qui vengono calcolati tutti i valori F e p supponendo che tutti i termini abbiano i residui come strato di errore che lo racchiude, e questo vale per tutti tranne che per "gruppo". Il test F 'corretto per il bilanciamento' per il gruppo è invece:

F_group <- an["group", "Mean Sq"] / an["subnum", "Mean Sq"]
c(Fvalue=F_group, pvalue=pf(F_group, 1, 18, lower.tail = FALSE))
   Fvalue    pvalue 
2.3623466 0.1416875 

dove usiamo la subnumMS invece della ResidualsMS nel denominatore del valore F.

Nota che questi valori corrispondono abbastanza bene ai risultati di Satterthwaite:

model <- lmer(rt ~ group * direction + (1 | subnum), data = ANT.2)
anova(model, type=1)
Type I Analysis of Variance Table with Satterthwaite's method
                 Sum Sq Mean Sq NumDF DenDF F value Pr(>F)
group           12065.3 12065.3     1    18  2.4334 0.1362
direction        1951.8  1951.8     1  5169  0.3936 0.5304
group:direction 11552.2 11552.2     1  5169  2.3299 0.1270

Le differenze rimanenti sono dovute al fatto che i dati non sono esattamente bilanciati.

Il PO si confronta anova.lmcon anova.lmerModLmerTest, il che è ok, ma per fare un paragone con un simile dobbiamo usare gli stessi contrasti. In questo caso c'è una differenza tra anova.lme anova.lmerModLmerTestpoiché producono rispettivamente test di Tipo I e III di default, e per questo set di dati c'è una (piccola) differenza tra i contrasti di Tipo I e III:

show_tests(anova(model, type=1))$group
               (Intercept) groupTreatment directionright groupTreatment:directionright
groupTreatment           0              1    0.005202759                     0.5013477

show_tests(anova(model, type=3))$group # type=3 is default
               (Intercept) groupTreatment directionright groupTreatment:directionright
groupTreatment           0              1              0                           0.5

Se il set di dati fosse stato completamente bilanciato, i contrasti di tipo I sarebbero stati gli stessi dei contrasti di tipo III (che non sono influenzati dal numero osservato di campioni).

Un'ultima osservazione è che la "lentezza" del metodo Kenward-Roger non è dovuta al rimodellamento del modello, ma perché comporta calcoli con la matrice di varianza-covarianza marginale delle osservazioni / residui (5191x5191 in questo caso) che non è il caso del metodo di Satterthwaite.

Per quanto riguarda il modello 2

Per quanto riguarda model2 la situazione diventa più complessa e penso che sia più facile iniziare la discussione con un altro modello in cui ho incluso l'interazione "classica" tra subnume direction:

model3 <- lmer(rt ~ group * direction + (1 | subnum) +
                 (1 | subnum:direction), data = ANT.2)
VarCorr(model3)
 Groups           Name        Std.Dev.  
 subnum:direction (Intercept) 1.7008e-06
 subnum           (Intercept) 4.0100e+01
 Residual                     7.0415e+01

Poiché la varianza associata all'interazione è essenzialmente zero (in presenza subnumdell'effetto principale casuale) il termine di interazione non ha alcun effetto sul calcolo dei gradi di libertà del denominatore, dei valori F e dei valori p :

anova(model3, type=1)
Type I Analysis of Variance Table with Satterthwaite's method
                 Sum Sq Mean Sq NumDF DenDF F value Pr(>F)
group           12065.3 12065.3     1    18  2.4334 0.1362
direction        1951.8  1951.8     1  5169  0.3936 0.5304
group:direction 11552.2 11552.2     1  5169  2.3299 0.1270

Tuttavia, subnum:directionè lo strato di errore che lo racchiude in subnumtal modo se rimuoviamo subnumtutto il SSQ associato ricade insubnum:direction

model4 <- lmer(rt ~ group * direction +
                 (1 | subnum:direction), data = ANT.2)

Ora il termine di errore naturale per group, directioned group:directionè subnum:directione con nlevels(with(ANT.2, subnum:direction))= 40 e quattro parametri, i gradi di libertà del denominatore per quei termini dovrebbero essere circa 36:

anova(model4, type=1)
Type I Analysis of Variance Table with Satterthwaite's method
                 Sum Sq Mean Sq NumDF  DenDF F value  Pr(>F)  
group           24004.5 24004.5     1 35.994  4.8325 0.03444 *
direction          50.6    50.6     1 35.994  0.0102 0.92020  
group:direction   273.4   273.4     1 35.994  0.0551 0.81583  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Questi test F possono anche essere approssimati con i test F 'bilanciati corretti' :

an4 <- anova(lm(rt ~ group*direction + subnum:direction, data=ANT.2))
an4[1:3, "F value"] <- an4[1:3, "Mean Sq"] / an4[4, "Mean Sq"]
an4[1:3, "Pr(>F)"] <- pf(an4[1:3, "F value"], 1, 36, lower.tail = FALSE)
an4
Analysis of Variance Table

Response: rt
                   Df   Sum Sq Mean Sq F value Pr(>F)    
group               1   994365  994365  4.6976 0.0369 *  
direction           1     1568    1568  0.0074 0.9319    
group:direction     1    10795   10795  0.0510 0.8226    
direction:subnum   36  7620271  211674 42.6137 <2e-16 ***
Residuals        5151 25586484    4967                   
---
Signif. codes:  0***0.001**0.01*0.05 ‘.’ 0.1 ‘ ’ 1

ora passiamo al modello2:

model2 <- lmer(rt ~ group * direction + (direction | subnum), data = ANT.2)

Questo modello descrive una struttura di covarianza ad effetto casuale piuttosto complicata con una matrice di covarianza varianza 2x2. La parametrizzazione predefinita non è facile da gestire e siamo meglio con una ri-parametrizzazione del modello:

model2 <- lmer(rt ~ group * direction + (0 + direction | subnum), data = ANT.2)

Se confrontiamo model2con model4, hanno ugualmente molti effetti casuali; 2 per ciascuno subnum, ovvero 2 * 20 = 40 in totale. Mentre model4stabilisce un singolo parametro di varianza per tutti i 40 effetti casuali, model2stabilisce che ogni subnumcoppia di effetti casuali ha una distribuzione normale bi-variabile con una matrice di varianza-covarianza 2x2 i cui parametri sono dati da

VarCorr(model2)
 Groups   Name           Std.Dev. Corr 
 subnum   directionleft  38.880        
          directionright 41.324   1.000
 Residual                70.405        

Ciò indica un eccesso di adattamento, ma conserviamolo per un altro giorno. Il punto importante qui è che model4è un caso speciale di model2 e che modelè anche un caso speciale di model2. Parlare liberamente (e intuitivamente) (direction | subnum)contiene o cattura la variazione associata all'effetto principale subnum e l'interazione direction:subnum. In termini di effetti casuali possiamo pensare a questi due effetti o strutture come a catturare rispettivamente la variazione tra righe e righe per colonne:

head(ranef(model2)$subnum)
  directionleft directionright
1    -25.453576     -27.053697
2     16.446105      17.479977
3    -47.828568     -50.835277
4     -1.980433      -2.104932
5      5.647213       6.002221
6     41.493591      44.102056

In questo caso, queste stime di effetti casuali e le stime dei parametri di varianza indicano entrambe che in realtà abbiamo solo un effetto principale casuale subnum(variazione tra le righe) presente qui. Ciò che porta a tutto ciò è il grado di libertà di quel denominatore Satterthwaite

anova(model2, type=1)
Type I Analysis of Variance Table with Satterthwaite's method
                 Sum Sq Mean Sq NumDF   DenDF F value Pr(>F)
group           12059.8 12059.8     1  17.998  2.4329 0.1362
direction        1803.6  1803.6     1 125.135  0.3638 0.5475
group:direction 10616.6 10616.6     1 125.136  2.1418 0.1458

è un compromesso tra queste strutture di effetto principale e di interazione: il gruppo DenDF rimane a 18 (nidificato in subnumbase alla progettazione) ma il directione group:directionDenDF sono compromessi tra 36 ( model4) e 5169 ( model).

Non credo che nulla indichi che l'approssimazione di Satterthwaite (o la sua implementazione in lmerTest ) sia difettosa.

Dà la tabella equivalente con il metodo Kenward-Roger

anova(model2, type=1, ddf="Ken")
Type I Analysis of Variance Table with Kenward-Roger's method
                 Sum Sq Mean Sq NumDF  DenDF F value Pr(>F)
group           12059.8 12059.8     1 18.000  2.4329 0.1362
direction        1803.2  1803.2     1 17.987  0.3638 0.5539
group:direction 10614.7 10614.7     1 17.987  2.1414 0.1606

Non sorprende che KR e Satterthwaite possano differire, ma per tutti gli scopi pratici la differenza nei valori p è minima. La mia analisi sopra indica che il DenDFfor directione group:directionnon dovrebbe essere più piccolo di ~ 36 e probabilmente più grande di quello dato che in pratica abbiamo solo l'effetto principale casuale del directionpresente, quindi se penso che ciò sia un'indicazione che il metodo KR diventa DenDFtroppo basso in questo caso. Ma tieni presente che i dati non supportano realmente la (group | direction)struttura, quindi il confronto è un po 'artificiale - sarebbe più interessante se il modello fosse effettivamente supportato.


+6, grazie, molto interessante! Un paio di domande. (1) Dove posso leggere di più su "racchiudere lo strato di errore"? Ho cercato su Google questo termine e questa risposta è stata l' unica hit. Più in generale, quale letteratura consiglieresti di conoscere questi problemi? (2a) Per quanto ho capito, RM-ANOVA classica per questo disegno corrisponde alla tua model3. Tuttavia, utilizza subnum:directioncome termine di errore per il test direction. Mentre qui puoi forzare che ciò accada solo escludendo (1|subnum)come in model4. Perché? (2b) Inoltre, RM-ANOVA produce df = 18 per direction, non 36 quando entri model4. Perché?
ameba,

Per i miei punti (2a + 2b), vedere summary(aov(rt ~ group*direction + Error(subnum/direction), data=ANT.2)).
ameba,

1
(1) L'argomento degli strati di errore e quali termini sono racchiusi in quali strati sono derivati ​​dalle espressioni del quadrato medio previsto per un determinato modello / disegno. Questo è il materiale "standard" di progettazione di esperimenti (DoE) sebbene questi argomenti più tecnici siano spesso lasciati cadere in varianti semplici ("applicate") di tali corsi. Vedi ad esempio ch 11 e 12 in users.stat.umn.edu/~gary/book/fcdae.pdf per un'introduzione. Ho imparato l'argomento dal testo equivalente di DC Montgomery e gli ampi materiali extra dal (recentemente e purtroppo) defunto professor Henrik Spliid.
Rune H Christensen,

1
... Per un trattamento più approfondito Variance Components (1992 e 2006) di Searle et al è un classico.
Rune H Christensen,

Ah, sì, avrei dovuto vederlo: se abbiamo un modello in cui entrambi subnume subnum:directionsono diversi da zero, allora diamo anova(lm(rt2 ~ group * direction + subnum + subnum:direction, data = ANT.2)) 18 df per tutti e tre i fattori e questo è ciò che il metodo KR rileva. Questo si può vedere già con il punto in model3cui KR fornisce il 18 df basato sul design per tutti i termini anche quando la varianza di interazione è zero mentre Satterthwaite riconosce il termine di varianza evanescente e regola di conseguenza il df ....
Rune H Christensen
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.