撰文:陳亮 中科院微生物所
責編:劉永鑫 中科院遺傳發育所
網絡分析背景知識近年來,隨著計算機技術的發展,網絡科學研究在社會網絡方面的分析方法已經成熟,從而促進了網絡分析方法向其他領域的滲透,例如:信號傳導網絡、神經網絡、代謝通路網絡、基因調控網絡、生態網絡等。
基於圖論(Graph theory)的網絡科學認為,任何非連續事物之間的關係都可以用網絡來表示,通過將網際網路內的電腦、社會關係中的個人、生物的基因等不同屬性的實體抽象為節點(Node),並用連接(Link)來展示實體之間的關係,通過量化以節點和連接為組件的網絡結構指數(Index),從而能夠在統一的框架下尋找複雜系統的共性。
目前生態學領域大家用到的網絡圖多為基於群落數據相關性構建的Co-occurrence網絡圖。此類網絡可以採用R中igraph包構建並實現出圖。當然,除此之外,還有一些非命令行的軟體,例如cytoscape,gephi,pajek等。但我認為,對於R使用者來說,通過R做圖還是最方便的。大致的流程如下圖所示:
1)根據觀察,實驗或者相關性推斷來確定物種間的聯繫。Co-occurrence網絡的構建多是基於相關性推斷來構建的。常用的相關性推斷方法有Pearson,Spearman, Sparcc等方法。
2)通過構建的相關性矩陣或者相互作用列表來構建igraph對象。常用的方法有以下三種,分別由graph_from_incidence_matrix,graph_from_adjacency_matrix,graph_from_edgelist三個函數獲得,詳細信息參照igraph官方幫助文檔。第一種數據格式是普通矩陣,矩陣中數字代表行列所代表的物種間存在聯繫,這種聯繫可通過實驗或觀察來得到。第二種數據格式是鄰接矩陣,物種間相關性計算得到的通常為此種形式。第三種為邊列表(edgelist),共兩列數據,分別代表網絡內的節點名稱,每一行代表這兩個節點間存在著聯繫。
3)計算網絡的各種參數,用以推斷網絡的性質。
常用網絡參數有:
平均路徑長度(Average path length):網絡中任意兩個節點之間的距離的平均值。其反映網絡中各個節點間的分離程度。現實網絡通常具有「小世界(Small-world)」特性。
聚集係數(Clustering coefficient):分局域聚類係數和全局聚集係數,是反映網絡中節點的緊密關係的參數,也稱為傳遞性。整個網絡的全局聚集係數C表徵了整個網絡的平均的「成簇性質」。
介數(Betweenness):網絡中不相鄰的節點i和j之間的通訊主要依賴於連接節點i和j的最短路徑。如果一個節點被許多最短路徑經過,則表明該節點在網絡中很重要。 經過節點n的數量所佔比例,介數反映了某節點在通過網絡進行信息傳輸中的重要性。
連接性 (Connectance): 網絡中物種之間實際發生的相互作用數之和(連接數之和)佔總的潛在相互作用數(連接數)的比例,可以反映網絡的複雜程度。
此外還包括:度分布(Degree distribution)、平均度(Average degree)、平均介數(Average betweenness)、平均最近鄰度(Average nearest-neighbor degree)、直徑(Diameter)、介數中心性(Betweenness centralization)和度中心性(Degree centralization)等參數。
各網絡參數計算方法及意義參見igraph.org官方幫助文檔。
網絡分析需要兩個文件,OTU表和OTU的屬性;具體格式見測試數據下載連結:後臺回復「網絡」獲取
1.最簡單的網絡圖
# 設置工作目錄:請修改下方目錄或在Rstudio的Session菜單中選擇下載測試數據所在的目錄
# setwd("~/Downloads/chenliang")
# 安裝需要的包,默認不安裝,沒安裝過的請取消如下注釋
# install.packages("igraph")
# install.packages("psych")
# 加載包
library(igraph)
library(psych)
# 讀取otu-sample矩陣,行為sample,列為otu
otu = read.table("otu_table.txt",head=T,row.names=1)
# 計算OTU間兩兩相關係數矩陣
# 數據量小時可以用psych包corr.test求相關性矩陣,數據量大時,可應用WGCNA中corAndPvalue, 但p值需要藉助其他函數矯正
occor = corr.test(otu,use="pairwise",method="spearman",adjust="fdr",alpha=.05)
occor.r = occor$r # 取相關性矩陣R值
occor.p = occor$p # 取相關性矩陣p值
# 確定物種間存在相互作用關係的閾值,將相關性R矩陣內不符合的數據轉換為0
occor.r[occor.p>0.05|abs(occor.r)<0.6] = 0
# 構建igraph對象
igraph = graph_from_adjacency_matrix(occor.r,mode="undirected",weighted=TRUE,diag=FALSE)
igraph
# NOTE:可以設置weighted=NULL,但是此時要注意此函數只能識別相互作用矩陣內正整數,所以應用前請確保矩陣正確。
# 可以按下面命令轉換數據
# occor.r[occor.r!=0] = 1
# igraph = graph_from_adjacency_matrix(occor.r,mode="undirected",weighted=NULL,diag=FALSE)
# 是否去掉孤立頂點,根據自己實驗而定
# remove isolated nodes,即去掉和所有otu均無相關性的otu 可省略,前期矩陣已處理過
bad.vs = V(igraph)[degree(igraph) == 0]
igraph = delete.vertices(igraph, bad.vs)
igraph
# 將igraph weight屬性賦值到igraph.weight
igraph.weight = E(igraph)$weight
# 做圖前去掉igraph的weight權重,因為做圖時某些layout會受到其影響
E(igraph)$weight = NA
# 簡單出圖
# 設定隨機種子數,後續出圖都從同一隨機種子數出發,保證前後出圖形狀相對應
set.seed(123)
plot(igraph,main="Co-occurrence network",vertex.frame.color=NA,vertex.label=NA,edge.width=1,
vertex.size=5,edge.lty=1,edge.curved=TRUE,margin=c(0,0,0,0))
最簡單的點線網絡圖
2.按相關類型設置邊顏色
# 如果構建網絡時,weighted=NULL,此步驟不能統計
sum(igraph.weight>0)# number of postive correlation
sum(igraph.weight<0)# number of negative correlation
# set edge color,postive correlation 設定為red, negative correlation設定為blue
E.color = igraph.weight
E.color = ifelse(E.color>0, "red",ifelse(E.color<0, "blue","grey"))
E(igraph)$color = as.character(E.color)
# 改變edge顏色後出圖
set.seed(123)
plot(igraph,main="Co-occurrence network",vertex.frame.color=NA,vertex.label=NA,edge.width=1,
vertex.size=5,edge.lty=1,edge.curved=TRUE,margin=c(0,0,0,0))
邊按相關性著色,正相關為紅色,負相關為藍色
3.按相關性設置邊寬度
# 可以設定edge的寬 度set edge width,例如將相關係數與edge width關聯
E(igraph)$width = abs(igraph.weight)*4
# 改變edge寬度後出圖
set.seed(123)
plot(igraph,main="Co-occurrence network",vertex.frame.color=NA,vertex.label=NA,
vertex.size=5,edge.lty=1,edge.curved=TRUE,margin=c(0,0,0,0))
邊寬度為4倍相關係數絕對值,看看邊是不是有粗有細,越粗代表相關絕對值越大
4.設置點的顏色和大小屬性對應物種和豐度
# 添加OTU注釋信息,如分類單元和豐度
# 另外可以設置vertices size, vertices color來表徵更多維度的數據
# 注意otu_pro.txt文件為我隨機產生的數據,因此網絡圖可能不會產生特定的模式或規律。
otu_pro = read.table("otu_pro.txt",head=T,row.names=1)
# set vertices size
igraph.size = otu_pro[V(igraph)$name,] # 篩選對應OTU屬性
igraph.size1 = log((igraph.size$abundance)*100) # 原始數據是什麼,為什麼*100再取e對數
V(igraph)$size = igraph.size1
# set vertices color
igraph.col = otu_pro[V(igraph)$name,]
levels(igraph.col$phylum)
levels(igraph.col$phylum) = c("green","deeppink","deepskyblue","yellow","brown","pink","gray","cyan","peachpuff") # 直接修改levles可以連值全部對應替換
V(igraph)$color = as.character(igraph.col$phylum)
set.seed(123)
plot(igraph,main="Co-occurrence network",vertex.frame.color=NA,vertex.label=NA,
edge.lty=1,edge.curved=TRUE,margin=c(0,0,0,0))
點大小對應OTU豐度,顏色對應門分類學種類
5.調整布局樣式
# 改變layout,layout有很多,具體查看igraph官方幫助文檔。
set.seed(123)
plot(igraph,main="Co-occurrence network",layout=layout_with_kk,vertex.frame.color=NA,vertex.label=NA,
edge.lty=1,edge.curved=TRUE,margin=c(0,0,0,0))
set.seed(123)
plot(igraph,main="Co-occurrence network",layout=layout.fruchterman.reingold,vertex.frame.color=NA,vertex.label=NA,
edge.lty=1,edge.curved=TRUE,margin=c(0,0,0,0))
不同的布局選項,和上圖有什麼變化
6.按模塊著色
# 模塊性 modularity
fc = cluster_fast_greedy(igraph,weights =NULL)# cluster_walktrap cluster_edge_betweenness, cluster_fast_greedy, cluster_spinglass
modularity = modularity(igraph,membership(fc))
# 按照模塊為節點配色
comps = membership(fc)
colbar = rainbow(max(comps))
V(igraph)$color = colbar[comps]
set.seed(123)
plot(igraph,main="Co-occurrence network",vertex.frame.color=NA,vertex.label=NA,
edge.lty=1,edge.curved=TRUE,margin=c(0,0,0,0))
按劃分的模塊著色,結果中也很常用
7.顯示標籤和點輪廓
# 最後添加刪除color和label項可顯示標籤和點顏色邊框
plot(igraph,main="Co-occurrence network",vertex.frame.color=NA,vertex.label=NA,
edge.lty=1,edge.curved=TRUE,margin=c(0,0,0,0))
最後的效果
8.常用網絡屬性
# network property
# 邊數量 The size of the graph (number of edges)
num.edges = length(E(igraph)) # length(curve_multiple(igraph))
num.edges
# 頂點數量 Order (number of vertices) of a graph
num.vertices = length(V(igraph))# length(diversity(igraph, weights = NULL, vids = V(igraph)))
num.vertices
# 連接數(connectance) 網絡中物種之間實際發生的相互作用數之和(連接數之和)佔總的潛在相互作用數(連接數)的比例,可以反映網絡的複雜程度
connectance = edge_density(igraph,loops=FALSE)# 同 graph.density;loops如果為TRUE,允許自身環(self loops即A--A或B--B)的存在
connectance
# 平均度(Average degree)
average.degree = mean(igraph::degree(igraph))# 或者為2M/N,其中M 和N 分別表示網絡的邊數和節點數。
average.degree
# 平均路徑長度(Average path length)
average.path.length = average.path.length(igraph) # 同mean_distance(igraph) # mean_distance calculates the average path length in a graph
average.path.length
# 直徑(Diameter)
diameter = diameter(igraph, directed = FALSE, unconnected = TRUE, weights = NULL)
diameter
# 群連通度 edge connectivity / group adhesion
edge.connectivity = edge_connectivity(igraph)
edge.connectivity
# 聚集係數(Clustering coefficient):分局域聚類係數和全局聚集係數,是反映網絡中節點的緊密關係的參數,也稱為傳遞性。整個網絡的全局聚集係數C表徵了整個網絡的平均的「成簇性質」。
clustering.coefficient = transitivity(igraph)
clustering.coefficient
no.clusters = no.clusters(igraph)
no.clusters
# 介數中心性(Betweenness centralization)
centralization.betweenness = centralization.betweenness(igraph)$centralization
centralization.betweenness
# 度中心性(Degree centralization)
centralization.degree = centralization.degree(igraph)$centralization
centralization.degree
通過以上的學習,大家是不是可以一步步基於OTU表和注釋,用R實現高大上的網絡分析和繪製了呢?想要提高,還得多讀,多練,多思考,解決科學問題是關鍵!
後臺回復「網絡」,獲取代碼和測試數據下載連結。
猜你喜歡10000+:菌群分析 寶寶與貓狗 梅毒狂想曲 提DNA發Nature Cell專刊 腸道指揮大腦
系列教程:微生物組入門 Biostar 微生物組 宏基因組
專業技能:學術圖表 高分文章 生信寶典 不可或缺的人
一文讀懂:宏基因組 寄生蟲益處 進化樹
必備技能:提問 搜索 Endnote
文獻閱讀 熱心腸 SemanticScholar Geenmedical
擴增子分析:圖表解讀 分析流程 統計繪圖
16S功能預測 PICRUSt FAPROTAX Bugbase Tax4Fun
在線工具:16S預測培養基 生信繪圖
科研經驗:雲筆記 雲協作 公眾號
編程模板: Shell R Perl
生物科普: 腸道細菌 人體上的生命 生命大躍進 細胞暗戰 人體奧秘
寫在後面為鼓勵讀者交流、快速解決科研困難,我們建立了「宏基因組」專業討論群,目前己有國內外5000+ 一線科研人員加入。參與討論,獲得專業解答,歡迎分享此文至朋友圈,並掃碼加主編好友帶你入群,務必備註「姓名-單位-研究方向-職稱/年級」。PI請明示身份,另有海內外微生物相關PI群供大佬合作交流。技術問題尋求幫助,首先閱讀《如何優雅的提問》學習解決問題思路,仍未解決群內討論,問題不私聊,幫助同行。
學習16S擴增子、宏基因組科研思路和分析實戰,關注「宏基因組」
點擊閱讀原文,跳轉最新文章目錄閱讀