箱线图
箱线图是能同时反映数据统计量和整体分布,又很漂亮的展示图。在2014年的Nature Method上有2篇Correspondence论述了使用箱线图的好处和一个在线绘制箱线图的工具。就这样都可以发两篇Nature method,没天理,但也说明了箱线图的重要意义。
 
下面这张图展示了Bar plot、Box plot、Volin plot和Bean plot对数据分布的反应。从Bar plot上只能看到数据标准差或标准误不同;Box plot可以看到数据分布的集中性不同;Violin plot和Bean plot展示的是数据真正的分布,尤其是对Biomodal数据的展示。
 
Box plot从下到上展示的是最小值,第一四分位数 (箱子的下边线)、中位数 (箱子中间的线)、第三四分位数 (箱子上边线)、最大值,具体解读看这里扩增子图表解读1箱线图:Alpha多样性

一步步解析箱线图绘制
假设有这么一个基因表达矩阵,第一列为基因名字,后面几列为样品名字,想绘制下样品中基因表达的整体分布。
  1. profile="Name;2cell_1;2cell_2;2cell_3;4cell_1;4cell_2;4cell_3;zygote_1;zygote_2;zygote_3
  2. A;4;6;7;3.2;5.2;5.6;2;4;3
  3. B;6;8;9;5.2;7.2;7.6;4;6;5
  4. C;8;10;11;7.2;9.2;9.6;6;8;7
  5. D;10;12;13;9.2;11.2;11.6;8;10;9
  6. E;12;14;15;11.2;13.2;13.6;10;12;11
  7. F;14;16;17;13.2;15.2;15.6;12;14;13
  8. G;15;17;18;14.2;16.2;16.6;13;15;14
  9. H;16;18;19;15.2;17.2;17.6;14;16;15
  10. I;17;19;20;16.2;18.2;18.6;15;17;16
  11. J;18;20;21;17.2;19.2;19.6;16;18;17
  12. L;19;21;22;18.2;20.2;20.6;17;19;18
  13. M;20;22;23;19.2;21.2;21.6;18;20;19
  14. N;21;23;24;20.2;22.2;22.6;19;21;20
  15. O;22;24;25;21.2;23.2;23.6;20;22;21"
读入数据并转换为ggplot2需要的长数据表格式
  1. profile_text <- read.table(text=profile, header=T, row.names=1, quote="",sep=";", check.names=F)
  2. # 在melt时保留位置信息
  3. # melt格式是ggplot2画图最喜欢的格式
  4. # 好好体会下这个格式,虽然多占用了不少空间,但是确实很方便
  5.  
  6. library(ggplot2)
  7. library(reshape2)
  8. data_m <- melt(profile_text)
  9. head(data_m)
  10. variable value
  11. 1 2cell_1 4
  12. 2 2cell_1 6
  13. 3 2cell_1 8
  14. 4 2cell_1 10
  15. 5 2cell_1 12
  16. 6 2cell_1 14
像往常一样,就可以直接画图了。
  1. # variable和value为矩阵melt后的两列的名字,内部变量, variable代表了点线的属性,value代表对应的值。
  2. p <- ggplot(data_m, aes(x=variable, y=value),color=variable) +
  3. geom_boxplot() +
  4. theme(axis.text.x=element_text(angle=50,hjust=0.5, vjust=0.5)) +
  5. theme(legend.position="none")
  6. p
  7. # 图会存储在当前目录的Rplots.pdf文件中,如果用Rstudio,可以不运行dev.off()
  8. dev.off()
箱线图出来了,看上去还可以,再加点色彩
  1. # variable和value为矩阵melt后的两列的名字,内部变量, variable代表了点线的属性,value代表对应的值。
  2. p <- ggplot(data_m, aes(x=variable, y=value),color=variable) +
  3. geom_boxplot(aes(fill=factor(variable))) +
  4. theme(axis.text.x=element_text(angle=50,hjust=0.5, vjust=0.5)) +
  5. theme(legend.position="none")
  6. p
  7. # 图会存储在当前目录的Rplots.pdf文件中,如果用Rstudio,可以不运行dev.off()
  8. dev.off()
再看看Violin plot
  1. # variable和value为矩阵melt后的两列的名字,内部变量, variable代表了点线的属性,value代表对应的值。
  2. p <- ggplot(data_m, aes(x=variable, y=value),color=variable) +
  3. geom_violin(aes(fill=factor(variable))) +
  4. theme(axis.text.x=element_text(angle=50,hjust=0.5, vjust=0.5)) +
  5. theme(legend.position="none")
  6. p
  7. # 图会存储在当前目录的Rplots.pdf文件中,如果用Rstudio,可以不运行dev.off()
  8. dev.off()
还有Jitter plot (这里使用的是ggbeeswarm包)
  1. library(ggbeeswarm)
  2. # 为了更好的效果,只保留其中一个样品的数据
  3. # grepl类似于Linux的grep命令,获取特定模式的字符串
  4. data_m2 <- data_m[grepl("_3", data_m$variable),]
  5.  
  6. # variable和value为矩阵melt后的两列的名字,内部变量, variable代表了点线的属性,value代表对应的值。
  7. p <- ggplot(data_m2, aes(x=variable, y=value),color=variable) +
  8. geom_quasirandom(aes(colour=factor(variable))) +
  9. theme_bw() + theme(panel.grid.major = element_blank(),
  10. panel.grid.minor = element_blank(), legend.key=element_blank()) +
  11. theme(legend.position="none")
  12. # 也可以用geom_jitter(aes(colour=factor(variable)))代替geom_quasirandom(aes(colour=factor(variable)))
  13. # 但个人认为geom_quasirandom给出的结果更有特色
  14.  
  15. ggsave(p, filename="jitterplot.pdf", width=14, height=8, units=c("cm"))
绘制单个基因 (A)的箱线图
为了更好的展示效果,下面的矩阵增加了样品数量和样品的分组信息。
  1. profile="Name;2cell_1;2cell_2;2cell_3;2cell_4;2cell_5;2cell_6;4cell_1;4cell_2;4cell_3;4cell_4;4cell_5;4cell_6;zygote_1;zygote_2;zygote_3;zygote_4;zygote_5;zygote_6
  2. A;4;6;7;5;8;6;3.2;5.2;5.6;3.6;7.6;4.8;2;4;3;2;4;2.5
  3. B;6;8;9;7;10;8;5.2;7.2;7.6;5.6;9.6;6.8;4;6;5;4;6;4.5"
  4.  
  5. profile_text <- read.table(text=profile, header=T, row.names=1, quote="",sep=";", check.names=F)
  6.  
  7. data_m = data.frame(t(profile_text['A',]))
  8. data_m$sample = rownames(data_m)
  9. # 只挑选显示部分
  10. # grepl前面已经讲过用于匹配
  11. data_m[grepl('_[123]', data_m$sample),]
获得样品分组信息 (这个例子比较特殊,样品的分组信息就是样品名字下划线前面的部分)
  1. # 可以利用strsplit分割,取出其前面的字符串
  2. # R中复杂的输出结果多数以列表的形式体现,在之前的矩阵操作教程中
  3. # 提到过用str函数来查看复杂结果的结构,并从中获取信息
  4. group = unlist(lapply(strsplit(data_m$sample,"_"), function(x) x[1]))
  5. data_m$group = group
  6. data_m[grepl('_[123]', data_m$sample),]

如果没有这个规律,也可以提到类似于下面的文件,指定样品所属的组的信息。

  1. sampleGroup_text="Sample;Group
  2. zygote_1;zygote
  3. zygote_2;zygote
  4. zygote_3;zygote
  5. zygote_4;zygote
  6. zygote_5;zygote
  7. zygote_6;zygote
  8. 2cell_1;2cell
  9. 2cell_2;2cell
  10. 2cell_3;2cell
  11. 2cell_4;2cell
  12. 2cell_5;2cell
  13. 2cell_6;2cell
  14. 4cell_1;4cell
  15. 4cell_2;4cell
  16. 4cell_3;4cell
  17. 4cell_4;4cell
  18. 4cell_5;4cell
  19. 4cell_6;4cell"
  20.  
  21. #sampleGroup = read.table(text=sampleGroup_text,sep="\t",header=1,check.names=F,row.names=1)
  22. #data_m <- merge(data_m, sampleGroup, by="row.names")
  23. # 会获得相同的结果,脚本注释掉了以免重复执行引起问题

矩阵准备好了,开始画图了 (小提琴图做例子,其它类似)

  1. # 调整下样品出现的顺序
  2. data_m$group <- factor(data_m$group, levels=c("zygote","2cell","4cell"))
  3. # group和A为矩阵中两列的名字,group代表了值的属性,A代表基因A对应的表达值。
  4. # 注意看修改了的地方
  5. p <- ggplot(data_m, aes(x=group, y=A),color=group) +
  6. geom_violin(aes(fill=factor(group))) +
  7. theme(axis.text.x=element_text(angle=50,hjust=0.5, vjust=0.5)) +
  8. theme(legend.position="none")
  9. p
  10. # 图会存储在当前目录的Rplots.pdf文件中,如果用Rstudio,可以不运行dev.off()
长矩阵绘制箱线图
常规矩阵绘制箱线图要求必须是个方正的矩阵输入,而有时想比较的几个组里面检测的值数目不同。比如有三个组,GrpA组检测了6个病人,GrpB组检测了10个病人,GrpC组是12个正常人的检测数据。这时就很难形成一个行位检测值,列为样品的矩阵,长表格模式就适合与这种情况。
  1. long_table <- "Grp;Value
  2. GrpA;10
  3. GrpA;11
  4. GrpA;12
  5. GrpB;5
  6. GrpB;4
  7. GrpB;3
  8. GrpB;2
  9. GrpC;2
  10. GrpC;3"
  11.  
  12. long_table <- read.table(text=long_table,sep="\t",header=1,check.names=F)
  13.  
  14. p <- ggplot(long_table, aes(x=Grp, y=Value),color=Grp) +
  15. geom_violin(aes(fill=factor(Grp))) +
  16. theme(axis.text.x=element_text(angle=50,hjust=0.5, vjust=0.5)) +
  17. theme(legend.position="none")
  18. p
长表格形式自身就是常规矩阵melt后的格式,这种用来绘制箱线图就很简单了,就不做解释了。

R语言学习 - 箱线图(小提琴图、抖动图、区域散点图)的更多相关文章

  1. R语言学习 第四篇:函数和流程控制

    变量用于临时存储数据,而函数用于操作数据,实现代码的重复使用.在R中,函数只是另一种数据类型的变量,可以被分配,操作,甚至把函数作为参数传递给其他函数.分支控制和循环控制,和通用编程语言的风格很相似, ...

  2. R语言学习笔记:基础知识

    1.数据分析金字塔 2.[文件]-[改变工作目录] 3.[程序包]-[设定CRAN镜像] [程序包]-[安装程序包] 4.向量 c() 例:x=c(2,5,8,3,5,9) 例:x=c(1:100) ...

  3. R语言学习笔记:分析学生的考试成绩

    孩子上初中时拿到过全年级一次考试所有科目的考试成绩表,正好可以用于R语言的统计分析学习.为了不泄漏孩子的姓名,就用学号代替了,感兴趣可以下载测试数据进行练习. num class chn math e ...

  4. R语言学习2:绘图

    本系列是一个新的系列,在此系列中,我将和大家共同学习R语言.由于我对R语言的了解也甚少,所以本系列更多以一个学习者的视角来完成. 参考教材:<R语言实战>第二版(Robert I.Kaba ...

  5. R语言学习笔记(二)

    今天主要学习了两个统计学的基本概念:峰度和偏度,并且用R语言来描述. > vars<-c("mpg","hp","wt") &g ...

  6. R语言学习笔记(数据预处理)

    setwd("d:/r/r-data/")data=read.table("salary.txt",header=T)attach(data)mean(Sala ...

  7. R语言学习路线和常用数据挖掘包(转)

    对于初学R语言的人,最常见的方式是:遇到不会的地方,就跑到论坛上吼一嗓子,然后欣然or悲伤的离去,一直到遇到下一个问题再回来.当然,这不是最好的学习方式,最好的方式是——看书.目前,市面上介绍R语言的 ...

  8. R语言学习笔记︱Echarts与R的可视化包——地区地图

    笔者寄语:感谢CDA DSC训练营周末上完课,常老师.曾柯老师加了小课,讲了echart与R结合的函数包recharts的一些基本用法.通过对比谢益辉老师GitHub的说明文档,曾柯老师极大地简化了一 ...

  9. 【R语言学习】时间序列

    时序分析会用到的函数 函数 程序包 用途 ts() stats 生成时序对象 plot() graphics 画出时间序列的折线图 start() stats 返回时间序列的开始时间 end() st ...

随机推荐

  1. 【CERC2008】【BZOJ4319】Suffix reconstruction

    Description 话说练习后缀数组时,小C 刷遍 poj 后缀数组题. 各类字符串题闻之丧胆.就在准备对敌方武将发出连环杀时,对方一记无中生有,又一招顺 手牵羊.小C 程序中的原字符数组就被牵走 ...

  2. Angular Scope解析与应用

    Scope层级结构 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA== ...

  3. 在Android程序中使用已有的SQLite数据库

    已经将这篇文章迁移至 Code问答,你也能够到这里查看这篇文章,请多多关注我的新技术博客CodeWenDa.com 在中文搜索中,没有找到一篇比較好的关于怎样在Android应用中使用自己事先创建好的 ...

  4. Android基础新手教程——4.1.1 Activity初学乍练

    Android基础新手教程--4.1.1 Activity初学乍练 标签(空格分隔): Android基础新手教程 本节引言: 本节開始解说Android的四大组件之中的一个的Activity(活动) ...

  5. MySQL-导入与导出

    CSV文件导入MySQL LOAD DATA INFILE语句允许您从文本文件读取数据,并将文件的数据快速导入数据库的表中. 导入文件操作之前,需要准备以下内容: 一.将要导入文件的数据对应的数据库表 ...

  6. iOS开发——高级篇——Runtime实际应用

    前言 本篇主要介绍Runtime在开发中的一些使用场景,顺便讲解了下MJExtension的底层实现 一.runtime简介 RunTime简称运行时.OC就是运行时机制,也就是在运行时候的一些机制, ...

  7. BZOJ 1055 区间DP

    1055: [HAOI2008]玩具取名 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1144  Solved: 668[Submit][Statu ...

  8. 谈谈C++私有继承

    很多C++程序猿从来没用过私有继承来设计他的类.的确,假设是本该用私有继承的地方却用了公有继承.对程序的功能的实现并无影响. 但这样的误用是一种错位的描写叙述.会引起阅读者的误解,甚至会引起类的使用者 ...

  9. spring-boot-configuration-processor的作用

    spring默认使用yml中的配置,但有时候要用传统的xml或properties配置,就需要使用spring-boot-configuration-processor了 先引入pom依赖 <d ...

  10. 【杂谈】HTML5到底给了我们什么?迟到的2016年终总结

    其实提笔的时候日期已经到了3月了,不过由于在过去的2016年笔者发生了蛮多的事情,所以还是决定记录一下,那些关于成长的片段. 其实HTML5是在2012年的时候接触的,当时和结果志趣相投的同事,看到了 ...