Пряма відповідь на ваше запитання полягає в тому, що остання модель, яку ви написали,
anova(lmer(y ~ a*b*c +(1|subject) + (1|a:subject) + (1|b:subject) + (1|c:subject) +
(1|a:b:subject) + (1|a:c:subject) + (1|b:c:subject), d))
Я вважаю, що "в принципі" правильно, хоча це дивна параметризація, яка не завжди, здається, працює добре в реальній практиці.
Щодо того, чому вихід, який ви отримуєте від цієї моделі, не відрізняється від aov()
результату, я думаю, що це дві причини.
- Ваш простий модельований набір даних є патологічним тим, що найкраще підійде модель, яка передбачає компоненти негативної дисперсії, до яких змішані моделі, що відповідають
lmer()
(і більшість інших змішаних модельних програм), не дозволять.
- Навіть з непатологічним набором даних, як ви створили модель, як було сказано вище, не завжди здається, що на практиці працює добре, хоча, маю визнати, я не дуже розумію, чому. На мій погляд, це також просто взагалі дивно, але це вже інша історія.
Дозвольте спочатку продемонструвати параметризацію, яку я віддаю перевагу на вашому початковому двосторонньому прикладі ANOVA. Припустимо, що ваш набір даних d
завантажений. Ваша модель (зауважте, що я змінила з "манекена" на контрастні коди):
options(contrasts=c("contr.sum","contr.poly"))
mod1 <- lmer(y ~ a*b+(1|subject) + (1|a:subject) + (1|b:subject),
data = d[d$c == "1",])
anova(mod1)
# Analysis of Variance Table
# Df Sum Sq Mean Sq F value
# a 1 2.20496 2.20496 3.9592
# b 1 0.13979 0.13979 0.2510
# a:b 1 1.23501 1.23501 2.2176
яка тут добре працювала, оскільки вона відповідала aov()
виходу. Модель, яку я віддаю перевагу, включає дві зміни: контрастне кодування факторів вручну, щоб ми не працювали з об'єктами фактора R (що я рекомендую робити у 100% випадків), а також визначати випадкові ефекти по-різному:
d <- within(d, {
A <- 2*as.numeric(paste(a)) - 3
B <- 2*as.numeric(paste(b)) - 3
C <- 2*as.numeric(paste(c)) - 3
})
mod2 <- lmer(y ~ A*B + (1|subject)+(0+A|subject)+(0+B|subject),
data = d[d$c == "1",])
anova(mod2)
# Analysis of Variance Table
# Df Sum Sq Mean Sq F value
# A 1 2.20496 2.20496 3.9592
# B 1 0.13979 0.13979 0.2510
# A:B 1 1.23501 1.23501 2.2176
logLik(mod1)
# 'log Lik.' -63.53034 (df=8)
logLik(mod2)
# 'log Lik.' -63.53034 (df=8)
Два підходи цілком рівноцінні в простій двосторонній задачі. Тепер ми перейдемо до трибічної проблеми. Раніше я згадував, що наведений вами приклад даних є патологічним. Тож, що я хочу зробити перед тим, як звернутися до вашого набору даних прикладу, - це спершу генерувати набір даних із фактичної моделі компонентів дисперсії (тобто, де ненульові компоненти дисперсії вбудовані в справжню модель). Спочатку я покажу, як здається, що моя бажана параметризація працює краще, ніж запропонована вами. Тоді я продемонструю інший спосіб оцінки компонентів дисперсії, який не нав'язує, що вони повинні бути негативними. Тоді ми зможемо побачити проблему з оригінальним набором даних.
Новий набір даних буде ідентичним за структурою, за винятком того, що у нас буде 50 предметів:
set.seed(9852903)
d2 <- expand.grid(A=c(-1,1), B=c(-1,1), C=c(-1,1), sub=seq(50))
d2 <- merge(d2, data.frame(sub=seq(50), int=rnorm(50), Ab=rnorm(50),
Bb=rnorm(50), Cb=rnorm(50), ABb=rnorm(50), ACb=rnorm(50), BCb=rnorm(50)))
d2 <- within(d2, {
y <- int + (1+Ab)*A + (1+Bb)*B + (1+Cb)*C + (1+ABb)*A*B +
(1+ACb)*A*C + (1+BCb)*B*C + A*B*C + rnorm(50*2^3)
a <- factor(A)
b <- factor(B)
c <- factor(C)
})
F-коефіцієнти, з якими ми хочемо відповідати:
aovMod1 <- aov(y ~ a*b*c + Error(factor(sub)/(a*b*c)), data = d2)
tab <- lapply(summary(aovMod1), function(x) x[[1]][1,2:4])
do.call(rbind, tab)
# Sum Sq Mean Sq F value
# Error: factor(sub) 439.48 8.97
# Error: factor(sub):a 429.64 429.64 32.975
# Error: factor(sub):b 329.48 329.48 27.653
# Error: factor(sub):c 165.44 165.44 17.924
# Error: factor(sub):a:b 491.33 491.33 49.694
# Error: factor(sub):a:c 305.46 305.46 41.703
# Error: factor(sub):b:c 466.09 466.09 40.655
# Error: factor(sub):a:b:c 392.76 392.76 448.101
Ось наші дві моделі:
mod3 <- lmer(y ~ a*b*c + (1|sub)+(1|a:sub)+(1|b:sub)+(1|c:sub)+
(1|a:b:sub)+(1|a:c:sub)+(1|b:c:sub), data = d2)
anova(mod3)
# Analysis of Variance Table
# Df Sum Sq Mean Sq F value
# a 1 32.73 32.73 34.278
# b 1 21.68 21.68 22.704
# c 1 12.53 12.53 13.128
# a:b 1 60.93 60.93 63.814
# a:c 1 50.38 50.38 52.762
# b:c 1 57.30 57.30 60.009
# a:b:c 1 392.76 392.76 411.365
mod4 <- lmer(y ~ A*B*C + (1|sub)+(0+A|sub)+(0+B|sub)+(0+C|sub)+
(0+A:B|sub)+(0+A:C|sub)+(0+B:C|sub), data = d2)
anova(mod4)
# Analysis of Variance Table
# Df Sum Sq Mean Sq F value
# A 1 28.90 28.90 32.975
# B 1 24.24 24.24 27.653
# C 1 15.71 15.71 17.924
# A:B 1 43.56 43.56 49.694
# A:C 1 36.55 36.55 41.703
# B:C 1 35.63 35.63 40.655
# A:B:C 1 392.76 392.76 448.101
logLik(mod3)
# 'log Lik.' -984.4531 (df=16)
logLik(mod4)
# 'log Lik.' -973.4428 (df=16)
Як ми бачимо, лише другий метод відповідає результату з aov()
, хоча перший метод є принаймні у бальній смузі. Другий метод також досягає більшої ймовірності журналу. Я не впевнений, чому ці два методи дають різні результати, оскільки я знову думаю, що вони "в принципі" еквівалентні, але, можливо, це є з якихось числових / обчислювальних причин. А може, я помиляюся, і вони не є рівнозначними навіть в принципі.
Зараз я покажу ще один спосіб оцінки компонентів дисперсії на основі традиційних ідей ANOVA. В основному ми візьмемо очікувані середні квадратні рівняння для вашої конструкції, замінимо спостережувані значення середніх квадратів та вирішимо для дисперсійних компонентів. Для того, щоб отримати очікувані середні квадрати ми будемо використовувати функцію R , яку я написав кілька років тому, називається EMS()
, яка документована ТУТ . Нижче я припускаю, що функція вже завантажена.
# prepare coefficient matrix
r <- 1 # number of replicates
s <- 50 # number of subjects
a <- 2 # number of levels of A
b <- 2 # number of levels of B
c <- 2 # number of levels of C
CT <- EMS(r ~ a*b*c*s, random="s")
expr <- strsplit(CT[CT != ""], split="")
expr <- unlist(lapply(expr, paste, collapse="*"))
expr <- sapply(expr, function(x) eval(parse(text=x)))
CT[CT != ""] <- expr
CT[CT == ""] <- 0
mode(CT) <- "numeric"
# residual variance and A*B*C*S variance are confounded in
# this design, so remove the A*B*C*S variance component
CT <- CT[-15,-2]
CT
# VarianceComponent
# Effect e b:c:s a:c:s a:b:s a:b:c c:s b:s a:s b:c a:c a:b s c b a
# a 1 0 0 0 0 0 0 4 0 0 0 0 0 0 200
# b 1 0 0 0 0 0 4 0 0 0 0 0 0 200 0
# c 1 0 0 0 0 4 0 0 0 0 0 0 200 0 0
# s 1 0 0 0 0 0 0 0 0 0 0 8 0 0 0
# a:b 1 0 0 2 0 0 0 0 0 0 100 0 0 0 0
# a:c 1 0 2 0 0 0 0 0 0 100 0 0 0 0 0
# b:c 1 2 0 0 0 0 0 0 100 0 0 0 0 0 0
# a:s 1 0 0 0 0 0 0 4 0 0 0 0 0 0 0
# b:s 1 0 0 0 0 0 4 0 0 0 0 0 0 0 0
# c:s 1 0 0 0 0 4 0 0 0 0 0 0 0 0 0
# a:b:c 1 0 0 0 50 0 0 0 0 0 0 0 0 0 0
# a:b:s 1 0 0 2 0 0 0 0 0 0 0 0 0 0 0
# a:c:s 1 0 2 0 0 0 0 0 0 0 0 0 0 0 0
# b:c:s 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0
# e 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
# get mean squares
(MSmod <- summary(aov(y ~ a*b*c*factor(sub), data=d2)))
# Df Sum Sq Mean Sq
# a 1 429.6 429.6
# b 1 329.5 329.5
# c 1 165.4 165.4
# factor(sub) 49 439.5 9.0
# a:b 1 491.3 491.3
# a:c 1 305.5 305.5
# b:c 1 466.1 466.1
# a:factor(sub) 49 638.4 13.0
# b:factor(sub) 49 583.8 11.9
# c:factor(sub) 49 452.2 9.2
# a:b:c 1 392.8 392.8
# a:b:factor(sub) 49 484.5 9.9
# a:c:factor(sub) 49 358.9 7.3
# b:c:factor(sub) 49 561.8 11.5
# a:b:c:factor(sub) 49 42.9 0.9
MS <- MSmod[[1]][,"Mean Sq"]
# solve
ans <- solve(CT, MS)
cbind(rev(ans[c(grep("e",names(ans)),grep("s",names(ans)))])/
c(1,2,2,2,4,4,4,1))
# s 1.0115549
# a:s 1.5191114
# b:s 1.3797937
# c:s 1.0441351
# a:b:s 1.1263331
# a:c:s 0.8060402
# b:c:s 1.3235126
# e 0.8765093
summary(mod4)
# Random effects:
# Groups Name Variance Std.Dev.
# sub (Intercept) 1.0116 1.0058
# sub.1 A 1.5191 1.2325
# sub.2 B 1.3798 1.1746
# sub.3 C 1.0441 1.0218
# sub.4 A:B 1.1263 1.0613
# sub.5 A:C 0.8060 0.8978
# sub.6 B:C 1.3235 1.1504
# Residual 0.8765 0.9362
# Number of obs: 400, groups: sub, 50
Гаразд, зараз ми повернемося до початкового прикладу. Коефіцієнти F, які ми намагаємося відповідати:
aovMod2 <- aov(y~a*b*c+Error(subject/(a*b*c)), data = d)
tab <- lapply(summary(aovMod2), function(x) x[[1]][1,2:4])
do.call(rbind, tab)
# Sum Sq Mean Sq F value
# Error: subject 13.4747 1.2250
# Error: subject:a 1.4085 1.4085 1.2218
# Error: subject:b 3.1180 3.1180 5.5487
# Error: subject:c 6.3809 6.3809 5.2430
# Error: subject:a:b 1.5706 1.5706 2.6638
# Error: subject:a:c 1.0907 1.0907 1.5687
# Error: subject:b:c 1.4128 1.4128 2.3504
# Error: subject:a:b:c 0.1014 0.1014 0.1149
Ось наші дві моделі:
mod5 <- lmer(y ~ a*b*c + (1|subject)+(1|a:subject)+(1|b:subject)+
(1|c:subject)+(1|a:b:subject)+(1|a:c:subject)+(1|b:c:subject),
data = d)
anova(mod5)
# Analysis of Variance Table
# Df Sum Sq Mean Sq F value
# a 1 0.8830 0.8830 1.3405
# b 1 3.1180 3.1180 4.7334
# c 1 3.8062 3.8062 5.7781
# a:b 1 1.5706 1.5706 2.3844
# a:c 1 0.9620 0.9620 1.4604
# b:c 1 1.4128 1.4128 2.1447
# a:b:c 1 0.1014 0.1014 0.1539
mod6 <- lmer(y ~ A*B*C + (1|subject)+(0+A|subject)+(0+B|subject)+
(0+C|subject)+(0+A:B|subject)+(0+A:C|subject)+
(0+B:C|subject), data = d)
anova(mod6)
# Analysis of Variance Table
# Df Sum Sq Mean Sq F value
# a 1 0.8830 0.8830 1.3405
# b 1 3.1180 3.1180 4.7334
# c 1 3.8062 3.8062 5.7781
# a:b 1 1.5706 1.5706 2.3844
# a:c 1 0.9620 0.9620 1.4604
# b:c 1 1.4128 1.4128 2.1447
# a:b:c 1 0.1014 0.1014 0.1539
logLik(mod5)
# 'log Lik.' -135.0351 (df=16)
logLik(mod6)
# 'log Lik.' -134.9191 (df=16)
У цьому випадку дві моделі дають в основному однакові результати, хоча другий метод має дуже високу ймовірність журналу. Жоден метод не відповідає aov()
. Але давайте подивимося, що ми отримуємо, коли ми вирішуємо компоненти дисперсії, як це було зроблено вище, використовуючи процедуру ANOVA, яка не обмежує компоненти дисперсії негативними (але яка може бути використана лише у врівноважених конструкціях без суцільних прогнозів і без відсутні дані; класичні припущення ANOVA).
# prepare coefficient matrix
r <- 1 # number of replicates
s <- 12 # number of subjects
a <- 2 # number of levels of A
b <- 2 # number of levels of B
c <- 2 # number of levels of C
CT <- EMS(r ~ a*b*c*s, random="s")
expr <- strsplit(CT[CT != ""], split="")
expr <- unlist(lapply(expr, paste, collapse="*"))
expr <- sapply(expr, function(x) eval(parse(text=x)))
CT[CT != ""] <- expr
CT[CT == ""] <- 0
mode(CT) <- "numeric"
# residual variance and A*B*C*S variance are confounded in
# this design, so remove the A*B*C*S variance component
CT <- CT[-15,-2]
# get mean squares
MSmod <- summary(aov(y ~ a*b*c*subject, data=d))
MS <- MSmod[[1]][,"Mean Sq"]
# solve
ans <- solve(CT, MS)
cbind(rev(ans[c(grep("e",names(ans)),grep("s",names(ans)))])/
c(1,2,2,2,4,4,4,1))
# s 0.04284033
# a:s 0.03381648
# b:s -0.04004005
# c:s 0.04184887
# a:b:s -0.03657940
# a:c:s -0.02337501
# b:c:s -0.03514457
# e 0.88224787
summary(mod6)
# Random effects:
# Groups Name Variance Std.Dev.
# subject (Intercept) 7.078e-02 2.660e-01
# subject.1 A 6.176e-02 2.485e-01
# subject.2 B 0.000e+00 0.000e+00
# subject.3 C 6.979e-02 2.642e-01
# subject.4 A:B 1.549e-16 1.245e-08
# subject.5 A:C 4.566e-03 6.757e-02
# subject.6 B:C 0.000e+00 0.000e+00
# Residual 6.587e-01 8.116e-01
# Number of obs: 96, groups: subject, 12
Тепер ми можемо побачити, що є патологічним щодо оригінального прикладу. Найкраще підійде модель, яка передбачає, що декілька випадкових дисперсійних компонентів є негативними. Але lmer()
(і більшість інших змішаних модельних програм) обмежує оцінки компонентів дисперсії негативними. Це, як правило, вважається розумним обмеженням, оскільки розбіжності, звичайно, ніколи не можуть бути негативними. Однак наслідком цього обмеження є те, що змішані моделі не в змозі точно представити набори даних, які містять негативні внутрішньокласові кореляції, тобто набори даних, де спостереження з одного кластеру менше(а не більше) аналогічно в середньому, ніж спостереження, проведені випадковим чином з набору даних, і, отже, коли дисперсія в кластері значно перевищує дисперсію між кластером. Такі набори даних є цілком розумними наборами даних, які іноді трапляються в реальному світі (або випадково імітують!), Але їх неможливо охарактеризувати моделлю дисперсійних компонентів, оскільки вони передбачають негативні компоненти дисперсії. Однак вони можуть бути "нерозумно" описані такими моделями, якщо програмне забезпечення це дозволить. aov()
дозволяє це. lmer()
не.
y ~ a*b + (1 + a*b|subject), d[d$c == "1",]
? А може, мені чогось не вистачає?