Equivalência entre um modelo anova de medidas repetidas e um modelo misto: lmer vs lme e simetria composta

9

Estou com problemas para obter resultados equivalentes entre um aovmodelo de medidas repetidas entre dentro e um lmermodelo misto.

Meus dados e script têm a seguinte aparência

data=read.csv("https://www.dropbox.com/s/zgle45tpyv5t781/fitness.csv?dl=1")
data$id=factor(data$id)
data
   id  FITNESS      TEST PULSE
1   1  pilates   CYCLING    91
2   2  pilates   CYCLING    82
3   3  pilates   CYCLING    65
4   4  pilates   CYCLING    90
5   5  pilates   CYCLING    79
6   6  pilates   CYCLING    84
7   7 aerobics   CYCLING    84
8   8 aerobics   CYCLING    77
9   9 aerobics   CYCLING    71
10 10 aerobics   CYCLING    91
11 11 aerobics   CYCLING    72
12 12 aerobics   CYCLING    93
13 13    zumba   CYCLING    63
14 14    zumba   CYCLING    87
15 15    zumba   CYCLING    67
16 16    zumba   CYCLING    98
17 17    zumba   CYCLING    63
18 18    zumba   CYCLING    72
19  1  pilates   JOGGING   136
20  2  pilates   JOGGING   119
21  3  pilates   JOGGING   126
22  4  pilates   JOGGING   108
23  5  pilates   JOGGING   122
24  6  pilates   JOGGING   101
25  7 aerobics   JOGGING   116
26  8 aerobics   JOGGING   142
27  9 aerobics   JOGGING   137
28 10 aerobics   JOGGING   134
29 11 aerobics   JOGGING   131
30 12 aerobics   JOGGING   120
31 13    zumba   JOGGING    99
32 14    zumba   JOGGING    99
33 15    zumba   JOGGING    98
34 16    zumba   JOGGING    99
35 17    zumba   JOGGING    87
36 18    zumba   JOGGING    89
37  1  pilates SPRINTING   179
38  2  pilates SPRINTING   195
39  3  pilates SPRINTING   188
40  4  pilates SPRINTING   189
41  5  pilates SPRINTING   173
42  6  pilates SPRINTING   193
43  7 aerobics SPRINTING   184
44  8 aerobics SPRINTING   179
45  9 aerobics SPRINTING   179
46 10 aerobics SPRINTING   174
47 11 aerobics SPRINTING   164
48 12 aerobics SPRINTING   182
49 13    zumba SPRINTING   111
50 14    zumba SPRINTING   103
51 15    zumba SPRINTING   113
52 16    zumba SPRINTING   118
53 17    zumba SPRINTING   127
54 18    zumba SPRINTING   113

Basicamente, 3 x 6 indivíduos ( id) foram submetidos a três FITNESSesquemas de treino diferentes cada um e o seu PULSEfoi medido após a realização de três tipos diferentes de resistência TEST.

Eu então ajustei o seguinte aovmodelo:

library(afex)
library(car)
set_sum_contrasts()
fit1 = aov(PULSE ~ FITNESS*TEST + Error(id/TEST),data=data)
summary(fit1)
Error: id
          Df Sum Sq Mean Sq F value   Pr(>F)    
FITNESS    2  14194    7097   115.1 7.92e-10 ***
Residuals 15    925      62                     
---
Signif. codes:  0***0.001**0.01*0.05 ‘.’ 0.1 ‘ ’ 1

Error: id:TEST
             Df Sum Sq Mean Sq F value   Pr(>F)    
TEST          2  57459   28729   253.7  < 2e-16 ***
FITNESS:TEST  4   8200    2050    18.1 1.16e-07 ***
Residuals    30   3397     113                     
---
Signif. codes:  0***0.001**0.01*0.05 ‘.’ 0.1 ‘ ’ 1

O resultado que eu obtenho usando

set_sum_contrasts()
fit2=aov.car(PULSE ~ FITNESS*TEST+Error(id/TEST),data=data,type=3,return="Anova")
summary(fit2)

é idêntico a isso.

Uma execução de modelo misto usando nlmefornece um resultado diretamente equivalente, por exemplo, usando lme:

library(lmerTest)    
lme1=lme(PULSE ~ FITNESS*TEST, random=~1|id, correlation=corCompSymm(form=~1|id),data=data)
anova(lme1)
             numDF denDF   F-value p-value
(Intercept)      1    30 12136.126  <.0001
FITNESS          2    15   115.127  <.0001
TEST             2    30   253.694  <.0001
FITNESS:TEST     4    30    18.103  <.0001


summary(lme1)
Linear mixed-effects model fit by REML
 Data: data 
       AIC      BIC    logLik
  371.5375 393.2175 -173.7688

Random effects:
 Formula: ~1 | id
        (Intercept) Residual
StdDev:    1.699959 9.651662

Correlation Structure: Compound symmetry
 Formula: ~1 | id 
 Parameter estimate(s):
       Rho 
-0.2156615 
Fixed effects: PULSE ~ FITNESS * TEST 
                                 Value Std.Error DF   t-value p-value
(Intercept)                   81.33333  4.000926 30 20.328628  0.0000
FITNESSpilates                 0.50000  5.658164 15  0.088368  0.9308
FITNESSzumba                  -6.33333  5.658164 15 -1.119327  0.2806
TESTJOGGING                   48.66667  6.143952 30  7.921069  0.0000
TESTSPRINTING                 95.66667  6.143952 30 15.570868  0.0000
FITNESSpilates:TESTJOGGING   -11.83333  8.688861 30 -1.361897  0.1834
FITNESSzumba:TESTJOGGING     -28.50000  8.688861 30 -3.280062  0.0026
FITNESSpilates:TESTSPRINTING   8.66667  8.688861 30  0.997446  0.3265
FITNESSzumba:TESTSPRINTING   -56.50000  8.688861 30 -6.502579  0.0000

Ou usando gls:

library(lmerTest)    
gls1=gls(PULSE ~ FITNESS*TEST, correlation=corCompSymm(form=~1|id),data=data)
anova(gls1)

No entanto, o resultado que eu obtenho usando lme4's lmeré diferente:

set_sum_contrasts()
fit3=lmer(PULSE ~ FITNESS*TEST+(1|id),data=data)
summary(fit3)
Linear mixed model fit by REML ['lmerMod']
Formula: PULSE ~ FITNESS * TEST + (1 | id)
   Data: data

REML criterion at convergence: 362.4

Random effects:
 Groups   Name        Variance Std.Dev.
 id       (Intercept)  0.00    0.0     
 Residual             96.04    9.8     
...

Anova(fit3,test.statistic="F",type=3)
Analysis of Deviance Table (Type III Wald F tests with Kenward-Roger df)

Response: PULSE
                    F Df Df.res    Pr(>F)    
(Intercept)  7789.360  1     15 < 2.2e-16 ***
FITNESS        73.892  2     15 1.712e-08 ***
TEST          299.127  2     30 < 2.2e-16 ***
FITNESS:TEST   21.345  4     30 2.030e-08 ***
---
Signif. codes:  0***0.001**0.01*0.05 ‘.’ 0.1 ‘ ’ 1

Alguém tem alguma idéia do que estou fazendo de errado com o lmermodelo? Ou de onde vem a diferença? Poderia ter algo a ver com lmernão permitir corelações intraclasse negativas ou algo assim? Dado que nlmeé glse lmeretornamos o resultado correto, porém, eu estou querendo saber como isso é diferente glse lme. Será que a opção os correlation=corCompSymm(form=~1|id)leva a estimar diretamente a correlação intraclasse, que pode ser positiva ou negativa, enquanto lmerestima um componente de variação, que não pode ser negativo (e acaba sendo estimado como zero neste caso)?

Tom Wenseleers
fonte
O que set_sum_contrasts()faz?
smillig
Ha é de AFEX biblioteca - ele define codificação usando opções (contrastes = c ( "contr.sum", "contr.poly")) efeito
Tom Wenseleers
1
A hipótese em sua última frase está exatamente correta.
precisa
Ha muito obrigado por isso! Lembro que você mencionou uma vez que havia uma versão de desenvolvimento de ponta do lme4 'flexLambda' disponível no github que permitiria estruturas de correlação do tipo corCompSymm. Ainda é esse o caso, e essa versão seria capaz de retornar o resultado lme por acaso?
21430 Tom Wenseleers #

Respostas:

14

Como Ben Bolker já mencionou nos comentários, o problema é como você suspeita: O lmer()modelo é disparado porque tenta estimar um modelo de componente de variação, com as estimativas do componente de variação restritas a não-negativas. O que tentarei fazer é fornecer uma compreensão um tanto intuitiva do que o seu conjunto de dados leva a isso e por que isso causa um problema nos modelos de componentes de variação.

Aqui está um gráfico do seu conjunto de dados. Os pontos brancos são as observações reais e os pontos pretos são o meio de assunto.

insira a descrição da imagem aqui

Para tornar as coisas mais simples, mas sem alterar o espírito do problema, subtraindo os efeitos fixos (isto é, os efeitos FITNESSe TEST, assim como a média geral) e lidando com os dados residuais como um problema de efeitos aleatórios unidirecionais . Então, aqui está a aparência do novo conjunto de dados:

insira a descrição da imagem aqui

Observe atentamente os padrões neste gráfico. Pense em como as observações tiradas do mesmo assunto diferem das observações tiradas de diferentes sujeitos. Observe especificamente o seguinte padrão: Como uma das observações de um assunto é mais alta (ou mais baixa) acima (ou abaixo) da média do sujeito, as outras observações desse sujeito tendem a estar no lado oposto da média do sujeito. E quanto mais a observação é da média do sujeito, mais as outras observações tendem a ser da média do sujeito no lado oposto. Isso indica uma correlação intra-classe negativa. Duas observações tiradas do mesmo assunto tendem a ser menos semelhantes, em média, do que duas observações extraídas aleatoriamente do conjunto de dados.

Outra maneira de pensar sobre esse padrão é em termos das magnitudes relativas da variação entre sujeitos e dentro dos sujeitos. Parece que há uma variação dentro do sujeito substancialmente maior em comparação com a variação entre sujeitos. Obviamente, esperamos que isso ocorra até certo ponto. Afinal, a variação entre sujeitos é baseada na variação nos pontos de dados individuais, enquanto a variação entre sujeitos é baseada na variação nas médias dos pontos de dados individuais (isto é, o sujeito significa), e sabemos que a variação de uma média tenderá a diminuir à medida que o número de coisas em média aumenta. Mas neste conjunto de dados, a diferença é bastante surpreendente: Há caminhomais variação dentro do sujeito do que entre sujeitos. Na verdade, essa diferença é exatamente a razão pela qual surge uma correlação intra-classe negativa.

yij=uj+eijujjassunto. Então, vamos pensar no que aconteceria se houvesse realmente 0 variação nos efeitos do sujeito - em outras palavras, se o verdadeiro componente de variação entre sujeitos fosse 0. Dado um conjunto de dados real gerado sob esse modelo, se calcularmos as médias amostrais para os dados observados de cada sujeito, essas médias amostrais ainda teriam alguma variação diferente de zero, mas refletiriam apenas uma variação de erro, e não uma variação de assunto "verdadeira" (porque assumimos que não há nenhuma).

var(X¯)=var(Xi)/nn

34810.84.3. E aí está o problema. Os dados sugerem que de alguma forma existe um componente de variação negativa, mas o software (sensatamente) não permitirá estimativas negativas dos componentes de variação, uma vez que uma variação nunca pode ser negativa. Os outros modelos que você ajusta evitam esse problema estimando diretamente a correlação intra-classe em vez de assumir um modelo de componente de variação simples.

Se você quiser ver como realmente pode obter a estimativa do componente de variação negativa implícita no seu conjunto de dados, use o procedimento que ilustro (com o Rcódigo que acompanha ) nesta outra resposta recente . Esse procedimento não é totalmente trivial, mas também não é muito difícil (para um design equilibrado como este).

Jake Westfall
fonte
Olá Jake, muito obrigado por esta explicação muito clara! Mas estou bem, se eu usar o modelo lme com simetria composta (ou uma estrutura geral de correlação), certo? E o Rho nesse modelo lme, -0,2156615, seria a correlação intraclasse negativa, certo?
Tom Wenseleers
@TomWenseleers Yep (para ambos)
Jake Westfall
1
+1. É uma excelente resposta pedagógica e é uma pena que tenha tão poucos votos positivos.
Ameba