乱花渐欲迷人眼,偷得浮生半日闲
当我在线下培训别人的时候,我常常问自己一个问题:
教什么才让让学员有真正的收获?
第一个答案,画出漂亮的图。因为,开题需要,结题需要,发文章需要,拿基金需要,这简直就是刚需,最应该让学员学会。但是有困境,不知道他们需要什么图。那就直方图,箱线图,小提琴图,圈图,韦恩图统统教一遍。老师高兴,学生也轻松。
但是,这个想法被我否决了,画图看起来重要,但是初学者最不应该学。初学者需要的是数据,最应该学的是清洗数据的能力。把数据调整到R包需要的格式,调个包,图就出来了。Y叔说过,数据就是图。
我曾经开玩笑的说,不需要任何画图的技能,只要会复制粘贴,也能用R语言画出可以发表的图,现在演示如下:
打开这个网站(http://www.sthda.com/english/),按照图中点击
跳转后下来,我们看到很多五彩斑斓的图,眼睛都要迷失了,喜欢哪个就点开哪个。
箭头所在的那个图,最能让人理解,我们点击进去。往下拉,一直拉到我们一开始看到的那张图。
这一看,上面是代码框,那好办了,我们复制一下。
在进行下一步之前,你最好还得有个称手的R语言环境。
学习R语言,从这一课开始
打开Rstudio,新建一个空的脚本文件
鼠标点击第一行,然后不断点run,一行行运行这段代码,应该就有结果
但是点着点着就报错了,提示“ggboxplot”这个函数找不到,应该是没有加载对应的R包。
我们使用两个问号+ggboxplot的形式找对应的R包,名字就做“ggpubr”
缺什么补什么,那就安装R包,并加载
install.packages("ggpubr")
library(ggpubr)
这时候再来运行刚才复制过来的代码就没问题了。
# Groups that we want to compare
my_comparisons <- list(
c("setosa", "versicolor"), c("versicolor", "virginica"),
c("setosa", "virginica")
)
# Create the box plot. Change colors by groups: Species
# Add jitter points and change the shape by groups
ggboxplot(
iris, x = "Species", y = "Sepal.Length",
color = "Species", palette = c("#00AFBB", "#E7B800", "#FC4E07"),
add = "jitter"
)+
stat_compare_means(comparisons = my_comparisons, method = "t.test")
很轻松地就复原了网页的图,
但是,这个图怎么用到自己的数据上呢?这个用于展示基因在癌和癌旁,或者基因在各个亚型中的表达应该是没有问题的。
我们加载公众号里常用的那个数据exprSet,这个数据是我自己准备的。
load("TCGA_ggplot.Rda")
这个数据叫清洁数据,行是患者,列是变量,包括,癌和癌旁信息,基因表达等。
我们模仿上图去修改代码。
("LumA", "Normal"),
c("LumB", "Normal"),
c("Her2", "Normal"),
c("Basal", "Normal")
)
library(ggpubr)
ggboxplot(
exprSet, x = "subgroup", y = "ESR1",
color = "subgroup", palette = c("#00AFBB", "#E7B800", "#FC4E07","#A687D8", "#89E4A4"),
add = "jitter"
)+
stat_compare_means(comparisons = my_comparisons, method = "t.test")
很轻松地获取了一张图片。但是有的人有心里癖好,觉得x轴的顺序需要调整。
想要变成这种顺序。
"LumA","LumB","Her2","Basal","Normal"
这个操作可以回到数据本身,我们可以用因子来限定顺序,核心就在因子中的levels 参数。这里的顺序可以任意更改。
exprSet$subgroup <- factor(exprSet$subgroup,levels = c("LumA","LumB","Her2","Basal","Normal"),ordered = F)
此刻我们再来作图
## 测试自己的数据
load(file = "TCGA_ggplot.Rda")
library(ggpubr)
## 这句代码用于改变顺序
exprSet$subgroup <- factor(exprSet$subgroup,levels = c("LumA","LumB","Her2","Basal","Normal"),ordered = F)
my_comparisons <- list(
c("LumA", "Normal"),
c("LumB", "Normal"),
c("Her2", "Normal"),
c("Basal", "Normal")
)
ggboxplot(
exprSet, x = "subgroup", y = "ESR1",
color = "subgroup", palette = c("#00AFBB", "#E7B800", "#FC4E07","#A687D8", "#89E4A4"),
add = "jitter"
)+
stat_compare_means(comparisons = my_comparisons, method = "t.test")
假如,想改一下,p值线条的顺序,最长的在上面,也是可以的,这要去看他的参数,我用问号打开这个函数,阅读了一下文档
?ggboxplot
进过修改后,得到如下代码
ggboxplot(
exprSet, x = "subgroup", y = "ESR1",
color = "subgroup", palette = "jco",
add = "jitter"
)+
stat_compare_means(comparisons = my_comparisons,
label = "p.signif",
label.y = c(23, 22, 21,20),
method = "t.test")
你看,我并没有骗人,初学者不应该学习画图,复制粘贴,偷别人的代码改一改就可以了。
这当然只是在增加学员的信心,给学习做减法。不要学画图,学习清理数据。有了清理数据的能力,才可能有自己的数据,继而拥有属于自己的图,比如,思考一下如何把手上的数据变成清洁数据。
在这个基础上,学习一点绘图技能就可以用ggplot2自己画出这张图来。
## 手工完成
library(ggplot2)
library(ggsignif)
ggplot(exprSet,aes(x=subgroup,y = ESR1)) +
#画出箱线图
geom_boxplot(aes(col=subgroup))+
#画出散点图
geom_jitter(aes(col=subgroup))+
#画出p值
geom_signif(comparisons = my_comparisons,
map_signif_level = TRUE, textsize=5,
y_position=c(22, 21, 20,19))+
#修改主题
theme_bw()+
#去掉框线
theme(panel.border = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.line = element_line(colour = "black"))+
#去掉legend
theme(legend.position='none')
实际上,ggpubr这个包用的就是ggplot2,如果先会了ggplot2,会觉得掌握ggpubr很麻烦,需要重新记忆一套语法,这也是Y叔看不上ggpubr这个包的原因。不过我这里只是为了说明一个事情:
新手不要上来就学习如何画图,清理数据,学会调包才是最重要的事。
当我想清楚了这个事情,我觉得我的课有了灵魂,我不再是仅仅教编程的讲师,我是一名临床医生,一个科研工作者,我要用R语言解决科研中遇到的问题,我就依靠这个想法设计课程。
昨天我收到学员的留言,心里十分高兴
当我以临床医生的角度去思考科研时,大家热衷灌水的模型预测,不再是技术上的数字,而是未来能让患者获益的利器。当我拿到一个技术上十分完美的模型时,我总问自己,如果用在临床,会增加医生对患者的诊断么?会提高医生对患者的治疗么?会改善患者的预后么?如果不能,再好的模型也只是纸上谈兵。
即使我现在都已经开始培训学员了,但是我依然停留在调整数据调用R包的阶段,我对R语言这个世界,没有任何贡献,我没有写过R包,没有写过图层,我仅仅是使用R语言解决自己的科学问题,十分功利。
所以,2019年,我要做点像样的事情。