R 畫網絡圖node
目的:用R作生信分析,畫基因樣本的網絡圖,從中觀察樣本的致病性狀況。json
1、所用到的包
- library(tidyr)
- library(ggplot2)
- library(reshape2)
- library(readr)
- library(network)
- library(dplyr)
- library(plyr)
- library(sna)
- library(GGally)
- library(ggnetwork)
- library(tidygraph)# tidy graph analysis
- #library(tidyverse)# tidy data analysis
- library(ggraph)
- library(stringr)
- library(networkD3)
- library(igraph)
- library(visNetwork)
- library(threejs)
- library(ndtv)
- library(grid)
- library(Rmisc)
- #library(vioplot)
- library(tibble)
13行中:tidyverse包集成了不少畫圖的包:以下api
tidyverse_packages(include_self = TRUE)網絡
[1] "broom" "cli" "crayon" "dplyr" "dbplyr" "forcats" "ggplot2" "haven" "hms" "httr" ide
[11] "jsonlite" "lubridate" "magrittr" "modelr" "purrr" "readr" "readxl\n(>=" "reprex" "rlang" "rstudioapi"函數
[21] "rvest" "stringr" "tibble" "tidyr" "xml2" "tidyverse" spa
可是若是同時使用這些包,會提示tidyverse_conflicts(),使用tidyverse_conflicts()能夠查看tidyverse和其餘哪些包衝突:.net
> tidyverse_conflicts()xml
-- Conflicts ------------------------------------------ tidyverse_conflicts() --blog
x tidygraph::arrange() masks dplyr::arrange(), plyr::arrange()
x tibble::as_data_frame() masks igraph::as_data_frame(), dplyr::as_data_frame()
x purrr::compact() masks plyr::compact()
x purrr::compose() masks igraph::compose()
x dplyr::count() masks plyr::count()
x tidyr::crossing() masks igraph::crossing()
x dplyr::failwith() masks plyr::failwith()
x tidygraph::filter() masks dplyr::filter(), stats::filter()
x igraph::groups() masks tidygraph::groups(), dplyr::groups()
x dplyr::id() masks plyr::id()
x dplyr::lag() masks stats::lag()
x tidygraph::mutate() masks dplyr::mutate(), plyr::mutate()
x tidygraph::rename() masks dplyr::rename(), plyr::rename()
x purrr::simplify() masks igraph::simplify()
x dplyr::summarise() masks plyr::summarise()
x dplyr::summarize() masks plyr::summarize()
因此我註釋掉了tidyverse,須要用哪一個包就本身添加。
2、畫網絡圖遇到的問題
1.顏色自定義
我根據list中屬性的種類來定義nodes的顏色,de[,5]中的值爲「P」、「V」、「B」,三個類別。
常規的寫法是:
geom_node_point(size = 3, alpha = 1,aes(color =de[,5])),
這樣系統自動分陪顏色,紅綠藍給BPV,
可是會出現如下問題:
A) de[,5]中PVB 出現的順序會影響到顏色的標記。
B) de[,5]中PVB並非三種都出現,而是三種的隨機組合出現,好比只有PV或者只有VB或者只有PB。
以上緣由致使網絡圖中顏色不對應,第一幅圖中紅=B 綠=P 藍=V,若是de[,5]中只有BV兩種,會生成紅=B,綠=V,致使圖例和實際的PVB值不對應。
同時由於看的人肯能出現色盲的狀況,通常不用紅色和綠色來表示nodes的顏色,因此須要自定義顏色。
好比我須要自定義顏色:效果是這樣
'V'='#b27390', 'P'='#f15941','B'='#42a3c6'
我用的ggraph這個畫圖函數,因此只須要加上scale_color_manual就行:
(若是使用的是ggplot,則用scale_fill_manual)。
這裏須要注意scale_color_manua有兩種寫法:
1)scale_color_manual(name="diagnosis",labs=c(‘V’,’P’,’B’) values=c(''#b27390', '#f15941','#42a3c6'))
2)scale_color_manual(name="diagnosis", values=c('V'='#b27390', 'P'='#f15941','B'='#42a3c6'))
必選參數values:https://blog.csdn.net/songzhilian22/article/details/49388973
values,用於指定這個標度應該生成的值。若是這個向量中的元素是有名稱的。則它將自動匹配輸入和輸出的值,不然它將按照離散型變量中水平的前後次序進行匹配。因此選擇第2中方法給定義顏色,以避免隨機產生顏色。
最後的結果以下:
2.多樣本for循環的使用問題
本數據中包含多個樣本,在畫圖以前要對樣本進行切割,使用split最好不過了。
split(data1, as.factor(data1$gene))#按照基因切割
split(gene, gene$sampleid)#按照樣本切割
切割後添加過濾條件,一個樣本至少攜帶兩個variant的sample保留下來作網絡圖。行數≥2的說明只有兩個variant,按照gene切割的安裝代碼以下,用到第一個for循環:
for (gene in data_per_gene) {
data_per_sample_per_gene <- split(gene, gene$sampleid)
########### Then we enumerate each sample to obtain the edges ###############
for (sample in data_per_sample_per_gene) {
######### we demand sample carry >=2 variants in the same gene to be considered #############
if ((nrow(sample)>=2)&&(sum(sample$GT)==2)){
####### create combinations of variants #################################
a <- combn(sample$num_id,2)
b <- data.frame(t(a))
b$sample <- as.character(unique(sample$sampleid))
b$gene <- as.character(unique(sample$gene))
edge <- rbind(edge, b)
}
}
}
而後對edge中的邊所對應的gene切割
edge_per_gene <- split(edge, as.factor(edge$gene))
接下來咱們爲每一個基因的每個variant建立邊:用到第二個for循環
for (gene in edge_per_gene)
這個循環裏,咱們不只要完成邊和點的鏈接,還要完成畫圖。
3.鏈接邊和點
對edge中的X1,X2進行分組操做,而後計算邊的權重。(不一樣的樣本有相同的邊也合併計算權重,值保留一條邊,用權重weight表示邊鏈接的次數)
edge2 <- gene %>%
group_by(X1, X2) %>%
summarise(weight = n()) %>%
ungroup()
unique(edge2)
而後定義nodes,選擇X1和X2中惟一出現的num_id合併去重,
nodesX1 <- subset(nodes0, (nodes0$num_id %in%edge2$X1))
nodesX2 <- subset(nodes0, (nodes0$num_id %in%edge2$X2))
nodes2<-unique(rbind(nodesX1,nodesX2))
把nodes2的第一列單獨拿出來:
nodes3<-as.data.frame(nodes2[,1])
接下來創建點和邊的鏈接關係,咱們把nodes3 從新編號命名,
nodes3$ID <- seq(1:nrow(nodes3))
colnames(nodes3) <- c("var","id")
nodes3$var <- as.integer(nodes3$var)
edges2中的邊也經過id與nodes3創建鏈接:
edges <- edge2 %>%
left_join(nodes3, by = c(X1 = "var")) %>%
rename(from = id)
edges <- edges %>%
left_join(nodes3, by = c(X2 = "var")) %>%
rename(to = id)
最後,選擇邊的集合:
edges <- select(edges, from,to,weight)
4.畫網絡圖
咱們建立無向圖,directed = FALSE。
我使用的library(network),網上還有library(networkD3),library(sna)等。
routes_network <- network(edges,
vertex.attr = nodes3,
matrix.type = "edgelist",
ignore.eval = FALSE)
routes_tidy <- tbl_graph(nodes = nodes3, edges = edges, directed = FALSE)
5.ggraph畫圖
畫圖以前,咱們自定義點的名字nodename
de<- routes_tidy %>%
activate(nodes) %>%
as.data.frame()
de<-cbind(de,nodes2$color_net)
colnames(de) <- c("var","id","degree","centrality","diagnosis")
nodename<-paste(de$degree,"-",de$var)
最後使用ggraph畫圖:
ggraph(routes_tidy ,layout = "fr") +
geom_edge_link(aes(width = weight),alpha = 0.6) +
geom_node_point(size = 3, alpha = 1,aes(color =de[,5])) +
scale_color_manual(name="diagnosis", values=c('V'='#b27390', 'P'='#f15941','B'='#42a3c6'))+#分配顏色
geom_node_text(aes(label = nodename), size = 0.5, repel = FALSE) +
scale_edge_width(range = c(0.2, 2)) +
labs(x = "", y = "", title = filename) +
theme(axis.ticks = element_blank()) +
theme(axis.text.x = element_blank())+
theme(axis.text.y = element_blank())+
theme(panel.grid=element_blank())+
theme(panel.background=element_blank())+
theme(panel.border=element_blank())
5.計算nodes的相關屬性
中心度:點度頻率(每種點度數的個數/全部點個數)
routes_tidy <-routes_tidy %>%
activate(nodes) %>%
mutate(centrality = degree(routes_tidy)/vcount(routes_tidy))
度:degree
#nodes的度
routes_tidy <-routes_tidy %>%
activate(nodes) %>%
mutate(degree = centrality_degree())