我花了很多时间阅读书籍章节、文章、在线教程等,但没有明确的答案(主要是因为它们只描述了单向方差分析或其他非常具体的应用程序)。该站点上也有许多类似的问题,但对于我的目的而言,再次没有令人满意的答案。
本质上,我想知道在给定任意数量的主题内或主体间因素(具有任意数量的水平)。
(注意:这里唯一的问题是应该检查哪些变量,而不是如何检查它们。通过“检验/检验正态性”,我不一定指统计假设检验,它也可以基于密度或 QQ 图,等等,没关系。唯一的问题是是否可能需要多元正态性检验,在这种情况下,问题又是应该包含哪些变量。)
至少本教程和这个答案建议检查每个单元格的正态性,即每个因素的每个级别的每个可能组合——但没有给出参考或详细的推理,这对于复杂的设计似乎相当极端。但大多数其他人(例如this或this或this answer或this book chapter或this video tutorial)建议只检查残差(无论因子内/因子之间如何)。即使我假设这是后者,问题仍然存在:应该检查哪些残差?
在下文中,我使用R
函数stats:aov
输出来举例说明一些可能的答案。
我准备了一个发明的数据集用于说明。每个单独的主题都用“ subject_id
”表示。有两个主体间因素:“ btwn_X
”和“ btwn_Y
”。还有两个主体内因素:“ wthn_X
”和“ wthn_Y
”。
# preparing some invented data
dat_example = data.frame(
subject = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
btwn_X = c(1, 1, 1, 1, 2, 2, 2, 2, 2, 2),
btwn_Y = c(1, 2, 1, 2, 2, 1, 1, 1, 2, 1),
measure_x1_yA = c(36.2, 45.2, 41, 24.6, 30.5, 28.2, 40.9, 45.1, 31, 16.9),
measure_x2_yA = c(-14.1, 58.5, -25.5, 42.2, -13, 4.4, 55.5, -28.5, 25.6, -37.1),
measure_x1_yB = c(83, 71, 111, 70, 92, 75, 110, 111, 110, 85),
measure_x2_yB = c(8.024, -14.162, 3.1, -2.1, -1.5, 0.91, 11.53, 18.37, 0.3, -0.59),
measure_x1_yC = c(27.4,-17.6,-32.7, 0.4, 37.2, 1.7, 18.2, 8.9, 1.9, 0.4),
measure_x2_yC = c(7.7, -0.8, 2.2, 14.1, 22.1, -47.7, -4.8, 8.6, 6.2, 18.2)
)
dat_example$subject = as.factor(as.character(dat_example$subject))
dat_example$btwn_X = as.factor(as.character(dat_example$btwn_X))
dat_example$btwn_Y = as.factor(as.character(dat_example$btwn_Y))
vars = c(
'measure_x1_yA',
'measure_x2_yA',
'measure_x1_yB',
'measure_x2_yB',
'measure_x1_yC',
'measure_x2_yC'
)
dat_l = stats::reshape(
dat_example,
direction = 'long',
varying = vars,
idvar = 'subject',
timevar = "within_factor",
v.names = "values",
times = vars
)
dat_l$wthn_X = sapply(strsplit(dat_l$within_factor, split = '_', fixed =
TRUE), `[`, 2)
dat_l$wthn_Y = sapply(strsplit(dat_l$within_factor, split = '_', fixed =
TRUE), `[`, 3)
dat_l$wthn_X = as.factor(as.character(dat_l$wthn_X))
dat_l$wthn_Y = as.factor(as.character(dat_l$wthn_Y))
# performing the ANOVA
aov_BBWW = aov(values ~ btwn_X * btwn_Y * wthn_X * wthn_Y +
Error(subject / (wthn_X * wthn_Y)), data = dat_l)
(另请参阅此处lme4::lmer
的扩展版本,其中包含各种因子变化和模型之间/内部。)
aov 对象aov_BBWW
返回以下内容:
Grand Mean: 23.6847
Stratum 1: subject
Terms:
btwn_X btwn_Y btwn_X:btwn_Y Residuals
Sum of Squares 61.549 351.672 18.969 3221.628
Deg. of Freedom 1 1 1 6
Residual standard error: 23.17192
15 out of 18 effects not estimable
Estimated effects may be unbalanced
Stratum 2: subject:wthn_X
Terms:
wthn_X btwn_X:wthn_X btwn_Y:wthn_X btwn_X:btwn_Y:wthn_X Residuals
Sum of Squares 23432.120 612.948 712.387 773.779 513.165
Deg. of Freedom 1 1 1 1 6
Residual standard error: 9.248106
8 out of 12 effects not estimable
Estimated effects may be unbalanced
Stratum 3: subject:wthn_Y
Terms:
wthn_Y btwn_X:wthn_Y btwn_Y:wthn_Y btwn_X:btwn_Y:wthn_Y Residuals
Sum of Squares 19262.400 982.159 1561.578 1836.188 5860.787
Deg. of Freedom 2 2 2 2 12
Residual standard error: 22.09975
8 out of 16 effects not estimable
Estimated effects may be unbalanced
Stratum 4: subject:wthn_X:wthn_Y
Terms:
wthn_X:wthn_Y btwn_X:wthn_X:wthn_Y btwn_Y:wthn_X:wthn_Y
Sum of Squares 20248.558 159.421 986.331
Deg. of Freedom 2 2 2
btwn_X:btwn_Y:wthn_X:wthn_Y Residuals
Sum of Squares 604.163 4789.399
Deg. of Freedom 2 12
Residual standard error: 19.9779
Estimated effects may be unbalanced
我可以访问以下残差(有关更多详细信息,请参见此处):
aov_BBWW$subject$residuals
aov_BBWW$`subject:wthn_X`$residuals
aov_BBWW$`subject:wthn_Y`$residuals
aov_BBWW$`subject:wthn_X:wthn_Y`$residuals
aov_BBWW$`(Intercept)`$residuals
根据上面引用的一些资料,这些残差应用于正态性检验,但尚不清楚是全部还是仅一个(以及在这种情况下是哪一个)。
编辑:
经过大量挖掘(并在 EdM 的回答和评论的帮助下),最权威的解决方案似乎是,在只有主体间因素的 ANOVA 的情况下,正确的变量只是residuals
来自 aov 对象的向量(例如aov_BB$residuals
) ,而如果有任何主题内变量,我应该这样做:
aov_proj = proj(aov_BBWW)
aov_proj[[length(aov_proj)]][,"Residuals"]
后者是要检查正态性和其他相关假设的变量。为什么会这样,我无法理解,但几个看似自信的消息来源给出了这个解决方案:this and this R mailing list replys, this and this and this CV answers(讽刺的是后两个不是被接受的),本教程和MASS文档. 大多数或所有这些来源都来自Venables 和 Ripley (2002),但我认为他们不会盲目地复制不正确的东西。
尽管如此,问题仍然悬而未决:我很乐意收到关于此事的进一步验证(或反驳)和解释。
(顺便说一句,如果要信任上述来源,则拟合值显然可以通过以下方式访问fitted(aov_BBWW[[length(aov_BBWW)]])
:)