有時(shí)候前方,我們從GEO數(shù)據(jù)庫挖掘了好幾組數(shù)據(jù)集的差異表達(dá)基因,我們需要統(tǒng)計(jì)這些基因列表的交集蒋川,一般可以用韋恩圖和Upset圖牲芋。而韋恩圖一般適合小樣本的交集,而多個(gè)樣本的話可以用Upset圖來表示捺球。
比如缸浦,我們通過GEO2R工具,獲得了差異基因列表的結(jié)果氮兵,假設(shè)有6個(gè)基因列表裂逐,我們可以把顯著性差異表達(dá)基因提取處理,用excel制作一個(gè)genelist泣栈,表頭是數(shù)據(jù)集卜高,每列是基因弥姻,保存為list.csv
,導(dǎo)入進(jìn)來以后,見表 [1]
list<-read.csv("/list.csv")
head(list)
Table 1: 6個(gè)基因列表
A | B | C | D | E | F |
---|---|---|---|---|---|
SLC2A3 | TMC4 | CDC25B | C15orf48 | SYTL1 | KIF2C |
UNC5B | CTHRC1 | C1orf132 | E2F1 | CDCA5 | AURKA |
MT2A | MMD | ST3GAL5 | C1orf132 | BIRC5 | AURKA |
ST3GAL5 | VSIG2 | TMEM154 | MTHFD2 | MCM10 | CDC20 |
TUBB6 | CTHRC1 | ST3GAL5 | KDELR3 | MTHFD2 | C17orf53 |
CTHRC1 | MMP11 | TMEM154 | NSG1 | MELK | CDCA5 |
但是這個(gè)表其實(shí)是有問題的掺涛,那就是這些列表里有些基因是重復(fù)的庭敦,而且還有NA值,我們可以把各自的重復(fù)值和NA值刪除薪缆。記住膜蛔,一定是刪除各列的重復(fù)值荠雕,而不是全部的表格窑滞。
我們可以把列表單獨(dú)提取處理转砖,然后分別去除重復(fù)值和NA值,然后指定成list的形式(當(dāng)然表格形式也是可以的诞外,不過不同行數(shù)的list怎么合并成一個(gè)表格我不會(huì),除非導(dǎo)出來用excel)灾票。
## 單獨(dú)提出各個(gè)list
listA<-list$A
listB<-list$B
listC<-list$C
listD<-list$D
listE<-list$E
listF<-list$F
## 去除各自列表的重復(fù)值
listA<-listA[!duplicated(listA)]
listB<-listB[!duplicated(listB)]
listC<-listC[!duplicated(listC)]
listD<-listD[!duplicated(listD)]
listE<-listE[!duplicated(listE)]
listF<-listF[!duplicated(listF)]
## 去除各自列表的NA值
listA<-na.omit(listA)
listB<-na.omit(listB)
listC<-na.omit(listC)
listD<-na.omit(listD)
listE<-na.omit(listE)
listF<-na.omit(listF)
## 合并list
list<-list(A=listA,B=listB,C=listC,D=listD,E=listE,F=listF)
不過峡谊,經(jīng)過我后期驗(yàn)證,其實(shí)不去除重復(fù)值和NA值刊苍,最后的結(jié)果是一樣的既们,可能已經(jīng)自動(dòng)去除了,具體是否這樣我沒去深入研究正什。
1 繪制韋恩圖
一般而言啥纸,主流畫韋恩圖的包是VennDiagram,教程非常多婴氮,比如使用VennDiagram包繪制韋恩圖
但是這里我想推薦一下ggVennDiagram這個(gè)包斯棒,有一天在Y數(shù)的公眾號(hào)瞎溜達(dá),看到一篇的ggVennDiagram 誕生記文章主经,知道這個(gè)包可以用ggplot2的語句荣暮,而且不限基因列表限制。
我以前喜歡用聯(lián)川生物的在線工具畫韋恩圖罩驻,我承認(rèn)他家可以畫很漂亮的韋恩圖穗酥,并且還是在線交互式繪圖,我看過很多在線工具惠遏,但是他家的確實(shí)是最好看的砾跃。而這個(gè)工具利用的就是VennDiagram這個(gè)包,但是缺點(diǎn)是最多只能畫5個(gè)节吮,所以還是推薦ggVennDiagram這個(gè)包抽高,可能顏值差了點(diǎn),但是效果還是不錯(cuò)的课锌。
先看最基本的函數(shù)厨内,見圖 [1]所示祈秕。
library(ggVennDiagram)
ggVennDiagram(list)
可以看到默認(rèn)顯示的是交集數(shù)字和比例,然后按照集合的數(shù)字填充顏色雏胃,對(duì)于很多個(gè)交集的話请毛,這樣的圖確實(shí)很難看,可是這個(gè)包符合ggolot2語句瞭亮,所以是可以高度DIY的方仿。我們看一下help的函數(shù)
ggVennDiagram(
x,
category.names = names(x), #自定義數(shù)據(jù)集的名稱
show_intersect = FALSE, #是否交互式演示
set_color = "black", # 數(shù)據(jù)集的顏色,默認(rèn)即可
set_size = NA, #數(shù)據(jù)集標(biāo)簽的大小统翩,默認(rèn)即可
label = c("both", "count", "percent", "none"), # 顯示數(shù)值仙蚜、比例還是不顯示
label_alpha = 0.5, #各個(gè)標(biāo)簽集合的外框透明度,0為全透明厂汗,默認(rèn)0.5
label_geom = c("label", "text"), #顯示數(shù)字和標(biāo)簽框
label_color = "black",#標(biāo)簽顏色
label_size = NA, #標(biāo)簽字體大小
label_percent_digit = 0, #標(biāo)簽的百分位數(shù)
label_txtWidth = 40, #標(biāo)簽文本的寬度
edge_lty = "solid", #標(biāo)簽邊緣類型委粉,默認(rèn)實(shí)心
edge_size = 1, #標(biāo)簽邊緣大小
...
)
可以看到可支持的函數(shù)很多,作者也寫了一些引導(dǎo)說明娶桦,大家可以自己嘗試跑一些贾节。
比如我們只顯示數(shù)字,設(shè)置為虛線顯示衷畦,見圖 [2]所示栗涂。
ggVennDiagram(
list,
label = "count",
edge_lty = "dashed",
edge_size = 0.5
)
然而,ggVennDiagram是支持ggplot2
語句的祈争,也就是說我們可以繼續(xù)疊加修改斤程,比如換個(gè)顏色,加個(gè)主題菩混,加個(gè)標(biāo)題什么的忿墅,還有把那個(gè)count的標(biāo)簽去掉什么的,最終效果見圖 [3]所示墨吓,也可以換個(gè)配色球匕,見圖[4]所示。
library(ggplot2)
ggVennDiagram(
list,
label = "count",
edge_lty = "dashed",
edge_size = 0.5)+
scale_fill_gradient(low="steelblue",high = "brown")+
theme_bw()+
ggtitle("Veen plot for six sets")+
theme(legend.position = 'none')
ggVennDiagram(
list,
label = "count",
edge_lty = "dashed",
edge_size = 0.5)+
scale_fill_distiller(palette = "RdBu")+
theme_void()+
ggtitle("Veen plot for six sets")+
theme(legend.position = 'none')
可是這依然不夠ggplot2帖烘,更多的可以看ggVennDiagram 的新生這篇文章亮曹,我們可以把數(shù)據(jù)轉(zhuǎn)換,比如給個(gè)華麗麗的標(biāo)簽秘症,見圖 [5]所示照卦。
venn = Venn(list)
data = process_data(venn)
ggplot() +
geom_sf(aes(fill = count), data = venn_region(data)) +
geom_sf(aes(color = id), data = venn_setedge(data), show.legend = FALSE) +
geom_sf_text(aes(label = name), data = venn_setlabel(data)) +
geom_sf_label(aes(label = count), data = venn_region(data)) +
theme_void()+
theme(legend.position = 'none')+
ggtitle("Veen plot for six sets")
而我們喜歡按數(shù)據(jù)集填充顏色,把fill改成id即可乡摹,最后效果見圖 [6]所示
ggplot() +
geom_sf(aes(fill = id), data = venn_region(data)) +
geom_sf(aes(color = id), data = venn_setedge(data), show.legend = FALSE) +
geom_sf_text(aes(label = name), data = venn_setlabel(data)) +
geom_sf_label(aes(label = count), data = venn_region(data)) +
theme_void()+
theme(legend.position = 'none')+
ggtitle("Veen plot for six sets")
2 繪制Upset圖
當(dāng)數(shù)據(jù)集多于5組的適合役耕,畫韋恩圖就吃力了,因?yàn)槿θμ啻狭院懿缓每此捕弧_@個(gè)時(shí)候就可以用Upset這種圖來表示了故慈。而推薦用UpsetR這個(gè)包,目前在CRAN上也收錄了框全,很方便的可以安裝察绷。
install.package('UpSetR)
UpsetR這個(gè)包默認(rèn)的畫圖其實(shí)不是list的形式,而是各個(gè)交集以0和1的expression形式津辩,用來表示有還是無拆撼。這個(gè)時(shí)候就需要需要我們先把數(shù)據(jù)處理好,這個(gè)可以使用UpSetR自帶的fromList()
函數(shù)實(shí)現(xiàn)喘沿,很簡(jiǎn)單的一句話闸度,最后的表格見表 [2]
library(UpSetR)
data2<-fromList(list)
Table 2: 6個(gè)基因列表的集合
A | B | C | D | E | F |
---|---|---|---|---|---|
1 | 1 | 0 | 1 | 0 | 0 |
1 | 0 | 0 | 0 | 0 | 0 |
1 | 1 | 1 | 1 | 1 | 0 |
1 | 1 | 1 | 1 | 1 | 1 |
1 | 0 | 0 | 0 | 0 | 0 |
1 | 1 | 1 | 1 | 1 | 0 |
當(dāng)然我們也可以不轉(zhuǎn)換數(shù)據(jù),只要加上一句fromList(list)也可以畫圖蚜印,現(xiàn)在我們用最基本的函數(shù)進(jìn)行下Upset圖的繪制莺禁,效果見圖 [7]所示。
upset(data2) # 要先加載UpSetR
### 如果不想對(duì)list進(jìn)行轉(zhuǎn)換窄赋,也可以直接用下面這個(gè)代碼
# upset(fromList(list))
很明顯的睁宰,這里有個(gè)很大的bug,那就是明明有6個(gè)數(shù)據(jù)集寝凌,那就是默認(rèn)只顯示了5個(gè)數(shù)據(jù)集(nset=5),既然默認(rèn)的參數(shù)統(tǒng)計(jì)不出來孝赫,我們就手動(dòng)添加進(jìn)來较木。
另外這個(gè)函數(shù)的功能相當(dāng)?shù)亩啵梢愿鞣N排序(按頻率排序青柄,按頻數(shù)排序伐债,還可以按數(shù)據(jù)集分組),還可以給點(diǎn)填色等等致开。具體的可以在示例說明找到峰锁,一切都等你發(fā)現(xiàn)
比如我們按freq排序,設(shè)置6個(gè)數(shù)據(jù)集双戳,見圖 [8]所示虹蒋。
upset(fromList(list),nsets = 6,order.by = "freq")
## upset(fromList(list),sets = c("A","B","C","D","E","F")) #也可以按需設(shè)置
我們想知道6個(gè)數(shù)據(jù)集都交集的情況,還想標(biāo)個(gè)顏色飒货,可以這樣魄衅,見圖 [9]所示。
upset(fromList(list),nsets = 6,order.by = "freq",,queries = list(list(query = intersects, params = list("A","B","C","D","E","F"), active = T)))
UpSetR是一個(gè)很強(qiáng)大的包晃虫,功能很多,但有一個(gè)問題就是不能使用ggplot語句扣墩,導(dǎo)出的圖也不是ggplot哲银,這個(gè)我們可以用Y叔的ggplotify轉(zhuǎn)換扛吞。當(dāng)然其實(shí)還有一個(gè)叫ggupset的包可以使用ggplot語句的,但是需要數(shù)據(jù)處理荆责,語法很復(fù)雜滥比,有興趣自己百度學(xué)習(xí)。
3 兩組圖的結(jié)合
Upset圖有個(gè)缺點(diǎn)就是草巡,如果按頻數(shù)畫圖守呜,右上角會(huì)空出很大一塊,我們能不能把韋恩圖和Upset圖組合到一起山憨,這個(gè)問題Y叔已經(jīng)考慮并解決過了查乒,可以參考轉(zhuǎn)UpSet圖為ggplot?
這里用到了Y叔叔的yyplot這個(gè)神包,然而這個(gè)包也是很難裝上的郁竟,因?yàn)檫@是Y叔的私人包玛迄,需要補(bǔ)裝很多包,而很多包都是只有Github上才能安裝棚亩,比如gglayer這個(gè)包蓖议,你在CRAN和BiocManager上都上找不到的,只有Y叔的Github上的包才能安裝讥蟆,但是又經(jīng)常訪問困難勒虾,所以我Fork到了我的gitee上。而且用yyplot畫韋恩圖瘸彤,需要用ggvenn
這個(gè)函數(shù)修然,但是這個(gè)函數(shù)又要配置Java環(huán)境,所以個(gè)中曲折自己摸索吧质况。
remotes::install_git('https://gitee.com/swcyo/gglayer/'))
remotes::install_git('https://gitee.com/swcyo/yyplot/'))
library(yyplot)
我們可以不用Y叔的yyplot畫韋恩圖(因?yàn)楹茈y安裝)愕宋,用ggVennDiagram的圖即可,兩種圖的組合原理是兩個(gè)ggplot圖形的疊加结榄,這里要用到Y(jié)叔的ggimge這個(gè)包(Y叔是無處不在的)中贝,最后效果見圖 [10]所示。
library(ggplotify) #把別的圖轉(zhuǎn)為ggplot2
library(ggimage) # 組合圖片
p1<-upset(fromList(list),nsets = 6,order.by = "freq",,queries = list(list(query = intersects, params = list("A","B","C","D","E","F"), active = T)))
g1<-as.ggplot(p1) # 轉(zhuǎn)換為ggplot2圖片
g2<-ggplot() +
geom_sf(aes(fill = id), data = venn_region(data)) +
geom_sf(aes(color = id), data = venn_setedge(data), show.legend = FALSE) +
geom_sf_text(aes(label = name), data = venn_setlabel(data)) +
geom_sf_label(aes(label = count), data = venn_region(data)) +
theme_void()+
theme(legend.position = 'none')
g3<-g1 + geom_subview(subview = g2 , x=.8, y=.7, w=.45, h=.45)
g3
但是這里有一個(gè)bug邻寿,就是左側(cè)的bar不見了,不知道是不是我電腦的問題依溯。老厌。。
如果要用yyplot畫韋恩圖的畫黎炉,可以這樣枝秤,最后效果見 [11]
library(yyplot)
g4<-ggvenn(fromList(list))
g5<-g1 + geom_subview(subview = g4 + theme_void(), x=.8, y=.7, w=.5, h=.5)
g5
4 在線交互式作圖
有很多網(wǎng)站可以在線交互式作圖慷嗜,有國產(chǎn)開發(fā)的淀弹,也有shiny丹壕,比如:
https://www.omicstudio.cn/tool/6
gehlenborglab.shinyapps.io/upsetr/
https://asntech.shinyapps.io/intervene/
更多的在線功能等著大家發(fā)現(xiàn)。