Code
sapply(UScrime[c("U1", "U2")], function (x) {c(mean=mean(x), sd=sd(x))}) %>%
::kable() knitr
U1 | U2 | |
---|---|---|
mean | 95.46809 | 33.97872 |
sd | 18.02878 | 8.44545 |
Rui
September 19, 2022
假设数据服从正态分布(大样本情况下可以放松为对称分布),那么平均值能够很好地反映数据的总体水平。那么两份符合上述假定的数据放在一起,可以使用两样本均值的 t 检验来分析两者水平的差异。根据两样本之间是否具有相关性,又可以将 t 检验分为独立样本 t 检验和配对样本 t 检验。
核心函数 t.test
:
t.test(
y ~ x, data,
alternative, mu = 0,
paired = FALSE,
var.equal = FALSE,
conf.level = 0.95,
...
)
t.test(
x, y = NULL,
alternative,
mu = 0,
paired = FALSE,
var.equal = FALSE,
conf.level = 0.95,
...
)
其中 y ~ x
在 R 中称为 formula,你可以理解为:把 x 作为自变量、y 作为因变量,将两个变量联系起来。在这里,x 为一个二分变量,y 为一个数值变量。也可以不使用这种 formula,直接指定 x 和 y
data
是指使用的数据,也是 x 和 y 的来源
alternative
可选备择假设的类型,包括 “two.sided”、“less”或”greater”。其中第一种对应双侧检验 \(H_0:\mu_1=\mu_2\),后面两种分别对应不同方向的单侧检验 \(H_0:\mu_1<\mu_2\) 和 \(H_0:\mu_1>\mu_2\)。默认值是 “two.sided”
mu
默认值为 0。以双侧检验为例,通常我们想比较两样本均值的差异 \(H_0:\mu_1=\mu_2\) 即 \(H_0:\mu_1-\mu_2=0\),但有时我们也想比较两样本均值的差值是否与我们给定的 mu
有显著差异,即 \(H_0:\mu_1-\mu_2=\mu\) 。
paired
接受一个逻辑值,默认为 FALSE,即认为两样本独立并使用独立样本 t 检验。若为 TRUE 则使用两样本配对 t 检验
var.equal
若为 TRUE 则假定两样本方差相等,并使用合并方差估计。与一般统计软件不同的是:R 中默认两样本方差不等(FALSE),并且使用 Welch 的修正自由度
conf.level
confidence level(置信水平的简写),默认值为 0.95
例子:
在美国南部犯罪与在非南部犯罪被判监禁的可能性一样吗?很显然,这是一个双侧检验,并假设方差不等。使用的数据来自 MASS
包中的 UScrime
M | So | Ed | Po1 | Po2 | LF | M.F | Pop | NW | U1 | U2 | GDP | Ineq | Prob | Time | y |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
151 | 1 | 91 | 58 | 56 | 510 | 950 | 33 | 301 | 108 | 41 | 394 | 261 | 0.084602 | 26.2011 | 791 |
143 | 0 | 113 | 103 | 95 | 583 | 1012 | 13 | 102 | 96 | 36 | 557 | 194 | 0.029599 | 25.2999 | 1635 |
142 | 1 | 89 | 45 | 44 | 533 | 969 | 18 | 219 | 94 | 33 | 318 | 250 | 0.083401 | 24.3006 | 578 |
136 | 0 | 121 | 149 | 141 | 577 | 994 | 157 | 80 | 102 | 39 | 673 | 167 | 0.015801 | 29.9012 | 1969 |
141 | 0 | 121 | 109 | 101 | 591 | 985 | 18 | 30 | 91 | 20 | 578 | 174 | 0.041399 | 21.2998 | 1234 |
121 | 0 | 110 | 118 | 115 | 547 | 964 | 25 | 44 | 84 | 29 | 689 | 126 | 0.034201 | 20.9995 | 682 |
127 | 1 | 111 | 82 | 79 | 519 | 982 | 4 | 139 | 97 | 38 | 620 | 168 | 0.042100 | 20.6993 | 963 |
131 | 1 | 109 | 115 | 109 | 542 | 969 | 50 | 179 | 79 | 35 | 472 | 206 | 0.040099 | 24.5988 | 1555 |
157 | 1 | 90 | 65 | 62 | 553 | 955 | 39 | 286 | 81 | 28 | 421 | 239 | 0.071697 | 29.4001 | 856 |
140 | 0 | 118 | 71 | 68 | 632 | 1029 | 7 | 15 | 100 | 24 | 526 | 174 | 0.044498 | 19.5994 | 705 |
设置 paired = TRUE
即可实现非独立样本的配对 t 检验:
t.test(x, y, UScrime, paired = TRUE)
U1 | U2 | |
---|---|---|
mean | 95.46809 | 33.97872 |
sd | 18.02878 | 8.44545 |
使用 iris
数据集,首先进行宽数据到长数据的转换。
宽数据:
Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
---|---|---|---|---|
5.1 | 3.5 | 1.4 | 0.2 | setosa |
4.9 | 3.0 | 1.4 | 0.2 | setosa |
4.7 | 3.2 | 1.3 | 0.2 | setosa |
4.6 | 3.1 | 1.5 | 0.2 | setosa |
5.0 | 3.6 | 1.4 | 0.2 | setosa |
5.4 | 3.9 | 1.7 | 0.4 | setosa |
4.6 | 3.4 | 1.4 | 0.3 | setosa |
5.0 | 3.4 | 1.5 | 0.2 | setosa |
4.4 | 2.9 | 1.4 | 0.2 | setosa |
4.9 | 3.1 | 1.5 | 0.1 | setosa |
转换为长数据:
Species | Variable | Value |
---|---|---|
setosa | Sepal.Length | 5.1 |
setosa | Sepal.Width | 3.5 |
setosa | Petal.Length | 1.4 |
setosa | Petal.Width | 0.2 |
setosa | Sepal.Length | 4.9 |
setosa | Sepal.Width | 3.0 |
setosa | Petal.Length | 1.4 |
setosa | Petal.Width | 0.2 |
setosa | Sepal.Length | 4.7 |
setosa | Sepal.Width | 3.2 |
批量独立样本 t 检验:
library(rstatix)
stat.test <- data.long %>%
group_by(Variable) %>%
t_test(Value ~ Species, paired = FALSE, alternative = "two.sided") %>% # 非配对t检验、双尾检验
adjust_pvalue(method = "BH") %>% # p值调整方法,可选FDR
add_significance(
"p.adj", # 根据调整后的p值换算显著性符号
cutpoints = c(0, 0.01, 0.05, 0.1, 1),
symbols = c("***", "**", "*", "ns") # *的数量可以自己改
)
stat.test %>% knitr::kable()
Variable | .y. | group1 | group2 | n1 | n2 | statistic | df | p | p.adj | p.adj.signif |
---|---|---|---|---|---|---|---|---|---|---|
Petal.Length | Value | setosa | versicolor | 50 | 50 | -39.492719 | 62.13977 | 0e+00 | 0e+00 | *** |
Petal.Length | Value | setosa | virginica | 50 | 50 | -49.986186 | 58.60939 | 0e+00 | 0e+00 | *** |
Petal.Length | Value | versicolor | virginica | 50 | 50 | -12.603779 | 95.57044 | 0e+00 | 0e+00 | *** |
Petal.Width | Value | setosa | versicolor | 50 | 50 | -34.080342 | 74.75469 | 0e+00 | 0e+00 | *** |
Petal.Width | Value | setosa | virginica | 50 | 50 | -42.785798 | 63.12262 | 0e+00 | 0e+00 | *** |
Petal.Width | Value | versicolor | virginica | 50 | 50 | -14.625367 | 89.04338 | 0e+00 | 0e+00 | *** |
Sepal.Length | Value | setosa | versicolor | 50 | 50 | -10.520986 | 86.53800 | 0e+00 | 0e+00 | *** |
Sepal.Length | Value | setosa | virginica | 50 | 50 | -15.386196 | 76.51587 | 0e+00 | 0e+00 | *** |
Sepal.Length | Value | versicolor | virginica | 50 | 50 | -5.629165 | 94.02549 | 2e-07 | 2e-07 | *** |
Sepal.Width | Value | setosa | versicolor | 50 | 50 | 9.454976 | 94.69777 | 0e+00 | 0e+00 | *** |
Sepal.Width | Value | setosa | virginica | 50 | 50 | 6.450349 | 95.54723 | 0e+00 | 0e+00 | *** |
Sepal.Width | Value | versicolor | virginica | 50 | 50 | -3.205761 | 97.92683 | 2e-03 | 2e-03 | *** |
---
title: "使用 R 进行 t 检验"
author: "Rui"
date: "2022-09-19"
categories: [R, 统计检验, rstatix]
image: "soda.jpg"
format:
html:
code-fold: true
code-tools: true
---
```{r setup, include = FALSE}
# 设置默认参数
knitr::opts_chunk$set(
echo = TRUE,
fig.align = "center",
message = FALSE,
warning = FALSE,
collapse = TRUE
)
```
# t 检验
假设数据服从正态分布(大样本情况下可以放松为对称分布),那么平均值能够很好地反映数据的总体水平。那么两份符合上述假定的数据放在一起,可以使用两样本均值的 t 检验来分析两者水平的差异。根据两样本之间是否具有相关性,又可以将 t 检验分为独立样本 t 检验和配对样本 t 检验。
## 独立样本 t 检验
核心函数 `t.test`:
```
t.test(
y ~ x, data,
alternative, mu = 0,
paired = FALSE,
var.equal = FALSE,
conf.level = 0.95,
...
)
```
```
t.test(
x, y = NULL,
alternative,
mu = 0,
paired = FALSE,
var.equal = FALSE,
conf.level = 0.95,
...
)
```
* 其中 `y ~ x` 在 R 中称为 formula,你可以理解为:把 x 作为自变量、y 作为因变量,将两个变量联系起来。在这里,x 为一个二分变量,y 为一个数值变量。也可以不使用这种 formula,直接指定 x 和 y
* `data` 是指使用的数据,也是 x 和 y 的来源
* `alternative` 可选备择假设的类型,包括 "two.sided"、"less"或"greater"。其中第一种对应双侧检验 $H_0:\mu_1=\mu_2$,后面两种分别对应不同方向的单侧检验 $H_0:\mu_1<\mu_2$ 和 $H_0:\mu_1>\mu_2$。默认值是 "two.sided"
* `mu` 默认值为 0。以双侧检验为例,通常我们想比较两样本均值的差异 $H_0:\mu_1=\mu_2$ 即 $H_0:\mu_1-\mu_2=0$,但有时我们也想比较两样本均值的差值是否与我们给定的 `mu` 有显著差异,即 $H_0:\mu_1-\mu_2=\mu$ 。
* `paired` 接受一个逻辑值,默认为 FALSE,即认为两样本独立并使用独立样本 t 检验。若为 TRUE 则使用两样本配对 t 检验
* `var.equal` 若为 TRUE 则假定两样本方差相等,并使用合并方差估计。与一般统计软件不同的是:R 中默认两样本方差不等(FALSE),并且使用 Welch 的修正自由度
* `conf.level` confidence level(置信水平的简写),默认值为 0.95
**例子:**
在美国南部犯罪与在非南部犯罪被判监禁的可能性一样吗?很显然,这是一个双侧检验,并假设方差不等。使用的数据来自 `MASS` 包中的 `UScrime`
```{r}
#| column: page
library(MASS)
library(tidyverse)
UScrime %>% head(10) %>% knitr::kable()
```
```{r}
#| column: page
t.test(Prob ~ So, data = UScrime) %>%
broom::tidy() %>%
knitr::kable()
```
::: callout-note
由于 Prob 是一个比例值,最好的处理方法是在 t 检验之前尝试对其进行正态化变换,比如:$y/(1-y)$ 对数变换 $\ln(y/(1-y))$、Box-Cox 变换等。
:::
## 非独立样本 t 检验
设置 `paired = TRUE` 即可实现非独立样本的配对 t 检验:
```
t.test(x, y, UScrime, paired = TRUE)
```
```{r}
sapply(UScrime[c("U1", "U2")], function (x) {c(mean=mean(x), sd=sd(x))}) %>%
knitr::kable()
```
```{r}
t.test(UScrime$U1, UScrime$U2, paired = TRUE) %>%
broom::tidy() %>%
knitr::kable()
```
# 批量 t 检验
使用 `iris` 数据集,首先进行宽数据到长数据的转换。
宽数据:
```{r}
iris %>% head(10) %>% knitr::kable()
```
转换为长数据:
```{r}
data <- iris %>% as.tibble()
data.long <- data %>%
pivot_longer(cols = -Species, names_to = "Variable", values_to = "Value")
data.long %>%
head(10) %>%
knitr::kable()
```
批量独立样本 t 检验:
```{r}
#| column: page
library(rstatix)
stat.test <- data.long %>%
group_by(Variable) %>%
t_test(Value ~ Species, paired = FALSE, alternative = "two.sided") %>% # 非配对t检验、双尾检验
adjust_pvalue(method = "BH") %>% # p值调整方法,可选FDR
add_significance(
"p.adj", # 根据调整后的p值换算显著性符号
cutpoints = c(0, 0.01, 0.05, 0.1, 1),
symbols = c("***", "**", "*", "ns") # *的数量可以自己改
)
stat.test %>% knitr::kable()
```