对邓老师组开发不同域之间二分网络的思考和ggCLusterNet的进一步完善
不同域之间的相互关系
例如:细菌和真菌,不考虑内部相关,只考虑细菌和真菌之间的相关。
邓老师在前些日子的讲座这提到的这种网络,称之为“二分网络”,其实二分网络是我17年听到的一个词汇,当时用于类似于Ven图,展示OTU之间的共有和特有的OTU的一个网络,并不是一个真正的网络,仅仅是一个简简单单的从属关系。
这一方法发表在2019年,下面是当时的新闻:
http://mem.rcees.ac.cn:8081/
中国科学院生态环境研究中心环境生物技术院重点实验室邓晔研究组长期致力于利用生态网络分析方法来探究生态群落内物种间的相互作用,近期该课题组构建了用于探索植物与微生物物种互作关系的二分网络分析方法和分析平台,在探索宏观和微观物种生态网络分析方法上取得进展。研究结果近期在线发表在生态学杂志《分子生态资源》(Molecular Ecology Resources)上。
宏观生态系统中,跨域物种间的生态网络一直是研究的热点。然而,自然生态系统地上-地下群落生态中,植物与微生物之间的相互作用在区域尺度上仍未得到较好的解析。本研究中,该课题组提出了利用微观的高通量分子检测数据和宏观的植被调查数据来构建植物与微生物之间的跨界生态网络方法(Inter-domain ecological networks, IDEN),并搭建了相应的开放式分析平台。利用该平台,邓晔课题组与中国林业科学研究院张于光研究员合作,对中国沿纬度梯度分布的30个森林生态系统中地上植物和地下土壤微生物群落数据进行了系统的分析。结果显示,区域尺度的跨界生态网络具有较高的连接度、嵌套结构、不对称专一性和模块化结构等网络拓扑结构属性。此外植物对于特定的微生物类群表现出一定的偏好性。对不同地点的局部尺度IDEN进行分析,也发现特定植物在不同地区都具有共存的微生物物种。本研究展示了自然生态系统中植物与微生物的共存关系,并有助于未来进一步理解生物群落中多个跨界生物物种之间的层级结构。
目前,该生态网络的分析方法及分析流程已经存放到邓晔课题组开放的分析平台IDENAP (http://mem.rcees.ac.cn:8081)网站上,欢迎感兴趣的科研人员使用。
该研究得到了科技部重点研发项目、国家自然基金委和中国科学院等基金的资助。论文第一作者为本中心博士研究生冯凯。论文链接:https://onlinelibrary.wiley.com/doi/abs/10.1111/1755-0998.13081
思考
关注不同域之间的相互作用,是目前多指标组合多指标测定的一个趋势。不同域之间网络我完全可以添加到ggclusterNet内部,因为我主打的cluster本来就是不同的分组的部分。完全可以类比于不同类型的指标。
计算部分:
网络的计算部分可以全部计算,不同域之间的网络做取子集。
这里我新建一个函数,用于这项功能的操作。
同样构造边和节点文件,用于网络可视化和网络属性的计算。
biostripe_network 二分网络
微生物网络
输入文件
#--导入所需R包#-------
library(phyloseq)
library(igraph)
library(network)
library(sna)
library(ggplot2)
library(ggClusterNet)
#-----导入数据#-------
# ps = readRDS("../ori_data/ps_liu.rds")
# ps
corBiostripe函数用于计算相关
这里我们在早期调用了psych包中的corr.test函数,使用三种相关方法,但是这三种是远远不够的,所以后续我们准备将x剁相关都加入其中。
这个函数仅仅用于计算不同模块之间的相关关系,也就是不同域之间的关系
数据输入格式
这里需要输入两个数据:
data:
行为测定的变量,列为样本
group:
指标的分组文件,第一列为变量,第二列为分组信息,这里的分组,也就是不同的域。
data1 <- read.delim("../ori_data/bios_network_normal//env.txt")
Gru <- read.delim("../ori_data/bios_network_normal//env_group.txt")
result <- corBiostripe(data = data1,group = Gru)
#--提取相关矩阵
cor = result[[1]]
制作分组,这里不同的域,就是分组
这是网络布局的基础,无论是什么聚类布局,都需要制作一个分组文件,这个文件有两列,一列是节点,一列是分组信息,这个分组信息名称为:group。
这个文件信息就是用于对节点进行分组,然后按照分组对节点归类,使用包中可视化函数计算节点位置。
netClu = Gru
colnames(netClu) <- c("ID","group")
head(netClu)
head(Gru)
PolygonClusterG 根据分组,计算布局
PolygonClusterG :不同的模块按照分分组聚集成不同的圆,并且圆形的大小一样。如果一个分组只有一个点,则这个点坐落在圆心位置。
这个函数在2020年8月19日增加了两个参数,并于当天更新打扫github上,用于控制不同模块之间距离的参数zoom,和模块半径的参数zoom。两个参数默认都是1.
下面我们演示zoom用法,调整变大,距离拉大,展示模块之间的关系
#--------计算布局#---------
#-------计算网络布局-得到节点坐标=node#---------
result2 = PolygonClusterG (cor = cor,nodeGroup =netClu,zoom = 3,zoom2 = 1 )
node = result2[[1]]
head(node)
### nodeadd 节点注释的简单封装,便捷实用otu表格和分组文件进行注释
library(dplyr)
nodes <- node %>%
inner_join(Gru,by =c("elements" = "SampleID") )
#-----计算边#--------
edge = edgeBuild(cor = cor,plotcord = node)
head(edge)
### 出图
pnet <- ggplot() + geom_segment(aes(x = X1, y = Y1, xend = X2, yend = Y2,color = as.factor(wei_label)),
data = edge, size = 0.5) +
geom_point(aes(X1, X2,fill = Group),pch = 21, size = 5,data = nodes) +
scale_colour_brewer(palette = "Set1") + theme_void()
pnet
# ggsave("./1.png",pnet)
# pnet <- pnet + geom_text_repel(aes(X1, X2,label=elements),size=4, data = plotcord)
下面演示zoom2 用法,数值变小,单个模块缩小,同样放大了模块之间关系
#--------计算布局#---------
#-------计算网络布局-得到节点坐标=node#---------
result2 = PolygonClusterG (cor = cor,nodeGroup =netClu,zoom = 1,zoom2 = 0.5 )
node = result2[[1]]
head(node)
### nodeadd 节点注释的简单封装,便捷实用otu表格和分组文件进行注释
library(dplyr)
nodes <- node %>%
inner_join(Gru,by =c("elements" = "SampleID") )
#-----计算边#--------
edge = edgeBuild(cor = cor,plotcord = node)
head(edge)
### 出图
pnet <- ggplot() + geom_segment(aes(x = X1, y = Y1, xend = X2, yend = Y2,color = as.factor(wei_label)),
data = edge, size = 0.5) +
geom_point(aes(X1, X2,fill = Group),pch = 21, size = 5,data = nodes) +
scale_colour_brewer(palette = "Set1") + theme_void()
pnet
# ggsave("./1.png",pnet)
# pnet <- pnet + geom_text_repel(aes(X1, X2,label=elements),size=4, data = plotcord)
换一种layout,PolygonRrClusterG:可以按照模块节点数量调整模块半径大小。
#--------计算布局#---------
#-------计算网络布局-得到节点坐标=node#---------
result2 = PolygonRrClusterG(cor = cor,nodeGroup =netClu,zoom = 1,zoom2 = 0.9 )
node = result2[[1]]
head(node)
### nodeadd 节点注释的简单封装,便捷实用otu表格和分组文件进行注释
library(dplyr)
nodes <- node %>%
inner_join(Gru,by =c("elements" = "SampleID") )
#-----计算边#--------
edge = edgeBuild(cor = cor,plotcord = node)
head(edge)
### 出图
pnet <- ggplot() + geom_segment(aes(x = X1, y = Y1, xend = X2, yend = Y2,color = as.factor(wei_label)),
data = edge, size = 0.5) +
geom_point(aes(X1, X2,fill = Group),pch = 21, size = 5,data = nodes) +
scale_colour_brewer(palette = "Set1") + theme_void()
pnet
# ggsave("./1.png",pnet)
# pnet <- pnet + geom_text_repel(aes(X1, X2,label=elements),size=4, data = plotcord)
#--------计算布局#---------
#-------计算网络布局-得到节点坐标=node#---------
result2 = PolygonRrClusterG(cor = cor,nodeGroup =netClu,zoom = 1,zoom2 = 0.9 )
node = result2[[1]]
head(node)
### nodeadd 节点注释的简单封装,便捷实用otu表格和分组文件进行注释
library(dplyr)
nodes <- node %>%
inner_join(Gru,by =c("elements" = "SampleID") )
#-----计算边#--------
edge = edgeBuild(cor = cor,plotcord = node)
head(edge)
### 出图
pnet <- ggplot() + geom_segment(aes(x = X1, y = Y1, xend = X2, yend = Y2,color = as.factor(wei_label)),
data = edge, size = 0.5) +
geom_point(aes(X1, X2,fill = Group),pch = 21, size = 5,data = nodes) +
scale_colour_brewer(palette = "Set1") + theme_void()
pnet
# ggsave("./1.png",pnet)
# pnet <- pnet + geom_text_repel(aes(X1, X2,label=elements),size=4, data = plotcord)
下面使用ranSNEClusterG来做layout
这个ranSNEClusterG函数,只可以设置zoom参数,模块之间的位置关系。
#--------计算布局#---------
#-------计算网络布局-得到节点坐标=node#---------
result2 = ranSNEClusterG(cor = cor,nodeGroup =netClu,zoom = 3,layout = "adj" )
node = result2[[1]]
head(node)
### nodeadd 节点注释的简单封装,便捷实用otu表格和分组文件进行注释
library(dplyr)
nodes <- node %>%
inner_join(Gru,by =c("elements" = "SampleID") )
#-----计算边#--------
edge = edgeBuild(cor = cor,plotcord = node)
head(edge)
### 出图
pnet <- ggplot() + geom_segment(aes(x = X1, y = Y1, xend = X2, yend = Y2,color = as.factor(wei_label)),
data = edge, size = 0.5) +
geom_point(aes(X1, X2,fill = Group),pch = 21, size = 5,data = nodes) +
scale_colour_brewer(palette = "Set1") + theme_void()
pnet
# ggsave("./1.png",pnet)
# pnet <- pnet + geom_text_repel(aes(X1, X2,label=elements),size=4, data = plotcord)
#--------计算布局#---------
#-------计算网络布局-得到节点坐标=node#---------
result2 = ranSNEClusterG(cor = cor,nodeGroup =netClu,zoom = 3,layout = "circrand" )
node = result2[[1]]
head(node)
### nodeadd 节点注释的简单封装,便捷实用otu表格和分组文件进行注释
library(dplyr)
nodes <- node %>%
inner_join(Gru,by =c("elements" = "SampleID") )
#-----计算边#--------
edge = edgeBuild(cor = cor,plotcord = node)
head(edge)
### 出图
pnet <- ggplot() + geom_segment(aes(x = X1, y = Y1, xend = X2, yend = Y2,color = as.factor(wei_label)),
data = edge, size = 0.5) +
geom_point(aes(X1, X2,fill = Group),pch = 21, size = 5,data = nodes) +
scale_colour_brewer(palette = "Set1") + theme_void()
pnet
# ggsave("./1.png",pnet)
# pnet <- pnet + geom_text_repel(aes(X1, X2,label=elements),size=4, data = plotcord)
#--------计算布局#---------
#-------计算网络布局-得到节点坐标=node#---------
result2 = ranSNEClusterG(cor = cor,nodeGroup =netClu,zoom = 3,layout = "random" )
node = result2[[1]]
head(node)
### nodeadd 节点注释的简单封装,便捷实用otu表格和分组文件进行注释
library(dplyr)
nodes <- node %>%
inner_join(Gru,by =c("elements" = "SampleID") )
#-----计算边#--------
edge = edgeBuild(cor = cor,plotcord = node)
head(edge)
### 出图
pnet <- ggplot() + geom_segment(aes(x = X1, y = Y1, xend = X2, yend = Y2,color = as.factor(wei_label)),
data = edge, size = 0.5) +
geom_point(aes(X1, X2,fill = Group),pch = 21, size = 5,data = nodes) +
scale_colour_brewer(palette = "Set1") + theme_void()
pnet
# ggsave("./1.png",pnet)
# pnet <- pnet + geom_text_repel(aes(X1, X2,label=elements),size=4, data = plotcord)
—如果做细菌和真菌网络,仅仅关注细菌和真菌网络之间的关系
library(EasyMicrobiome)
# 导入细菌ps,通过相对丰度value1来过滤otu表格
ps16 = readRDS("../ori_data/bios-network_micro/16S/ps_16S.rds")
#导入真菌ps,通过相对丰度value1来过滤otu表格
psIT = readRDS("../ori_data/bios-network_micro/ITS/ps_ITS.rds")
合并细菌phloseq对象和真菌phyloseq对象
基于微生物网络,尤其是细菌真菌群落之间的关系,这里我们corBiostripe函数也提供了简便的方法用于细菌真菌群落之间网络的绘制。
ps.merge <- merge16S_ITS (ps16,psIT,N16s = 0.005,NITS = 0.005)
ps.mergeresult <- corBiostripe(ps = ps.merge)
#--提取相关矩阵
cor = result[[1]]
dim(cor)
#--分组信息提取
tax = as.data.frame((vegan_tax(ps.merge)))
netClu = data.frame(ID = row.names(tax),group = tax$filed)
head(netClu)#--------计算布局#---------
#-------计算网络布局-得到节点坐标=node#---------
result2 = PolygonClusterG(cor = cor,nodeGroup =netClu,zoom = 3,zoom2 = 1 )
node = result2[[1]]
head(node)
### nodeadd 节点注释的简单封装,便捷实用otu表格和分组文件进行注释
library(dplyr)
nodes <- node %>%
inner_join(netClu ,by =c("elements" = "ID") )
head(nodes)
#-----计算边#--------
edge = edgeBuild(cor = cor,plotcord = node)
head(edge)
### 出图
pnet <- ggplot() + geom_segment(aes(x = X1, y = Y1, xend = X2, yend = Y2,color = as.factor(wei_label)),
data = edge, size = 0.5) +
geom_point(aes(X1, X2,fill = group),pch = 21, size = 5,data = nodes) +
scale_colour_brewer(palette = "Set1") + theme_void()
pnet
附件:
如何构造phyloseq对象 以细菌和真菌群落为例子
#--对于微生物数据而言,许多数据都是和微生物组数据做一个联合
# 举例来说:细菌真菌网络,细菌,真菌,环境因子之间的网络,等。
# 所以我涉及了一个流程,用于合并细菌真菌结果,合并环境因子结果,用于网络绘制。
# --细菌phyloseq文件构建
metadata = read.delim("../ggClusterNet_Decument/ori_data/bios-network_micro/metadata.tsv")
head(metadata)
row.names(metadata) = metadata$SampleID
otutab = read.table("../ggClusterNet_Decument/ori_data/bios-network_micro/16S//otutab.txt", header=T, row.names=1, sep="\t", comment.char="", stringsAsFactors = F)
taxonomy = read.delim("../ggClusterNet_Decument/ori_data/bios-network_micro/16S//taxonomy.txt", header=T, row.names=1, sep="\t", comment.char="", stringsAsFactors = F)
head(taxonomy )
# 导入phyloseq(ps)对象
library(phyloseq)
ps = phyloseq(sample_data(metadata),otu_table(as.matrix(otutab), taxa_are_rows=TRUE), tax_table(as.matrix(taxonomy)))
ps
saveRDS(ps,"../ggClusterNet_Decument/ori_data/bios-network_micro/16S//ps_16S.rds")
# --真菌phyloseq文件构建
metadata = read.delim("../ggClusterNet_Decument/ori_data/bios-network_micro/metadata.tsv")
row.names(metadata) = metadata$SampleID
otutab = read.table("../ggClusterNet_Decument/ori_data/bios-network_micro/ITS/otuITS.txt",
header=T, row.names=1, sep="\t", comment.char="", stringsAsFactors = F)
taxonomy = read.delim("../ggClusterNet_Decument/ori_data/bios-network_micro/ITS/taxITS.txt",
header=T, row.names=1, sep="\t", comment.char="", stringsAsFactors = F)
# 导入phyloseq(ps)对象
library(phyloseq)
ps = phyloseq(sample_data(metadata),otu_table(as.matrix(otutab), taxa_are_rows=TRUE), tax_table(as.matrix(taxonomy)))
ps
saveRDS(ps,"../ggClusterNet_Decument/ori_data/bios-network_micro/ITS//ps_ITS.rds")
后记
目前就只有这几个layout函数支持二分网络的绘制,下一步,到时候会有更多的layout。