귀하의 질문에 대한 직접적인 대답은 여러분이 마지막으로 쓴 모델입니다.
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)
두 가지 접근 방식은 단순한 양방향 문제에서 완전히 동일합니다. 이제 3 방향 문제로 넘어가겠습니다. 앞서 언급 한 데이터 세트는 병리학적인 것으로 언급했습니다. 따라서 예제 데이터 집합을 해결하기 전에 먼저 실제 분산 구성 요소 모델에서 데이터 집합을 생성하는 것입니다 (예 : 0이 아닌 분산 구성 요소가 실제 모델에 내장 된 경우). 먼저 선호하는 매개 변수가 제안한 것보다 어떻게 더 잘 작동하는지 보여 드리겠습니다. 그런 다음 마이너스 가 아니 어야 함을 의미하지 않는 분산 성분을 추정하는 다른 방법을 보여 드리겠습니다 . 그런 다음 원래 예제 데이터 세트의 문제를 볼 수있는 위치에있게됩니다.
새로운 데이터 셋은 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()
, 첫 번째 방법은 최소한 야구장에 있지만 두 번째 방법 만의 출력과 일치합니다 . 두 번째 방법은 더 높은 로그 가능성을 달성합니다. 이 두 가지 방법이 다른 결과를 제공하는 이유를 잘 모르겠습니다. 다시 말하지만 "원칙적으로"동등한 것으로 생각되지만 수치 / 계산상의 이유 일 수 있습니다. 아니면 내가 틀렸을 수도 있고 원칙적으로 동등하지 않습니다.
이제 기존 분산 분석 아이디어를 기반으로 분산 성분을 추정하는 다른 방법을 보여 드리겠습니다. 기본적으로 우리는 설계에 대한 예상 평균 제곱 방정식을 취하고 평균 제곱의 관측 값을 대체하고 분산 성분을 풀 것입니다. 예상 평균 제곱을 얻으려면 우리는 내가라고, 몇 년 전에 쓴 것이라는 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 가정).
# 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",]
않습니까? 아니면 뭔가 빠졌습니까?