Jawaban langsung untuk pertanyaan Anda adalah bahwa model terakhir yang Anda tulis,
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))
Saya percaya "pada prinsipnya" benar, meskipun itu adalah parameterisasi aneh yang sepertinya tidak selalu berfungsi dengan baik dalam praktik yang sebenarnya.
Adapun mengapa output yang Anda dapatkan dari model ini berbeda dengan aov()
output, saya pikir ada dua alasan.
- Dataset simulasi sederhana Anda bersifat patologis karena model yang paling pas adalah yang menyiratkan komponen varians negatif, yang tidak dapat diterima oleh model campuran
lmer()
(dan sebagian besar program model campuran lainnya).
- Bahkan dengan dataset non-patologis, cara Anda mengatur model, seperti yang disebutkan di atas, tampaknya tidak selalu bekerja dengan baik dalam praktiknya, walaupun harus saya akui saya tidak begitu mengerti mengapa. Secara umum juga aneh menurut saya, tapi itu cerita lain.
Ijinkan saya mendemonstrasikan parameterisasi yang saya sukai pada contoh ANOVA dua arah awal Anda. Asumsikan bahwa dataset Anda d
dimuat. Model Anda (perhatikan bahwa saya mengubah dari dummy ke kode kontras) adalah:
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
yang bekerja dengan baik di sini karena cocok dengan aov()
output. Model yang saya sukai melibatkan dua perubahan: pengkodean kontras faktor secara manual sehingga kami tidak bekerja dengan objek faktor R (yang saya sarankan lakukan dalam 100% kasus), dan menetapkan efek acak berbeda:
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)
Kedua pendekatan ini benar-benar setara dalam masalah 2 arah yang sederhana. Sekarang kita akan beralih ke masalah 3 arah. Saya sebutkan sebelumnya bahwa contoh dataset yang Anda berikan bersifat patologis. Jadi apa yang ingin saya lakukan sebelum membahas contoh dataset Anda adalah pertama-tama menghasilkan dataset dari model komponen varians yang sebenarnya (yaitu, di mana komponen varians non-nol dibangun ke dalam model yang benar). Pertama saya akan menunjukkan bagaimana parameterisasi pilihan saya tampaknya berfungsi lebih baik daripada yang Anda usulkan. Kemudian saya akan menunjukkan cara lain untuk memperkirakan komponen varians yang tidak memaksakan bahwa mereka harus non-negatif. Kemudian kita akan berada dalam posisi untuk melihat masalah dengan dataset contoh asli.
Dataset baru akan identik dalam struktur kecuali kita akan memiliki 50 subjek:
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)
})
Rasio-F yang ingin kami cocokkan adalah:
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
Berikut adalah dua model kami:
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)
Seperti yang bisa kita lihat, hanya metode kedua yang cocok dengan keluaran aov()
, meskipun metode pertama setidaknya di stadion baseball. Metode kedua juga mencapai kemungkinan log yang lebih tinggi. Saya tidak yakin mengapa kedua metode ini memberikan hasil yang berbeda, karena sekali lagi saya pikir mereka setara "pada prinsipnya", tetapi mungkin karena beberapa alasan numerik / komputasi. Atau mungkin saya salah dan mereka pada prinsipnya tidak setara.
Sekarang saya akan menunjukkan cara lain untuk memperkirakan komponen varians berdasarkan ide-ide ANOVA tradisional. Pada dasarnya kami akan mengambil persamaan kuadrat rata-rata yang diharapkan untuk desain Anda, menggantikan nilai-nilai yang diamati dari kuadrat rata-rata, dan menyelesaikan komponen varians. Untuk mendapatkan kuadrat rata-rata yang diharapkan kita akan menggunakan fungsi R yang saya tulis beberapa tahun yang lalu, yang disebut EMS()
, yang didokumentasikan DI SINI . Di bawah ini saya menganggap fungsi sudah dimuat.
# 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
Oke, sekarang kita akan kembali ke contoh semula. Rasio-F yang kami coba padankan adalah:
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
Berikut adalah dua model kami:
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)
Dalam hal ini kedua model pada dasarnya menghasilkan hasil yang sama, meskipun metode kedua memiliki log-likelihood yang sedikit lebih tinggi. Tidak ada metode yang cocok aov()
. Tapi mari kita lihat apa yang kita dapatkan ketika kita menyelesaikan untuk komponen varians seperti yang kita lakukan di atas, menggunakan prosedur ANOVA yang tidak membatasi komponen varians menjadi non-negatif (tetapi yang hanya dapat digunakan dalam desain seimbang tanpa prediktor kontinu dan tidak ada data yang hilang; asumsi ANOVA klasik).
# 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
Sekarang kita bisa melihat apa yang patologis tentang contoh aslinya. Model pas terbaik adalah salah satu yang menyiratkan bahwa beberapa komponen varians acak adalah negatif. Tetapi lmer()
(dan sebagian besar program model campuran lainnya) membatasi estimasi komponen varians menjadi non-negatif. Ini umumnya dianggap sebagai kendala yang masuk akal, karena varian tentu saja tidak pernah bisa benar-benar negatif. Namun, konsekuensi dari kendala ini adalah bahwa model campuran tidak dapat secara akurat mewakili dataset yang menampilkan korelasi intraclass negatif, yaitu, dataset di mana pengamatan dari cluster yang sama kurang(daripada lebih banyak) serupa rata-rata dari pengamatan yang diambil secara acak dari dataset, dan akibatnya di mana varians dalam-cluster secara substansial melebihi varians antara-cluster. Dataset semacam itu adalah kumpulan data yang masuk akal sempurna yang kadang-kadang akan dijumpai di dunia nyata (atau disimulasikan secara tidak sengaja!), Tetapi tidak dapat dijelaskan secara masuk akal oleh model komponen-varians, karena menyiratkan komponen varians negatif. Namun mereka dapat "tidak masuk akal" dijelaskan oleh model seperti itu, jika perangkat lunak akan mengizinkannya. aov()
memungkinkan itu. lmer()
tidak.
y ~ a*b + (1 + a*b|subject), d[d$c == "1",]
? Atau mungkin saya melewatkan sesuatu?