R进行两因素重复测量方差分析并可视化(双组折线图)

在仙桃学术上的生信工具里面,有一个折线图的绘图工具,可以很快速便捷的得出结论并可视化结果,当然不是说这个功能有多强大,而是统计学方法非常专业。
比如用它自带的数据https://bioinfomatics.xiantao.love/biotools/data/demo/free/linePlot/%E6%8A%98%E7%BA%BF%E5%9B%BE.xlsx
通过无脑式的鼠标点击,可得到下面一系列的结果。

折线图

可以看到有很多结果,包括各种统计学描述、各种格式的图片,以及一个demo.R

比如统计描述

组别1 组别2 数目 最小值 最大值 中位数(Median) 四分位距(IQR) 下四分位 上四分位 均值(Mean) 标准差(SD) 标准误(SE)
Time1 Control 12 2.833 3.306 2.967 0.254 2.885 3.139 3.020 0.154 0.044
Time1 Intervene 12 2.624 3.418 3.074 0.297 2.876 3.173 3.032 0.258 0.074
Time2 Control 12 2.733 3.240 2.930 0.187 2.861 3.047 2.957 0.148 0.043
Time2 Intervene 12 3.419 4.318 4.082 0.388 3.824 4.212 4.005 0.285 0.082
Time3 Control 12 2.611 3.414 2.938 0.392 2.805 3.197 2.979 0.246 0.071
Time3 Intervene 12 5.799 6.285 6.065 0.185 5.916 6.101 6.030 0.139 0.040

又比如异常值分析、正态性检验(Shapiro-Wilk normality test)、方差齐性检验(Levene's test)、协方差同质假设(Homogeneity of covariances assumption/Box’s M-test)、球形假设(Mauchly's Test for Sphericity)、两因素单向重复测量数据方差分析(Two-way mixed ANOVA)、单独效应分析(Simple effect)、多重成对比较(Pairwise Comparisons of Estimated Marginal Means)等等专业术语,并且还给了详细的统计学结果。


image.png
image.png
image.png

这种统计学结果让大家很欣慰,那么这些结果都是如何计算出来的呢???


我们可以点开demo.R这个结果,读一读代码
https://bioinfomatics.xiantao.love/biotools/code/open/lineplot.R

现在我们复现一下:

加载需要的包并导入数据

library(ggplot2)
library(reshape2)
library(car)
library(rstatix)
## 导入数据,比如我们把下载的折线图数据保存在桌面
library(readxl)
data <- read_excel("~/Desktop/折线图.xlsx") ## mac系统代码
data # 显示结果
trt Time1 Time2 Time3
Control 3.185968 2.875802 3.414224
Control 2.832632 2.862111 2.801333
Control 3.123533 2.984142 2.909648
Control 2.880927 3.146924 3.256431
Control 3.090936 2.732620 2.966887
Control 2.920949 2.865287 2.820161
Control 3.306013 2.856390 2.806807
Control 2.885842 3.002480 2.611145
Control 2.955919 3.239596 3.182478
Control 2.978572 2.818567 2.734901
Control 3.190647 3.042065 3.001664
Control 2.883867 3.063226 3.240626
Intervene 2.623973 3.771982 6.041055
Intervene 2.663926 3.841685 6.098856
Intervene 3.045286 4.301342 6.108293
Intervene 3.054712 4.065593 6.085687
Intervene 3.127857 4.097633 6.055522
Intervene 3.147686 4.134947 5.926182
Intervene 3.248095 3.419161 5.855298
Intervene 3.326086 4.182629 5.885426
Intervene 3.093890 4.318014 6.151859
Intervene 3.418347 4.303615 6.284906
Intervene 2.935396 3.986879 5.798966
Intervene 2.697790 3.640084 6.073529

新增一列id,id即为数字,用于后续分析,必不可少

data$id <- 1:nrow(data)
trt Time1 Time2 Time3 id
Control 3.185968 2.875802 3.414224 1
Control 2.832632 2.862111 2.801333 2
Control 3.123533 2.984142 2.909648 3
Control 2.880927 3.146924 3.256431 4
Control 3.090936 2.732620 2.966887 5
Control 2.920949 2.865287 2.820161 6
Control 3.306013 2.856390 2.806807 7
Control 2.885842 3.002480 2.611145 8
Control 2.955919 3.239596 3.182478 9
Control 2.978572 2.818567 2.734901 10
Control 3.190647 3.042065 3.001664 11
Control 2.883867 3.063226 3.240626 12
Intervene 2.623973 3.771982 6.041055 13
Intervene 2.663926 3.841685 6.098856 14
Intervene 3.045286 4.301342 6.108293 15
Intervene 3.054712 4.065593 6.085687 16
Intervene 3.127857 4.097633 6.055522 17
Intervene 3.147686 4.134947 5.926182 18
Intervene 3.248095 3.419161 5.855298 19
Intervene 3.326086 4.182629 5.885426 20
Intervene 3.093890 4.318014 6.151859 21
Intervene 3.418347 4.303615 6.284906 22
Intervene 2.935396 3.986879 5.798966 23
Intervene 2.697790 3.640084 6.073529 24

将短数据转换为长数据

data2 <- gather(data, key = "x", value = "value", -trt, -id)

对各组进行统计学描述

data3 <- data2 %>% 
  group_by(trt, x) %>% 
  get_summary_stats(value)
trt x variable n min max median q1 q3 iqr mad mean sd se ci
Control Time1 value 12 2.833 3.306 2.967 2.885 3.139 0.254 0.156 3.020 0.154 0.044 0.098
Control Time2 value 12 2.733 3.240 2.930 2.861 3.047 0.187 0.137 2.957 0.148 0.043 0.094
Control Time3 value 12 2.611 3.414 2.938 2.805 3.197 0.392 0.252 2.979 0.246 0.071 0.156
Intervene Time1 value 12 2.624 3.418 3.074 2.876 3.173 0.297 0.232 3.032 0.258 0.074 0.164
Intervene Time2 value 12 3.419 4.318 4.082 3.824 4.212 0.388 0.327 4.005 0.285 0.082 0.181
Intervene Time3 value 12 5.799 6.285 6.065 5.916 6.101 0.185 0.097 6.030 0.139 0.040 0.088

批量运行正态性检验(Shapiro-Wilk normality test)

for(i in unique(data[,1])){
  data1 <- data[data[,1] == i,]
  print(lapply(data1[,-1], function(x) shapiro.test(x)))
}

$Time1

Shapiro-Wilk normality test

data: x

W = 0.91913, p-value = 0.2788

$Time2

Shapiro-Wilk normality test

data: x

W = 0.88011, p-value = 0.08792

$Time3

Shapiro-Wilk normality test

data: x

W = 0.73897, p-value = 0.002055

$id

Shapiro-Wilk normality test

data: x

W = 0.95933, p-value = 0.7742

批量运行方差齐性检验(Levene's Test)

for(i in unique(data2$x)){
  data1 <- data2[data2$x == i,]
  print(leveneTest(value~trt, data = data1))
}

Levene's Test for Homogeneity of Variance (center = median)
Df F value Pr(>F)
group 1 1.5617 0.2245
22
Levene's Test for Homogeneity of Variance (center = median)
Df F value Pr(>F)
group 1 2.5864 0.122
22
Levene's Test for Homogeneity of Variance (center = median)
Df F value Pr(>F)
group 1 3.8375 0.06291 .
22


Signif. codes: 0 ‘’ 0.001 ‘’ 0.01 ‘’ 0.05 ‘.’ 0.1 ‘ ’ 1

两因素重复测量方差分析

anova_test(data = data2, dv = value, wid = id, within = x, between = trt) 

ANOVA Table (type II tests)

$ANOVA
Effect DFn DFd F p p<.05 ges
1 trt 1 22 510.657 1.02e-16 * 0.918
2 x 2 44 391.826 9.19e-29 * 0.902
3 trt:x 2 44 407.706 4.01e-29 * 0.905

$Mauchly's Test for Sphericity
Effect W p p<.05
1 x 0.966 0.699
2 trt:x 0.966 0.699

$Sphericity Corrections
Effect GGe DF[GG] p[GG] p[GG]<.05 HFe DF[HF] p[HF] p[HF]<.05
1 x 0.968 1.94, 42.57 6.65e-28 * 1.059 2.12, 46.61 9.19e-29 *
2 trt:x 0.968 1.94, 42.57 2.98e-28 * 1.059 2.12, 46.61 4.01e-29 *

可视化结果

ggplot(data = data3, aes(x = x, y = mean, color = trt, group = trt)) +
  geom_errorbar(aes(ymin=mean-sd, ymax=mean+sd), color = "black", width = 0.2) +
  geom_line() +
  geom_point() +
  theme_bw()

image.png

当然这个图跟原图不一样,并且没有两两比较,我们可以使用ggpubrrstatix进行二次绘图。

关于rstatix进行统计学分析,其实可以Repeated Measures ANOVA in R: The Ultimate Guide - Datanovia
得到答案,具体的分析,我们暂不说了,只说如何进行统计学分析,并且自动两两比较

res.aov <- anova_test(data = data2, dv = value, wid = id, within = x, between = trt) 
# 组间两两比较
pwc <- data2 %>%
    group_by(x) %>%
    pairwise_t_test(
        value ~ trt, paired = TRUE,
        p.adjust.method = "bonferroni" ## 校正方法,包括 "holm", "hochberg", "hommel", "bonferroni", "BH", "BY", "fdr", "none".等
    )
pwc
x .y. group1 group2 n1 n2 statistic df p p.adj p.adj.signif
Time1 value Control Intervene 12 12 -0.1453235 11 8.87e-01 8.87e-01 ns
Time2 value Control Intervene 12 12 -12.3908123 11 1.00e-07 1.00e-07 ****
Time3 value Control Intervene 12 12 -40.9352857 11 0.00e+00 0.00e+00 ****

可以看到已经自动进行了两两比较,我们使用rstatix包的add_xy_position()函数可以添加两两比较列表和x轴y轴位置。

 pwc <- pwc %>% add_xy_position(x = "x")# 按时间分列
pwc
x .y. group1 group2 n1 n2 statistic df p p.adj p.adj.signif y.position groups xmin xmax
1 value Control Intervene 12 12 -0.1453235 11 8.87e-01 8.87e-01 ns 3.7834 Control , Intervene 0.8 1.2
2 value Control Intervene 12 12 -12.3908123 11 1.00e-07 1.00e-07 **** 4.6834 Control , Intervene 1.8 2.2
3 value Control Intervene 12 12 -40.9352857 11 0.00e+00 0.00e+00 **** 6.6504 Control , Intervene 2.8 3.2

可视化绘图

library(ggpubr)
ggline(data2,x='x',y='value',
color = 'trt', #按组配色
add = 'mean_sd', #添加均数标准差,也可以设置均数标准误,CI等。
palette = "aaas" # aaas杂志配色
)+stat_pvalue_manual(pwc, tip.length = 0, hide.ns = TRUE) + # 添加两两比较,隐藏无意义
    labs(
        subtitle = get_test_label(res.aov, detailed = TRUE), # 添加整体差异
        caption = get_pwc_label(pwc) # 右下角条件两两比较方法。
    )
image.png

当然,我们还可以继续修改图片,比如全部显示结果,取消显著性标记的下划线,或者显示具体的p值等

ggline(data2,x='x',y='value',
       color = 'trt', #按组配色
       add = 'mean_sd', #添加均数标准差,也可以设置均数标准误,CI等。
       palette = "aaas",# aaas杂志配色
ggtheme = theme_bw(), #背景
xlab = F,ylab = "Score", #xy轴名称
legend.title="Treatment" ,legend="top", #标签名称和位置
title = "Comparison of two groups at different times" #标题
)+stat_pvalue_manual(pwc, bracket.size = 0) + # 添加两两比较,显示所有结果
    labs(
        subtitle = get_test_label(res.aov, detailed = TRUE), # 添加整体差异
        caption = get_pwc_label(pwc) # 右下角显示事后两两比较方法。
    )
image.png

也可以显示数值

ggline(data2,x='x',y='value',
       color = 'trt', #按组配色
       add = 'mean_sd', #添加均数标准差,也可以设置均数标准误,CI等。
       palette = "aaas",# aaas杂志配色#背景
       xlab = F,ylab = "Score", #xy轴名称
       legend.title="Treatment" ,legend="right",
       title = "Comparison of two groups at different times" #标题
)+stat_pvalue_manual(pwc, bracket.size = 0,label = "p.adj") + # 添加两两比较,显示所有结果
    labs(
        subtitle = get_test_label(res.aov, detailed = TRUE), # 添加整体差异
        caption = get_pwc_label(pwc) # 右下角显示事后两两比较方法。
    )
image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,830评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,992评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,875评论 0 331
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,837评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,734评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,091评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,550评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,217评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,368评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,298评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,350评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,027评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,623评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,706评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,940评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,349评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,936评论 2 341

推荐阅读更多精彩内容

  • 转自个人微信公粽号【易学统计】的统计学习笔记:R语言:两因素重复测量方差分析[https://mp.weixin....
    小易学统计阅读 4,004评论 0 13
  • 两个总体间的差异如何比较?研究样本,通过研究样本来分析总体。实际上,所研究的总体往往是无限总体,总体的参数是无法用...
    灵动的小猪阅读 7,979评论 0 7
  • 比较两个及两个以上样本的均值差异 方差分析前提 独立性:样本须是相互独立的随机样本 正态性 :样本来自正态分布总体...
    吴十三和小可爱的札记阅读 2,702评论 0 8
  • 方差分析的基本思想及应用条件 方差分析的基本思想 在进行科学研究时,有时要按实验设计将所研究的对象分为多个处理组进...
    backup备份阅读 7,433评论 0 10
  • 目录 前言 为什么不能两两比较? 1方差分析(ANOVA)原理2.2方差分析(ANOVA)需满足条件 实例讲解3....
    Z_bioinfo阅读 4,412评论 1 17