如何准确的使用R进行两独立样本的显著性检验,T检验?非参数检验?

在科研工作中,使用较多的应该就是两独立样本的显著性检验,也就是我们常说的比较两个组有没有统计学差异,比方说我们收集了身高数据,想比较男性和女性的身高有没有差别,这就是两独立样本的显著性检验,而最让人耳熟能详的就是t检验,然而有时候(我认为更多的适合)却又有一个非参数检验,其实统计学不那么严谨的话,基本都是用t检验,然而这样暴力的选择并不科学,那么到底该如何选择才是最科学的呢?

目前常用的统计软件有SPSS和GraphPad,不过这两个都是收费软件,虽然有破解版,然而总归是没有版权的,而R作为开源软件,又附带N多的包,功能什么强大,反正免费就是王道。。。

有两个参考网站可以供学习

一、假设检验的前提是什么?

1. 两个样本是否独立?

如果两个样本不是独立样本,而是配对样本,那么就不能用独立样本的t检验,而应该是配对样本的t检验。

  • 独立样本就是说两组样本没有什么关联,比如说男女的身高差,男的就跟女的没有任何关联

  • 配对样本是其实是一种样本,不过经历了某种干预,比方说没有用药的时候是A组,然后给A组的成员用了药就变成了B组;又比方说同一个病人标本取了癌组织和癌旁组织,那么所有取了癌组织和癌旁组织标本的患者就是配对样本。

2. 两组中每组的数据是否服从正态分布?

在进行假设检验前,首先就要看是不是正态分布,也就是说要进行正态检验,一般有Shapiro-Wilk test(S-W检验)和Kolmogorov-Smirnov test(K-S检验),两种方法都有人用,但是一般选择S-W检验。这里我们一般不需要过分纠结选哪种,K-S检验适合用于大数据样本的正态性检验,我们主流还是选择S-W检验(shapiro.test())

  • 只有符合正态分布的才可以使用t检验

  • 如果数据不是正态分布的,可以尝试先进行数值转换,如log2处理,如果满足正态分布,可以选择t检验

  • 如果数据不是正态分布,数值转换以后还是非正态,则建议使用非参数检验(即,两样本Wilcoxon秩检验)

3. 这两个总体是否符合方差齐性?

这点其实只在数据符合正态分布的使用,因为不正态分布的话,直接就非参数检验,但是一般非正态分布的情况下也可以做一下方差齐性检验。

方差齐性的检验方法也很多,一般也有三种检验方法:

方差齐性检验方法总体样本要求正态性要求函数
F检验两个总体样本要求有正态性var.test
Bartlett \(\chi^2\)检验多个总体样本要求有正态性bartlett.test()
Levene检验多个总体样本不要求正态性leveneTest(),需加载car包

一般方差齐性检验完以后,会有两种情况

  • 如果正态分布,两个总体符合方差齐性:选择近似t检验(有Satterthwaite法近似t检验、Welch法近似t检验和Cochran & Cox法近似t检验三种方法,一般为Welch法)

  • 如果正态分布,但两个总体不符合方差齐性:正宗的t检验

二、一般操作步骤

1、正态性检验

比如先随机构建一个表格,看男女的体重差异

women_weight <- c(88.9, 81.2, 73.3, 21.8, 63.4, 84.6, 28.4, 28.8, 28.5)
men_weight <- c(37.8, 80, 33.4, 36, 89.4, 83.3, 97.3, 81.3, 92.4)
# 建立一个数据框
my_data <- data.frame( 
                group = rep(c("Woman", "Man"), each = 9),
                weight = c(women_weight,  men_weight)
                )
print(my_data)
##    group weight
## 1  Woman   88.9
## 2  Woman   81.2
## 3  Woman   73.3
## 4  Woman   21.8
## 5  Woman   63.4
## 6  Woman   84.6
## 7  Woman   28.4
## 8  Woman   28.8
## 9  Woman   28.5
## 10   Man   37.8
## 11   Man   80.0
## 12   Man   33.4
## 13   Man   36.0
## 14   Man   89.4
## 15   Man   83.3
## 16   Man   97.3
## 17   Man   81.3
## 18   Man   92.4

在进行正态分布前,我们可以先统计一下数据,如按性别计算统计信息(中位数和四分位数范围(IQR)),这里使用dplyr软件包,用group_by函数,我们可以分别统计两种性别的数目、均数和标准差等信息。

#install.packages("dplyr")
library(dplyr)
## 
## 载入程辑包:'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
group_by(my_data, group) %>% # 按group 分组
  summarise(
    count = n(), #定义数目
    mean = mean(weight, na.rm = TRUE), #定义均数,去除空白值
    sd = sd(weight, na.rm = TRUE), #定义标准差,去除空白
  )
## # A tibble: 2 × 4
##   group count  mean    sd
##   <chr> <int> <dbl> <dbl>
## 1 Man       9  70.1  26.4
## 2 Woman     9  55.4  28.1

可以简单看一下boxplot

boxplot(weight~group,my_data,col = c("steelblue", "brown"))

然后就开始做正态性检验,这里选择Shapiro-Wilk test,即shapiro.test()函数

这里要注意:不是简单用shapiro.test(data$y)统计所有样品的正态分布,而应该是各个组的样品的正态分布,也就是要同时看男性和女性的正态分布,同时满足正态分布,才叫两独立样品的正态分布

使用with()和shapiro.test()的函数来为每组样本计算Shapiro-Wilk测试。

with(my_data, shapiro.test(weight[group == "Man"]))  # 检验男性的正态分布
## 
##  Shapiro-Wilk normality test
## 
## data:  weight[group == "Man"]
## W = 0.79399, p-value = 0.01743
with(my_data, shapiro.test(weight[group == "Woman"]))  # 检验女性的正态分布
## 
##  Shapiro-Wilk normality test
## 
## data:  weight[group == "Woman"]
## W = 0.83017, p-value = 0.04485
shapiro.test(my_data$weight) # 不考虑分组的话,要这样进行正态检验,这个适合于单个样品与均值的比较
## 
##  Shapiro-Wilk normality test
## 
## data:  my_data$weight
## W = 0.83988, p-value = 0.005889

可以看到两组样品的P值都是<0.05(男性p值为0.01743,女性p值为0.04485),也就是两组样品的正态分布具有显著性差异,也就是说都不符合正态分布,这个时候就可以直接选择非参数检验了,当然也可以同时检验一下是否还具有方差齐性。

这里还要注意,如果两组数据中只有一组不是正态分布要使用两独立样本的非参数Wilcoxon秩检验。

2、方差齐性检验

两独立样品推荐使用F检验来检验方差齐性。可以使用var.test(y,x,data)函数执行以下操作

var.test(weight ~ group, data = my_data)
## 
##  F test to compare two variances
## 
## data:  weight by group
## F = 0.88062, num df = 8, denom df = 8, p-value = 0.8617
## alternative hypothesis: true ratio of variances is not equal to 1
## 95 percent confidence interval:
##  0.1986398 3.9040261
## sample estimates:
## ratio of variances 
##           0.880622

可以看到p值为0.8617,大于0.5,认为两组的方差具有差异,也就是说方差具有齐性,如果之前的数据呈正态分布,就可以使用t检验了,但是之前的数据不呈正态分布,所以还是选择非参数检验,所以如果数据不是正态分布的话,理论上就没有必要做方差齐性检验了。

3、非参数检验

我们知道这个数据不是正态分布,我们就选择非参数检验,但这里还要分两种情况:

  • 一种是双尾假设,也就是全部假设(比如我要知道的是男女之间的体重有没有差异)

  • 一种是单尾假设,也就是说只看一种结果(比如我只想知道男的体重是不是比女的重)

那么这样就有三种结果:

  1. 男女的体重之间有显着差异吗?

    wilcox.test(weight ~ group, #数值比分组
                data = my_data, #数据
                var.equal = TRUE, #方差具有齐性
                alternative = "two.sided" #双尾假设
                )
    ## 
    ##  Wilcoxon rank sum exact test
    ## 
    ## data:  weight by group
    ## W = 59, p-value = 0.1135
    ## alternative hypothesis: true location shift is not equal to 0
    wilcox.test(weight ~ group, #数值比分组
                data = my_data, #数据
                var.equal = FALSE, #方差不具有齐性
                alternative = "two.sided" #双尾假设
                )
    ## 
    ##  Wilcoxon rank sum exact test
    ## 
    ## data:  weight by group
    ## W = 59, p-value = 0.1135
    ## alternative hypothesis: true location shift is not equal to 0

    这个数据的结果告诉我们,不管方差有没有齐性,其实两个的结果都是一样的,也佐证了非正态分布的样品,一般可以不做方差齐性检验,但是做了更严谨,因为毕竟还是有个var.equal函数,大家可以自行比较。

  2. 男性的体重是否小于女性的体重?

wilcox.test(weight ~ group, 
            data = my_data,
        var.equal = TRUE, 
        alternative = "less" #不要问less是什么意思。。。
        )
## 
##  Wilcoxon rank sum exact test
## 
## data:  weight by group
## W = 59, p-value = 0.953
## alternative hypothesis: true location shift is less than 0

结果可以看出p>0.05,男的体重不比女性轻 3. 男性的体重是否大于女性的体重?

wilcox.test(weight ~ group, 
            data = my_data,
        var.equal = TRUE, 
        alternative = "greater" #不要问greater是什么意思。。。
        )
## 
##  Wilcoxon rank sum exact test
## 
## data:  weight by group
## W = 59, p-value = 0.05675
## alternative hypothesis: true location shift is greater than 0

结果可以看出p>0.05,男的体重不比女的重

4、t检验

这里我就不用别的数据来统计了,还是用这个数据,但是你要知道这样的结果是错的。。。

  • 如果数据呈正态分布,方差也具有齐性,我们就用t检验,依然有双尾和单尾假设,我们默认双尾,函数如下:
t.test(weight ~ group, 
       data = my_data, 
       var.equal = TRUE, # 方差具有齐性,要选择T,默认其实是F
       alternative = "two.sided")
## 
##  Two Sample t-test
## 
## data:  weight by group
## t = 1.1421, df = 16, p-value = 0.2702
## alternative hypothesis: true difference in means between group Man and group Woman is not equal to 0
## 95 percent confidence interval:
##  -12.55755  41.89088
## sample estimates:
##   mean in group Man mean in group Woman 
##            70.10000            55.43333
  • 如果数据呈正态分布,但是方差不具有齐性,这时候我们选择近似t检验,需要把var.equal设置为F,其实默认就是F
t.test(weight ~ group, 
       data = my_data, 
       var.equal = F, # 方差具有齐性,要选择T,默认其实是F
       alternative = "two.sided")
## 
##  Welch Two Sample t-test
## 
## data:  weight by group
## t = 1.1421, df = 15.936, p-value = 0.2703
## alternative hypothesis: true difference in means between group Man and group Woman is not equal to 0
## 95 percent confidence interval:
##  -12.56646  41.89980
## sample estimates:
##   mean in group Man mean in group Woman 
##            70.10000            55.43333

如果想知道单尾假设结果,可以参考非参数检验,把alternative(可以简写为alt)设置为less或者greater即可


三、分析流程图


那么,一套组合拳就打完了,你对是选择哪种检验方法还清楚吗?

欧阳松
欧阳松
主治医师、讲师

My research interests include urogenital tumors, urolithiasis, male infertility, male erectile dysfunction,etc.

Related