迄今为止最强大的upset plot R包,没有之一!
关注公众号,发送R语言或Python,获取学习资料!
以下是正文,请看我的表演!🙃
upset plot我们已经介绍了多种画法,包括最流行的UpsetR
,还介绍了使用complexHeatmap
包画upset plot,以及ggupset
包。这些包各有各的特色,基本用法差不多,在一些组合图形方面各有不同,大家可以翻看之前的文章。
今天再介绍一个画upset plot的R包(感觉有点像收集龙珠了),这个包不得了,官方宣传:具有UpsetR
的所有优点,且完全支持ggplot2
语法!
和其他同类型R包的比较
安装
数据集
基础使用
挑选交集
交集选择模式
展示所有集合
添加图形
调整交集条形图(intersection size)
调整标签外观
增加颜色映射
调整高度比例
隐藏intersection size
展示集合比例
使用ggplot2继续调整
和其他同类型R包的比较
UpsetR
:画upset plot的强大工具和先锋,但是不支持ggplot
语法,且很久没更新了;ggupset
:支持ggplot
语法,适合画一些简单的图形;ComplexHeatmap
:不支持ggplot2
,提供超多完整的自定义选项,如果你同时需要画热图,用它!
安装
# 安装一个数据集
install.packages("ggplot2movies")
# 3选1
install.packages('ComplexUpset')
if(!require(devtools)) install.packages("devtools")
devtools::install_github("krassowski/complex-upset")
# conda/mamba安装!
# conda install -c conda-forge r-complexupset
数据集
使用的还是来自IMDB中的电影数据。
library(ggplot2)
library(ComplexUpset)
movies <- as.data.frame(ggplot2movies::movies)
head(movies, 3)
## title year length budget rating votes r1 r2 r3 r4 r5
## 1 $ 1971 121 NA 6.4 348 4.5 4.5 4.5 4.5 14.5
## 2 $1000 a Touchdown 1939 71 NA 6.0 20 0.0 14.5 4.5 24.5 14.5
## 3 $21 a Day Once a Month 1941 7 NA 8.2 5 0.0 0.0 0.0 0.0 0.0
## r6 r7 r8 r9 r10 mpaa Action Animation Comedy Drama Documentary
## 1 24.5 24.5 14.5 4.5 4.5 0 0 1 1 0
## 2 14.5 14.5 4.5 4.5 14.5 0 0 1 0 0
## 3 24.5 0.0 44.5 24.5 24.5 0 1 0 0 0
## Romance Short
## 1 0 0
## 2 0 0
## 3 0 1
第18-24列是电影类型,用0,1矩阵表示的。
genres <- colnames(movies)[18:24]
genres
## [1] "Action" "Animation" "Comedy" "Drama" "Documentary"
## [6] "Romance" "Short"
把mpaa
这一列中的空值变成NA
,然后为了方便演示去掉缺失值:
movies[movies$mpaa == "", "mpaa"] <- NA
movies <- na.omit(movies)
基础使用
最少需要提供2个参数,第一个是你的数据集,需要包含使用0,1矩阵表示的数据,第2个是需要展示的子集的名字。
upset(movies,genres,
name = "genres", # 底部的标签
width_ratio = 0.1 # 左侧图形的宽度
)
挑选交集
提供了3种方式!
可以挑选交集中的元素个数大于/小于某个值的集合展示,默认不包含没被用到的集合,可以使用keep_empty_group = T
包括进来。
神奇的来了,支持拼图!
p1 <- upset(movies, genres, name = "genres",width_ratio = 0.2,
min_size = 10,
wrap = T
) +
ggtitle("Without empty groups (Short dropped)")
p2 <- upset(movies, genres, name = "genres",width_ratio = 0.2,
min_size = 10, # 最少10个
max_size = 100, # 最多100个
wrap = T,
keep_empty_group = T
) +
ggtitle("With empty groups")
p1 + p2
或者使用min_degree/max_degree
参数选择有特定交集个数的集合进行展示:
upset(movies, genres, width_ratio = 0.1,
min_degree = 3
)
或者直接使用n_intersections
参数指定要展示多少交集:
upset(movies, genres, width_ratio = 0.1,
n_intersections = 15
)
交集选择模式
有4种交集选择模式,这4种模式很重要,在后面添加各种图形、映射不同颜色时非常有用,我觉得这部分是这个包的核心,有点难理解,需要结合给出的图形。
exclusive_intersection region: 选定集合的交集,但要去掉选定集合以外的集合中的元素,(简称: distinct), 默认是这一种; inclusive_intersection region: 选定集合的交集 (简称: intersect); exclusive_union region: 选定集合的并集,但要去掉选定集合以外的集合中的元素; inclusive_union region: 选定集合的并集,(简称: union)
下面是一张图,使用3个集合,展示这4种模式:
上面这张图可以使用complexUpset
画出来,只需要提供不同的交集选择模式即可,这也体现了这个包的牛逼之处,不仅可以画upset plot,也可以画传统的韦恩图:
# 先构造一个数据集用于演示
abc_data = create_upset_abc_example()
head(abc_data) # 数据集长这样
## A B C
## 1 TRUE FALSE FALSE
## 2 TRUE FALSE FALSE
## 3 TRUE FALSE FALSE
## 4 TRUE FALSE FALSE
## 5 TRUE FALSE FALSE
## 6 TRUE FALSE FALSE
# 定义一个画韦恩图的函数
abc_venn = (
ggplot(arrange_venn(abc_data)) # 这个函数可以计算韦恩图的坐标!
+ coord_fixed()
+ theme_void()
+ scale_color_venn_mix(abc_data)
)
# 画不同的交集类型
simple_venn = (
abc_venn
+ geom_venn_region(data=abc_data, alpha=0.3)
+ geom_point(aes(x=x, y=y), size=0.75, alpha=0.3)
+ geom_venn_circle(abc_data)
+ geom_venn_label_set(abc_data, aes(label=region), outwards_adjust=2.55)
)
highlight = function(regions) scale_fill_venn_mix(
abc_data, guide='none', highlight=regions, inactive_color='NA'
)
# 拼图
(
(
simple_venn + highlight(c('A-B')) + labs(title='Exclusive intersection of A and B')
| simple_venn + highlight(c('A-B', 'A-B-C')) + labs(title='Inclusive intersection of A and B')
) /
(
simple_venn + highlight(c('A-B', 'A', 'B')) + labs(title='Exclusive union of A and B')
| simple_venn + highlight(c('A-B', 'A-B-C', 'A', 'B', 'A-C', 'B-C')) + labs(title='Inclusive union of A and B')
)
)
上面是4个图形展示4种模式,也可以在同一张图中展示4种模式:
abc_venn = (
ggplot(arrange_venn(abc_data))
+ coord_fixed()
+ theme_void()
+ scale_color_venn_mix(abc_data)
)
(
abc_venn
+ geom_venn_region(data=abc_data, alpha=0.05)
+ geom_point(aes(x=x, y=y, color=region), size=1)
+ geom_venn_circle(abc_data)
+ geom_venn_label_set(abc_data, aes(label=region))
+ geom_venn_label_region(
abc_data, aes(label=size),
outwards_adjust=1.75,
position=position_nudge(y=0.2)
)
+ scale_fill_venn_mix(abc_data, guide='none')
)
上面这种传统传统韦恩图不会画也不要紧,只要记住4种交集选择模型即可,毕竟韦恩图我们有更好的实现方式,不需要用complexUpset
。
只要记住了4种交集选择模式,就可以使用upset plot的方式来呈现了:
# 定义一个函数,可以根据4种交集选择模式画出相应的图形
abc_upset = function(mode) upset(
abc_data, c('A', 'B', 'C'), mode=mode, set_sizes=FALSE,
encode_sets=FALSE,
queries=list(upset_query(intersect=c('A', 'B'), color='orange')),
base_annotations=list(
'Size'=( # 可以看到这里使用了ggplot2语法!
intersection_size(
mode=mode,
mapping=aes(fill=exclusive_intersection),
size=0,
text=list(check_overlap=TRUE)
) +
scale_fill_venn_mix(
data=abc_data,
guide='none',
colors=c('A'='red', 'B'='blue', 'C'='green3')
)
)
)
)
# 使用了类似patchwork的拼图方式
(
(abc_upset('exclusive_intersection') | abc_upset('inclusive_intersection'))
/
(abc_upset('exclusive_union') | abc_upset('inclusive_union'))
)
展示所有集合
展示所有集合对数据集很大时非常耗费内存!只有在模式不是exclusive intersection时才有意义。
upset(
movies, genres,
width_ratio=0.1,
min_size=10,
mode='inclusive_union',
base_annotations=list('Size'=(intersection_size(counts=FALSE, mode='inclusive_union'))),
intersections='all', # 展示所有集合
max_degree=3
)
添加图形
使用annotations
参数添加其他图形。
set.seed(123)
upset(movies,genres,min_size = 10,width_ratio = 0.1,
# 添加图形,提供了3种方法
annotations = list(
# 方法1:使用list,这里我们使用length 这一列数据
"Length" = list(
aes=aes(x=intersection, y=length),
geom=geom_boxplot(na.rm = T)
),
# 方法2:使用ggplot2,这里我们使用 rating 这一列数据
"Rating" = (
ggplot(mapping = aes(y = rating)) + # 默认x=intersection,省略了
geom_violin(alpha=0.5,na.rm = T)+
geom_jitter(aes(color=log10(votes)),na.rm = T)
),
# 方法3:使用内置的 upset_annotate() 函数
"Budget" = upset_annotate("budget",geom_boxplot(na.rm = T))
)
)
对于分类变量,我们可以使用百分比堆积条形图展示不同的比例:
upset(
movies,
genres,
annotations = list(
'MPAA Rating'=(
ggplot(mapping=aes(fill=mpaa))
+ geom_bar(stat='count', position='fill')
+ scale_y_continuous(labels=scales::percent_format())
+ scale_fill_manual(values=c(
'R'='#E41A1C', 'PG'='#377EB8',
'PG-13'='#4DAF4A', 'NC-17'='#FF7F00'
))
+ ylab('MPAA Rating')
)
),
width_ratio=0.1
)
可以分别设置不同的交集模式:
set.seed(0)
upset(
movies,
genres,
mode='inclusive_intersection',
annotations = list(
# 这里如果不指定就会使用上面设置好的模式)
'Length (inclusive intersection)'=(
ggplot(mapping=aes(y=length))
+ geom_jitter(alpha=0.2, na.rm=TRUE)
),
'Length (exclusive intersection)'=(
ggplot(mapping=aes(y=length))
+ geom_jitter(alpha=0.2, na.rm=TRUE)
+ upset_mode('exclusive_intersection')
),
'Length (inclusive union)'=(
ggplot(mapping=aes(y=length))
+ geom_jitter(alpha=0.2, na.rm=TRUE)
+ upset_mode('inclusive_union')
)
),
min_size=10,
width_ratio=0.1
)
调整交集条形图(intersection size)
图形上面的条形图(intersection size)可以被精确调整,比如颜色/标签/字体等。
调整标签外观
upset(movies,genres,min_size=10,width_ratio = 0.1,
# 调整intersection size
base_annotations = list(
"intersection size"=intersection_size(counts = F) # 不显示个数
)
)
upset(movies,genres,min_size=10,width_ratio = 0.1,
base_annotations = list(
"intersection size"=intersection_size(
# 调整标签颜色和方向
text = list(vjust=-0.1,
hjust=-0.1,
angle=45),
text_colors = c(on_background = "brown",
on_bar = "yellow"
)
)
# 右上角添加汇总数字
+ annotate(
geom='text', x=Inf, y=Inf,
label=paste('Total:', nrow(movies)),
vjust=1, hjust=1
)
# y轴标题
+ ylab('Intersection size')
)
)
增加颜色映射
upset(movies,genres,width_ratio = 0.1,min_size=10,
base_annotations = list(
"intersection size" = intersection_size(
counts = F,
mapping = aes(fill=mpaa)
)
)
)
支持自定义颜色!
library(ggsci)
upset(movies,genres, min_size=10,width_ratio = 0.1,
base_annotations = list(
"intersection" = intersection_size(
counts = F,
mapping = aes(fill=mpaa)
)
+ scale_fill_lancet() # 使用ggsci包的lancet配色
)
)
如果要使用单一颜色,则要使用以下方法:
upset(movies,genres, min_size=10,width_ratio = 0.1,
base_annotations = list(
"intersection" = intersection_size(
counts = F,
mapping = aes(fill="bars_color")
)
+ scale_fill_manual(values = c("bars_color"="skyblue"),guide="none")
)
)
调整高度比例
使用height_ratio
调整上面条形(intersection size)和下面矩阵(intersection matrix)的比例。
upset(
movies,
genres,
height_ratio=1, # 1:1
width_ratio=0.1
)
隐藏intersection size
upset(
movies,
genres,
base_annotations=list(), # 提供一个空列表
min_size=10,
width_ratio=0.1
)
展示集合比例
upset(
movies, genres, name='genre', width_ratio=0.1, min_size=10,
base_annotations=list(
'Intersection size'=intersection_size(),
'Intersection ratio'=intersection_ratio() # 展示占比
)
)
使用ggplot2继续调整
upset(
movies, genres, width_ratio=0.1,
base_annotations = list(
'Intersection size'=(
intersection_size()
+ ylim(c(0, 700))
+ theme(plot.background=element_rect(fill='#E5D3B3'))
+ ylab('# observations in intersection')
)
),
min_size=10
)
后面会继续介绍这个目前为止最为强大的upset plot R 包!
以上就是今天的内容,希望对你有帮助哦!欢迎点赞、在看、关注、转发!
欢迎扫描二维码加 QQ群 :613637742
欢迎关注公众号:医学和生信笔记
“医学和生信笔记,专注R语言数据分析和可视化、R在临床医学中的应用。保姆级教程带你入门R语言,主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等,细致的R包讲解让你快速掌握数据清洗及可视化!
往期推荐