学会数据集合upset作图,从零开始。
其实,虽然我已经上了10次线下课,但是这种表现多个数据交集的图,一直都不会画。

最主要的原因就是,从来没有这个需求。但是今天我突发奇想,想要学习一下。我要连续更新六个月,那么有很多不想学的技能也会慢慢学会。
因为我现在不会,所以以下是我学习的过程。我将展示如何从零开始,学会这个图的绘制。
我在微信,google 检索了以"upset 集合 R"检索,
https://weixin.sogou.com/
浏览了一些帖子,发现有一个叫UpsetR
的R包可以实现,还有一个基于ggplot2的图层可以实现,他包含在ggupset
这个包里面。

此外,我常常看Y叔的公众号,也把他写过的相关帖子翻了出来阅读。
一图告诉你venn plot和upset plot的关系
转UpSet图为ggplot?
ggupset -- ggplot2版本的upset plot
有两种画法的时候,我会首先基于ggplot2的画法,因为后期可以添油加醋的活实在太多了。
1.找到ggupset
的官方教程
https://github.com/const-ae/ggupset

2.运行教程中的例子,复现原图
library(ggupset)
library(dplyr)
library(ggplot2)
tidy_movies %>%
distinct(title, year, length, .keep_all=TRUE) %>%
ggplot(aes(x=Genres)) +
geom_bar() +
scale_x_upset(n_intersections = 20)

3.了解该包需要的数据格式
获取出图前的数据,并查看
dd1 <- tidy_movies %>%
distinct(title, year, length, .keep_all=TRUE)

最终发现,他需要的数据是个数据框,而且箭头那一列属于列表,这个是用
class
函数看出来的。列表的内容最终变成了这个图的横坐标,是个分类变量。
4. 调整自己的数据变成那个格式
我想了想,自己有什么数据能用来展示呢?目前只有通路富集后的基因了。
load(file = "gene_pathway_membership.rda")
这个数据之前出现过,是个矩阵,而且是个逻辑矩阵。行名是通路富集的条目,列名是基因名称,TRUE
代表这一列的基因在行对应的通路中。

理解了所需要的数据格式后,我做了如下操作
library(tibble)
library(tidyr)
library(dplyr)
## 调整数据格式
tidydata <- gene_pathway_membership %>%
as.data.frame() %>%
rownames_to_column("Pathway") %>%
gather(Gene, Member, -Pathway) %>%
filter(Member=="TRUE") %>%
select(- Member) %>%
group_by(Gene) %>%
summarize(Pathways = list(Pathway))

第一列是基因,第二列是列表,里面都是将来能用的很坐标,理解上面的代码,需要一行行拆解(请自行完成),用到的了gather,用到了之前讲到的
group_by
联合summarize
。
5.用调整好的数据画图
数据调整好了,画图是最简单的。
ggplot(tidydata,aes(x = Pathways)) +
geom_bar() +
scale_x_upset()

此时,我想尝试以另外一个R包UpsetR
, 发现他需要的数据很直观:
他需要一个数据框,列名代表很坐标,行代表包含的内容,数据框内用0或者1代表包含关系。
我们用例子来说话,还是刚才的数据

现在要把逻辑矩阵变成数值矩阵,我们之前讲过,这里最简单的方法是乘以1
dd2 <- gene_pathway_membership*1

然后调整数据格式,实际上就是转置。
library(dplyr)
dd2 <- dd2 %>%
t() %>%
as.data.frame()

有了合适的数据,画图就是无脑操作。
UpSetR::upset(dd2,sets = colnames(dd2), keep.order = TRUE)

那现在的问题是,明显第二种方法要简单的得多啊,为什么要用第一种方法,因为第一种方法跟ggplot2兼容性比较好,可以作出很多变换,比如:


而且按照Y叔帖子里面说的,这时候还可以方便地把韦恩图嵌套进去。我们测试一下
先画upse图
p1 <- ggplot(tidydata,aes(x = Pathways)) +
geom_bar() +
theme_bw() +
theme(panel.border = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.line = element_line(colour = "black"))+
scale_x_upset()

再画韦恩图
用得是yyplot里面得ggvenn
函数,该函数的输入数据跟UpSetR::upset
数据要求一样。
library(yyplot)
p2 <- yyplot::ggvenn(dd2)+
theme_void()+
theme(legend.position = "none")

图中嵌图
使用的是Y叔的ggimage
R包。
library(ggimage)
p3 <- as.ggplot(p1) + geom_subview(subview = p2, x=.8, y=.75, w=.5, h=.5)

这样,我们就从零开始学会了一个upset作图。不过还有个疑问,其实我们手上也没有这种形式的数据啊?

这是由富集结果转换过来的。如何转换其实不是很难,我们下次碰到了真实数据再来搞。
我是果子,明天见,而且明天还有大事发生。