问题
你想要(精确)检验样本的方差同质性(同方差,方差齐性)。许多统计检验假设总体同方差。
方案
有许多检验方差同质性的方式,下面列出三种:
- Bartlett’s test - 如果数据服从正态分布,这是最好地检验方法。该方法对非正态数据非常敏感,如果数据不是正态的很可能返回假阳性的结果。
- Levene’s test - 数据偏离正态性时比Bartlett检验更稳定(鲁棒性更好),内置于
car
包 - Fligner-Killeen test - 这是一个非参数检验,数据偏离正态是非常稳定适用。
对于所有的检验,零假设为总体方差相同(同质;不是相等的意思);备择假设是至少两组样本(总体方差)不同。
样例数据
这里的例子使用了InsectSprays
和 ToothGrowth
数据集。 InsectSprays
数据集有一个独立变量,而 ToothGrowth
数据集有两个独立变量。
head(InsectSprays)
#> count spray
#> 1 10 A
#> 2 7 A
#> 3 20 A
#> 4 14 A
#> 5 14 A
#> 6 12 A
tg <- ToothGrowth
tg$dose <- factor(tg$dose) # Treat this column as a factor, not numeric
head(tg)
#> len supp dose
#> 1 4.2 VC 0.5
#> 2 11.5 VC 0.5
#> 3 7.3 VC 0.5
#> 4 5.8 VC 0.5
#> 5 6.4 VC 0.5
#> 6 10.0 VC 0.5
快速绘制数据集的箱线图:
plot(count ~ spray, data = InsectSprays)
plot(len ~ interaction(dose,supp), data=ToothGrowth)
初一看好像数据集的方差都不同质,但这需要像下面一样进行合适的检验。
Bartlett’s test
有一个独立变量:
bartlett.test(count ~ spray, data=InsectSprays)
#>
#> Bartlett test of homogeneity of variances
#>
#> data: count by spray
#> Bartlett's K-squared = 25.96, df = 5, p-value = 9.085e-05
# Same effect, but with two vectors, instead of two columns from a data frame
# bartlett.test(InsectSprays$count ~ InsectSprays$spray)
有多个独立变量,必须使用interaction()
函数将这些独立变量包裹为含所有因子组合的单个变量。如果不适应,那么会得到错误的自由度,因而p值也将是错误的。
bartlett.test(len ~ interaction(supp,dose), data=ToothGrowth)
#>
#> Bartlett test of homogeneity of variances
#>
#> data: len by interaction(supp, dose)
#> Bartlett's K-squared = 6.9273, df = 5, p-value = 0.2261
# The above gives the same result as testing len vs. dose alone, without supp
bartlett.test(len ~ dose, data=ToothGrowth)
#>
#> Bartlett test of homogeneity of variances
#>
#> data: len by dose
#> Bartlett's K-squared = 0.66547, df = 2, p-value = 0.717
Levene’s test
leveneTest
函数是car
包的一部分。
有一个独立变量:
library(car)
leveneTest(count ~ spray, data=InsectSprays)
#> Levene's Test for Homogeneity of Variance (center = median)
#> Df F value Pr(>F)
#> group 5 3.8214 0.004223 **
#> 66
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
有两个独立变量。注意这里 interaction
函数不需要,因为该函数用于其他两个检验。
leveneTest(len ~ supp*dose, data=tg)
#> Levene's Test for Homogeneity of Variance (center = median)
#> Df F value Pr(>F)
#> group 5 1.7086 0.1484
#> 54
Fligner-Killeen test
有一个独立变量:
fligner.test(count ~ spray, data=InsectSprays)
#>
#> Fligner-Killeen test of homogeneity of variances
#>
#> data: count by spray
#> Fligner-Killeen:med chi-squared = 14.483, df = 5, p-value = 0.01282
# Same effect, but with two vectors, instead of two columns from a data frame
# fligner.test(InsectSprays$count ~ InsectSprays$spray)
当处理多个独立变量时,这个fligner.test
函数有跟bartlett.test
相同的行为。必须使用 interaction()
函数。
fligner.test(len ~ interaction(supp,dose), data=ToothGrowth)
#>
#> Fligner-Killeen test of homogeneity of variances
#>
#> data: len by interaction(supp, dose)
#> Fligner-Killeen:med chi-squared = 7.7488, df = 5, p-value = 0.1706
# The above gives the same result as testing len vs. dose alone, without supp
fligner.test(len ~ dose, data=ToothGrowth)
#>
#> Fligner-Killeen test of homogeneity of variances
#>
#> data: len by dose
#> Fligner-Killeen:med chi-squared = 1.3879, df = 2, p-value = 0.4996