關(guān)于單因素方差分析,網(wǎng)上有很多方法,比如使用R語言進(jìn)行單因素方差分析以及結(jié)果可視化這個(gè)教程。
但是R到底如何做多組樣本均數(shù)比較及兩兩比較?我覺得上面的教程是錯(cuò)誤的,原因如下:
- 沒有進(jìn)行正態(tài)性檢驗(yàn)和方差齊性檢驗(yàn)?
- 兩兩比較直接使用t檢驗(yàn),而不是事后檢驗(yàn)
rstatix包是一個(gè)非常好的統(tǒng)計(jì)學(xué)包,含有許許多多的統(tǒng)計(jì)函數(shù),關(guān)于ANOVA的分析,可以看下嗎這個(gè)教程,雖然是英語的,但是邏輯性很強(qiáng)。
ANOVA in R: The Ultimate Guide - Datanovia
我們可以用經(jīng)典的內(nèi)置ToothGrowth數(shù)據(jù)進(jìn)行演示。
構(gòu)建數(shù)據(jù)
data("ToothGrowth") ## 加載數(shù)據(jù)
df <- ToothGrowth ## 重命名數(shù)據(jù)
df$dose<-as.factor(df$dose) ## 將劑量dose設(shè)置為因子,這步很重要
數(shù)據(jù)統(tǒng)計(jì)
library(rstatix)
library(tidyr)
## 按dose分組計(jì)算各組的len均值和標(biāo)準(zhǔn)差
df %>%
group_by(dose) %>%
get_summary_stats(len, type = "mean_sd")
dose | variable | n | mean | sd | |
---|---|---|---|---|---|
1 | 0.5 | len | 20 | 10.605 | 4.5 |
2 | 1 | len | 20 | 19.735 | 4.415 |
3 | 2 | len | 20 | 26.1 | 3.774 |
簡單可視化數(shù)據(jù)
library(ggpubr)
ggboxplot(df, x = "dose", y = "len")
正態(tài)性檢驗(yàn)
可以使用以下兩種方法之一檢查正態(tài)性假設(shè):
分析方差分析模型殘差。以檢查所有組的正態(tài)性。此方法更容易,并且當(dāng)您有許多組或每個(gè)組的數(shù)據(jù)點(diǎn)很少時(shí),它非常方便。
分別檢查每個(gè)組的正態(tài)性。當(dāng)只有幾個(gè)組并且每個(gè)組有許多數(shù)據(jù)點(diǎn)時(shí),可以使用此方法。
模型殘差的正態(tài)性檢驗(yàn)
首先構(gòu)建殘差的線性模型,以QQ圖的形式展示結(jié)果,見下圖所示。
# 構(gòu)建線性模型
model <- lm(len ~ dose, data = df)
# 構(gòu)建殘差的QQ圖
ggqqplot(residuals(model))
計(jì)算Shapiro-Wilk正態(tài)性檢驗(yàn)
shapiro_test(residuals(model))
variable | statistic | p.value | |
---|---|---|---|
1 | residuals(model) | 0.967308970963541 | 0.1076299868954 |
在QQ圖中,由于所有點(diǎn)都大致沿著參考線落下,因此我們可以假設(shè)呈正態(tài)分布。這一結(jié)論得到了Shapiro Wilk檢驗(yàn)的支持。p值不顯著(p=0.0798),因此我們可以假設(shè)為正態(tài)。
各組的正態(tài)性檢驗(yàn)
計(jì)算各組水平的Shapiro-Wilk檢驗(yàn)。如果數(shù)據(jù)為正態(tài)分布,則p值應(yīng)大于0.05。
df %>%
group_by(dose) %>%
shapiro_test(len)
dose | variable | statistic | p | |
---|---|---|---|---|
1 | 0.5 | len | 0.9406450940929 | 0.246601486196049 |
2 | 1 | len | 0.931343143558916 | 0.163882141233336 |
3 | 2 | len | 0.977753538808449 | 0.901911496439863 |
根據(jù)Shapiro-Wilk的正態(tài)性檢驗(yàn),各組均為正態(tài)分布(p>0.05)。
請注意,如果樣本數(shù)量大于 50,則首選正態(tài)QQ 圖,因?yàn)樵谳^大的樣本量下,Shapiro-Wilk檢驗(yàn)變得非常敏感,即使與正態(tài)性有輕微的偏差。
QQ圖繪制了給定數(shù)據(jù)與正態(tài)分布之間的相關(guān)性。為每組數(shù)據(jù)繪制QQ圖,見Figure 2所示。
ggqqplot(df, "len", facet.by = "dose")
所有點(diǎn)都大致沿著參考線落下。所以我們可以假設(shè)數(shù)據(jù)是正態(tài)分布的。
如果對數(shù)據(jù)的正態(tài)性有疑問,可以使用Kruskal-Wallis檢驗(yàn),這是單因素ANOVA檢驗(yàn)的非參數(shù)替代方法。
方差齊性檢驗(yàn)
-
殘差結(jié)合擬合圖可用于檢查方差的同質(zhì)性。
plot(model, 1)
在上圖中,殘差和擬合值(每個(gè)組的均值)之間沒有明顯的關(guān)系,結(jié)果很好。因此,我們可以假設(shè)方差的同質(zhì)性。
- 也可以使用 Levene 檢驗(yàn)來檢查方差的同質(zhì)性:
df %>% levene_test(len ~ dose)
df1 | df2 | statistic | p | |
---|---|---|---|---|
1 | 2 | 57 | 0.64573411096315 | 0.528069457375992 |
這時(shí),我們要注意,一定要將dose定義為因子,否則會(huì)因?yàn)榻Y(jié)果是數(shù)字而報(bào)錯(cuò)。
上面的結(jié)果中,我們可以看到 p 值> 0.05,這意味組間方差之間沒有顯著差異。因此,我們可以假設(shè)不同組中方差具有齊性或同質(zhì)性。
在不滿足方差齊性假設(shè)的情況下,可以使用函數(shù)
Welch_ANOVA_test()
函數(shù)計(jì)算Welch單因素方差分析測試。該測試不需要假設(shè)方差相等。
計(jì)算檢驗(yàn)
res.aov<- df %>% anova_test(len ~ dose)
res.aov
Effect | DFn | DFd | F | p | p<.05 | ges | |
---|---|---|---|---|---|---|---|
1 | dose | 2 | 57 | 67.416 | 9.53e-16 | * | 0.703 |
在上表中,該列對應(yīng)于廣義eta平方(效應(yīng)大小)。它測量結(jié)果變量(這里是植物)中的變異性比例,可以用預(yù)測因子(這里是治療)來解釋。效應(yīng)大小為0.703(26%)意味著70.3%的變化可歸因于劑量條件
從上述ANOVA表中可以看出,各組之間存在顯著差異(p=9.53e-16),顯示為”*“,F(xiàn)(2,57)=67.416,p=9.53e-16,eta2[g]=0.703。
該結(jié)果可以在可視化的時(shí)候引用上。
事后檢驗(yàn)
常用單因素方差分析用于多組間的兩兩比較的方法是Tukey事后檢驗(yàn)(而不是簡單的t檢驗(yàn))。可用rstati的tukey_hsd()
函數(shù)計(jì)算。
而對于方差不齊的情況下可以使用Games Howell事后檢驗(yàn),即rstati的
games_howell_test
()
函數(shù)
pwc <- tukey_hsd(df, len ~ dose)
pwc
另外,還有幾個(gè)同等的代碼,結(jié)果一樣
df %>% tukey_hsd(len ~ dose)
aov(len ~ dose, data = df) %>% tukey_hsd()
term | group1 | group2 | null.value | estimate | conf.low | conf.high | p.adj | p.adj.signif | |
---|---|---|---|---|---|---|---|---|---|
1 | dose | 0.5 | 1 | 0 | 9.13 | 5.90180527932805 | 12.3581947206719 | 2e-8 | **** |
2 | dose | 0.5 | 2 | 0 | 15.495 | 12.266805279328 | 18.7231947206719 | 1.12e-11 | **** |
3 | dose | 1 | 2 | 0 | 6.36499999999999 | 3.13680527932805 | 9.59319472067194 | 0.0000425 | **** |
可視化報(bào)告
我們可以將單因素方差分析的結(jié)果報(bào)告如下:
進(jìn)行單因素方差分析,以評估3個(gè)不同劑量組的牙齒生長是否不同:0.5(n=20)、1.0(n=20)和2.0(n=20)。
數(shù)據(jù)表示為平均值+/-標(biāo)準(zhǔn)差。不同劑量組之間的牙齒生長在統(tǒng)計(jì)學(xué)上有顯著差異,F(xiàn)(2,57)=67.416,p=9.53e-16,廣義eta平方=0.703。
Tukey事后分析顯示,三組數(shù)據(jù)具有統(tǒng)計(jì)學(xué)意義(p=0.012)
帶有p值的箱示圖可視化結(jié)果
使用add_xy_position()
函數(shù)自動(dòng)進(jìn)行兩兩分組比較,同時(shí)確定x和y軸位置。
## 添加各組比較和坐標(biāo)軸位置
pwc <- pwc %>% add_xy_position(x = "dose")
term | group1 | group2 | null.value | estimate | conf.low | conf.high | p.adj | p.adj.signif | y.position | groups | xmin | xmax | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | dose | 0.5 | 1 | 0 | 9.13 | 5.90180527932805 | 12.3581947206719 | 2e-8 | **** | 35.388 | 0.5,1 | 1 | 2 |
2 | dose | 0.5 | 2 | 0 | 15.495 | 12.266805279328 | 18.7231947206719 | 1.12e-11 | **** | 37.62 | 0.5,2 | 1 | 3 |
3 | dose | 1 | 2 | 0 | 6.36499999999999 | 3.13680527932805 | 9.59319472067194 | 0.0000425 | **** | 39.852 | 1,2 | 2 | 3 |
- 使用
stat_pvalue_manual()
函數(shù)可以自動(dòng)添加兩兩比較的p值和顯示的位置,還可以選擇是否顯示無意義的結(jié)果,以及是顯示星號還是數(shù)值 - 使用
labs()
函數(shù)添加整體結(jié)果和方法
## ggpubr繪圖,加整體p值和兩兩比較p值
ggboxplot(df, x = "dose", y = "len") +
stat_pvalue_manual(pwc,hide.ns = TRUE ) +#隱藏?zé)o意義的結(jié)果
labs(subtitle = get_test_label(res.aov, detailed = TRUE),
caption = get_pwc_label(pwc)
)
當(dāng)然,我們也可以適當(dāng)美化,比如配色,主題什么的,見Figure 3所示。
ggboxplot(df, x = "dose", y = "len",
add = 'jitter',color = 'dose',
palette = 'lancet', #設(shè)置lancet配色
ggtheme = theme_bw(), # 設(shè)置背景
legend='none' ## 去除分組標(biāo)簽
) +stat_pvalue_manual(pwc, hide.ns = TRUE) +
labs( subtitle = get_test_label(res.aov, detailed = TRUE), caption = get_pwc_label(pwc))
我們也可以用柱狀圖來可視化,見Figure 4所示。
ggbarplot(df, x = "dose", y = "len",
add = 'mean_sd',fill = 'dose',
palette = 'npg', #設(shè)置lancet配色
ggtheme = theme_pubclean(), # 設(shè)置背景
legend='none' ## 去除分組標(biāo)簽
) +stat_pvalue_manual(pwc, hide.ns = TRUE) +
labs( subtitle = get_test_label(res.aov, detailed = TRUE), caption = get_pwc_label(pwc))
放寬標(biāo)準(zhǔn)的方差齊性假設(shè)
經(jīng)典的單因素方差分析檢驗(yàn)要求所有組的方差相等。在本例,Levene檢驗(yàn)不顯著,提示方差齊性假設(shè)證明是良好的。
在違反方差齊性假設(shè)的情況下,我們?nèi)绾芜M(jìn)行ANOVA檢驗(yàn)?zāi)兀?/p>
在無法假設(shè)方差齊性的情況下(即Levene檢驗(yàn)顯著時(shí)),使用Welch單因素檢驗(yàn)是標(biāo)準(zhǔn)單單因素方差分析的替代方法。
在這種情況下,可以使用Games-Howell事后檢驗(yàn)或成對t檢驗(yàn)(不假設(shè)方差相等)來比較所有可能的群體差異組合。
# Welch One way ANOVA test
res.aov2 <- df %>% welch_anova_test(len ~ dose)
# Pairwise comparisons (Games-Howell)
pwc2 <- df %>% games_howell_test(len ~ dose)
# 可視化: box plots with p-values
pwc2 <- pwc2 %>% add_xy_position(x = "dose", step.increase = 1)
ggboxplot(df, x = "dose", y = "len",
add = 'jitter',color = 'dose',
palette = 'lancet', #設(shè)置lancet配色
ggtheme = theme_bw(), # 設(shè)置背景
legend='none' ## 去除分組標(biāo)簽
) +
stat_pvalue_manual(pwc2, hide.ns = TRUE) + # 如果不想隱藏?zé)o意義的,可以設(shè)置hide.ns = F
labs(
subtitle = get_test_label(res.aov2, detailed = TRUE),
caption = get_pwc_label(pwc2)
)
兩組方法的比較
將兩種方法進(jìn)行比較,見Figure 5所示。
p1<-ggboxplot(df, x = "dose", y = "len",
add = 'jitter',color = 'dose',
palette = 'lancet', #設(shè)置lancet配色
ggtheme = theme_bw(), # 設(shè)置背景
legend='none', ## 去除分組標(biāo)簽
title = 'ANOVA text') +stat_pvalue_manual(pwc, hide.ns = TRUE,label = 'p.adj') +
labs( subtitle = get_test_label(res.aov, detailed = TRUE), caption = get_pwc_label(pwc))
p2<-ggboxplot(df, x = "dose", y = "len",
add = 'jitter',color = 'dose',
palette = 'lancet', #設(shè)置lancet配色
ggtheme = theme_bw(), # 設(shè)置背景
legend='none', ## 去除分組標(biāo)簽
title = 'Welch one-way test' ) +
stat_pvalue_manual(pwc2, hide.ns = TRUE,label = 'p.adj') +
labs(subtitle = get_test_label(res.aov2, detailed = TRUE),
caption = get_pwc_label(pwc2)
)
## 拼圖
cowplot::plot_grid(p1,p2)
當(dāng)然,如果使用放寬條件的情況,其實(shí)還有一個(gè)更簡單的辦法,就是直接使用ggstatsplot這個(gè)包
library(ggstatsplot)
p3<-ggbetweenstats(df,dose,len,p.adjust.method = 'none')
p3
cowplot::plot_grid(p3,p2)
可以看到結(jié)果是一樣的.
另外,rstatix包也可以進(jìn)行雙因素、多因素的ANOVA,具體的可以去https://www.datanovia.com/en/lessons/anova-in-r學(xué)習(xí)教程