Estou com problemas para obter resultados equivalentes entre um aov
modelo de medidas repetidas entre dentro e um lmer
modelo 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 FITNESS
esquemas de treino diferentes cada um e o seu PULSE
foi medido após a realização de três tipos diferentes de resistência TEST
.
Eu então ajustei o seguinte aov
modelo:
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 nlme
fornece 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 lmer
modelo? Ou de onde vem a diferença? Poderia ter algo a ver com lmer
não permitir corelações intraclasse negativas ou algo assim? Dado que nlme
é gls
e lme
retornamos o resultado correto, porém, eu estou querendo saber como isso é diferente gls
e 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 lmer
estima um componente de variação, que não pode ser negativo (e acaba sendo estimado como zero neste caso)?
fonte
set_sum_contrasts()
faz?Respostas:
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.
Para tornar as coisas mais simples, mas sem alterar o espírito do problema, subtraindo os efeitos fixos (isto é, os efeitos
FITNESS
eTEST
, 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: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.
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
R
có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).fonte