欢迎光临散文网 会员登陆 & 注册

优雅地复现R统计图:从「梵婀玲」图(violin plot)开始

2023-08-03 11:25 作者:杭州猿通信息科技  | 我要投稿

作者:狐贝贝

        ANOVA(方差分析)或Kruskal-Wallis H秩和检验是统计学中用于检验两个或多个样本均值/中位数之间是否存在显著差异的常用算法。

        在统计学的学习资料或论文当中,我们经常能看到如下图所示ANOVA分析或Kruskal-Wallis秩和检验的小提琴图。

         小提琴图清楚地展示了各组的数据分布,ANOVA分析或Kruskal-Wallis秩和检验的结果,以及两两组间比较的显著性。

图1

对于复现这样一张简单的统计图,同学们是不是摩拳擦掌,跃跃欲试呢?

       下面,小猿团队的小狐带您一步步使用R语言的ggplot函数或统计猿在线工具实现Kruskal-Wallis秩和检验及数据的可视化。本讲内容包括数据准备与整理、Kruskal-Wallis秩和检验和事后多重比较检验。

 在学习教程之前,请同学们自行完成R语言GUI和RStudio两个软件的安装。

未安装“ggplot2”等R包的同学请先通过install.packages("包的名字")自行安装。

Step 1:构造模拟数据

首先我们用runif函数构造了5组模拟数据,每组10个随机数。runif函数可以生成指定范围内的均匀分布随机数。

library(tidyverse)

library(ggpubr)

library(ggsignif)

library(rstatix)


#随机数生成每次会有所不同

data <- data.frame(

  TIME_IA = runif(10, min = 0.05, max = 0.4),

  TIME_ISM = runif(10, min = -0.2, max = 0.1),

  TIME_ISS = runif(10, min = 0.1, max = 0.5),

  TIME_IE = runif(10, min = -0.25, max = 0.2),

  TIME_IR = runif(10, min = 0.2, max = 0.6)

)


Step 2:宽数据转变为长数据,以及保存数据

通过pivot_longer函数将宽格式的数据转换为长格式。长格式更方便进行分组分析。

由于代码生成的数据具有随机性,每次都不一样,同学们可以保存数据,下次直接读取数据。

data_long <- pivot_longer(data, cols = everything(),

                          names_to = "group", values_to = "Score") %>%

  as.data.frame()

#保存数据

write.csv(data_long,"data_long.csv")

 

#读取数据

data_long=read.csv("data_long.csv")

#数据进行因子化

data_long$group <- factor(data_long$group, levels = colnames(data))

 

Step 3:Kruskal-Wallis秩和检验

 

使用kruskal_test进行Kruskal-Wallis秩和检验。p值小于0.05,说明至少有两组之间存在显著差异,但具体是哪两组需要进行事后多重比较。

kw_test <- data_long %>%

  kruskal_test(Score ~ group)

kw_test

Step 4:事后多重比较检验

采用dunn_test(Dunn’s test)进行事后多重比较,并用bonferroni方法控制整体型I错误。标注出了不同组间的显著性差异。

stat.test <- data_long %>%

  dunn_test(

    Score ~ group,

p.adjust.method = "Bonferroni

"

  )%>%

  add_significance("p.adj", #根据校正后的p value换算显著性符号

#对于显著性符号,小编一般只用到以下几个层级(做多3个星号,默认最多是4个星号)

                   cutpoints = c(0, 0.001, 0.01, 0.05, 1),

                   symbols = c("***", "**", "*", "ns"))

  

Step 5:绘制小提琴图及添加显著性符号

核密度图、散点图、箱线图共同构成了小提琴图,直观展示了不同组的分布情况。

此外,添加了统计检验的显著性标记。

 

#使用ggsci包生成5个《自然》期刊颜色

library("scales")

library(ggsci)

 

show_col(pal_npg("nrc")(nlevels(data_long$group)))

 

colors=pal_npg("nrc")(nlevels(data_long$group))

colors_a=pal_npg(palette = c("nrc"), alpha = 0.6)(nlevels(data_long$group))

 

#写作图的主题

#喜欢拐角(GraphPad Prism)风格的主题用这个

prism=  theme_classic()+

  theme(

    legend.position = "none",

    #tick深灰色

    axis.ticks = element_line(color="grey20"),

    axis.title.x=element_text(size = 8,color="black",face="bold"),

    axis.title.y=element_text(size = 8,color="black",face="bold"),

    legend.title = element_text(size = 8,color="black",face="bold"),

    axis.text.x=element_text(

      angle = 45, #横坐标旋转45°

      hjust = 1,

      vjust=1,

      size = 8,color="black",

      margin=unit(c(0.2,0.2,0.2,0.2), "cm")),

    axis.text.y = element_text(

     

      size = 8,color="black",

      margin=unit(c(0.2,0.2,0.2,0.2), "cm")),

    legend.text = element_text(size = 8,color="black"),

    axis.ticks.length=unit(0.2, "cm")#tick长度

  )

 

#喜欢完整包围起来风格的主题用这个

bw=theme_bw()+

  theme(

    legend.position = "none",

    #去掉网格线

    panel.grid = element_blank(),

    #tick深灰色

    axis.ticks = element_line(color="grey20"),

    axis.title.x=element_text(size = 8,color="black",face="bold"),

    axis.title.y=element_text(size = 8,color="black",face="bold"),

    legend.title = element_text(size = 8,color="black",face="bold"),

    axis.text.x=element_text(

      angle = 45, #横坐标旋转45°

      hjust = 1,

      vjust=1,

      size = 8,color="black",

      margin=unit(c(0.2,0.2,0.2,0.2), "cm")),

    axis.text.y = element_text(

     

      size = 8,color="black",

      margin=unit(c(0.2,0.2,0.2,0.2), "cm")),

    legend.text = element_text(size = 8,color="black"),

    axis.ticks.length=unit(0.2, "cm")#tick长度

  )

 

#先绘制图像

p <- ggplot()+

  #核密度图:

  geom_violin(data=data_long,aes(group, Score, color = group, fill = group), width = 0.75)+

    # 箱线图:

  geom_boxplot(data=data_long,aes(group, Score, color = group), width = 0.2)+

  # 抖动散点:

  geom_jitter(data=data_long,aes(group, Score, color = group), width = 0.05)+

 

  #添加KW检验结果

  geom_text(aes(x=1.5,y=0.6),label=paste0(kw_test$method,", ",

                                        ifelse(kw_test$p<0.001,"p < 0.001",paste0("p = ", sprintf("%.4f", kw_test$p)))))+

  # 颜色模式:

  scale_color_manual(values = colors )+

  scale_fill_manual(values = colors_a )+

    scale_y_continuous(limits = c(-0.3,0.62),breaks=seq(-0.3,0.6,0.15))+

  xlab("Group")+

  # 主题

  bw

p

图2

# 根据显著性检验结果,添加显著性标记:

x_value <- rep(1:4, 4:1)

y_value <- rep(apply(data, 2, max)[1:4], 4:1) + 0.01

y_value <- y_value + c(0.03*1:4, 0.03*1:3, 0.03*1:2, 0.03)

color_value <- c(colors[2:5], colors[3:5], colors[4:5], colors[5])

 

for (i in 1:nrow(stat.test)) {

  if (stat.test$p.adj.signif[i] != "ns") {

    y_tmp <- y_value[i]

    p <- p+annotate(geom = "text",

                    label = stat.test$p.adj.signif[i],

                    x = x_value[i],

                    y = y_tmp,

                    color = color_value[i])

  }

}

 

p

通过for循环添加了显著性符号,完成小提琴图的绘制。

图3

使用for循环算法,完成显著性符号的添加。通过显著性符号的颜色,即可判断出是与哪一组数据进行比较。

例如,TIME_IA列上方的显著性符号*为靛青色,说明经校正假阳性的dunn’s检验反映出,TIME_IA组显著高于(高低是主要是基于中位数的判断)TIME_IE组。

 

Step 6: 将图片保存文件

保存为矢量图格式,后续可进行字体、字号、线条粗细等细节的调整。

ggsave("single_plot.pdf", height = 4, width = 4)

ggsave("single_plot.svg", height = 4, width = 4)

图4

通过显著性符号的颜色,即可判断出是与哪一组数据进行比较。

例如,TIME_IA列上方的显著性符号*为靛青色,说明经校正假阳性的dunn’s检验反映出,TIME_IA组显著高于(高低是主要是基于中位数的判断)TIME_IE组。

 

Step 7: 将图片保存文件

保存为矢量图格式,后续可进行字体、字号、线条粗心等细节的调整。

ggsave("single_plot.pdf", height = 4, width = 4)

ggsave("single_plot.svg", height = 4, width = 4)


如果认为写代码比较困难,我们还可以再尝试用统计猿软件实现统计图的复现。

打开我们的统计猿网站(https://fast.statsape.com/)。


图5   高级制图

选择高级制图。

图6  制图页面

点开小提琴图-多重比较小提琴图。

图7  多重比较小提琴图

选择上传本地数据。还未生成图片之前,左侧看到的小提琴图是样例展示,非真实数据(可观察横坐标)。

图8   上传数据表

点击文件夹图标进行上传数据表(刚刚使用R语言生成的数据)。提示“上传成功”。

图9   数据表上传成功

在右侧设置好各项属性后,包括横坐标、纵坐标、分类变量、配色等。小编作图时,各项参数均与R语言中的参数保持了一致。

点击“开始”,不一会儿便生成了图片。

图10   调整图的各项参数

在本篇教程中,我们实现了Kruskal-Wallis秩和检验分析的完整流程,包括假设检验、可视化展示,对学习统计分析方法很有帮助。同学们在实践中,可替换为自己的数据,进行统计学分析。

优雅地复现R统计图:从「梵婀玲」图(violin plot)开始的评论 (共 条)

分享到微博请遵守国家法律