通过前期的分析,我们确定了感兴趣的module,但是module中又含有几十甚至上百的基因,下一步需要进一步筛选hub gene。
WGCNA(3):基因模块与性状关联识别重要基因 - 简书 (jianshu.com)
差异基因,hub 基因以及关键基因的区别,可以去看这篇帖子:
关键基因和hub基因(生物网络角度) - 云+社区 - 腾讯云 (tencent.com)
1. 准备工作
导入前期数据,这里我选择了分步法构建网络的结果,大家可以根据自己的数据选择使用哪种方法构建网络。
# 设置工作目录
> setwd("D:/RNA-seq/WGCNA/mad0.3/cor 0.25")
# 载入WGCNA包
> library('WGCNA')
# 允许R语言以最大线程运行
> options(stringsAsFactors = FALSE)
> allowWGCNAThreads()
Allowing multi-threading with up to 4 threads.
# 载入第一步中的表达量和表型值
> lnames = load(file = "WGCNA0.3-dataInput.RData")
> lnames
# 载入第二步的网络数据
> lnames = load(file = "networkConstruction-stepByStep.RData")
> lnames
2. 筛选hub基因
2.1 筛选key module
- 在上一步基因模块与性状的热图中,可以明显看到和性状相关性最强的基因模块是哪一个,即为key module。
- 当然也可以反向找,感兴趣的基因在哪个module里,这个module就是key module。
由于我没有目的基因,所以这里都将与性状相关性最强的module当做Key module。
参考文章:WGCNA关键模块和hub基因筛选 - 简书 (jianshu.com)
2.2 筛选hub gene
在确定key module后,需要进一步确定hub gene,通常有三种方法。
a. 连接度 connectivity
参考材料:
https://horvath.genetics.ucla.edu/html/CoexpressionNetwork/Rpackages/WGCNA/Tutorials/Simulated-07-Membership.pdf
这里需要计算每个基因的连接度,在网络分析里通常称为degree。
- 整个网络的连接度是kTotal
- 模块连接度是kWithin,
- kOut=kTotal-kWithin
- kDiff=kIn-kOut=2*kIN-kTotal
# 这部分计算量还挺大的,如果基因数目多的话需要在Linux下计算
> ADJ=abs(cor(datExpr,use="p"))^6
> Alldegrees =intramodularConnectivity(ADJ, moduleColors)
> write.csv(Alldegrees, file = "intramodularConnectivity.csv")
绘制GS和连接度的相关性散点图:
## 这部分在专题(3)中计算过一次,因为没有保存,所以这里又重新计算
> nSamples = nrow(datExpr)
# 指定datTrait中感兴趣的一个性状,这里选择weight_g
> weight = as.data.frame(datTraits$weight_g)
> names(weight) = "weight"
# 各基因模块的名字(颜色)
> modNames = substring(names(MEs), 3)
# 计算MM的P值
> geneModuleMembership = as.data.frame(cor(datExpr, MEs, use = "p"))
> MMPvalue = as.data.frame(corPvalueStudent(as.matrix(geneModuleMembership), nSamples))
> names(geneModuleMembership) = paste("MM", modNames, sep="")
> names(MMPvalue) = paste("p.MM", modNames, sep="")
# 计算性状和基因表达量之间的相关性(GS)
> geneTraitSignificance = as.data.frame(cor(datExpr, weight, use = "p"))
> GSPvalue = as.data.frame(corPvalueStudent(as.matrix(geneTraitSignificance), nSamples))
> names(geneTraitSignificance) = paste("GS.", names(weight), sep="")
> names(GSPvalue) = paste("p.GS.", names(weight), sep="")
下面代码可以实现GS和degree的回归散点图:
> colorlevels=unique(moduleColors)
> pdf("GS vs. degree_weight.pdf",width = 14,height = 8)
# 布局。这个可以根据自己的module数目进行调整。我有20个module,所以这里设置了4行,每行5个图
> par(mfrow=c(4,5))
# 设置图形边界,四个数字分别对应下左上右
> par(mar = c(5,5,3,3))
> for (i in c(1:length(colorlevels)))
{
whichmodule=colorlevels[[i]];
restrict1 = (moduleColors==whichmodule);
verboseScatterplot(Alldegrees$kWithin[restrict1],
geneTraitSignificance[restrict1,1],
col=moduleColors[restrict1],
main=whichmodule,
xlab = "Connectivity", ylab = "Gene Significance", abline = TRUE)
}
> dev.off()
图中可以看出,weight这个性状中,green和brown两个module中的GS和连接度的相关性最好,这两个module中的hub gene有更高的GS。
b. KME (官方)
这个方法是WGCNA官方说明书推荐的,通过计算KME值(module eigengene-based connectivity)来衡量基因和模块的关系,通常选择|kME| >=阈值(0.8)来筛选出hub gene。
- kME = cor(x, ME),x是基因表达量
Hub genes are those that show most connections in the network as indicated by their high KME (eigengene connectivity) value.
# 基于准备工作,进行下列计算
# 计算KME值
> datKME=signedKME(datExpr, MEs, outputColumnName="kME_MM.")
> write.csv(datKME, "kME_MM.csv")
# 提取感兴趣的module,这里以lightyellow为例
> FilterGenes = abs(datKME$kME_MM.lightyellow) > 0.8
# 返回结果
> table(FilterGenes)
FilterGenes
FALSE TRUE
41584 41
# 共有41个gene,输出结果
> hubgene_lightyellow <- dimnames(data.frame(datExpr))[[2]][FilterGenes]
> write.csv(hubgene_lightyellow, "hubgene_KME_lightyellow.csv")
这里的41个gene里发现有不是这个module里的基因,修改如下:
> datKME=signedKME(datExpr, MEs, outputColumnName="kME_MM.")
> module = "lightyellow"
> column = match(module, modNames)
> moduleGenes = moduleColors==module
> lightyellow_module<-as.data.frame(dimnames(data.frame(datExpr))[[2]][moduleGenes])
> names(lightyellow_module)="genename"
> lightyellow_KME<-as.data.frame(datKME[moduleGenes,column])
> names(lightyellow_KME)="KME"
> rownames(lightyellow_KME)=lightyellow_module$genename
> FilterGenes = abs(lightyellow_KME$KME) > 0.8
> table(FilterGenes)
FilterGenes
FALSE TRUE
638 39
> lightyellow_hub<-subset(lightyellow_KME, abs(lightyellow_KME$KME)>0.8)
> write.csv(lightyellow_hub, "hubgene_KME_lightyellow.csv")
这里就只有39个了,都在module里。
c. MM & GS (常用)
在专题(3)中,我们绘制了MM vs. GS的散点图:
hub基因即为图中右上角的基因,生信技能树中有相关的介绍:
WGCNA得到模块之后如何筛选模块里面的hub基因 (qq.com)
即通过MM和GS进行筛选,这里的标准不固定,根据自己的数据进行更改。这里我用的标准是|GS|>0.2,|MM|>0.8。
# 选择lightyellow模块
> hub<- abs(geneModuleMembership$MMlightyellow)>0.8 & abs(geneTraitSignificance)>0.2
> table(hub)
hub
FALSE TRUE
41595 41
> hub<-as.data.frame(dimnames(data.frame(datExpr))[[2]][hub])
> write.csv(hub, "hubgene_GSMM_lightyellow_weight.csv")
这里发现,41个gene中有不属于这个module的基因,评论区的小伙伴们也遇到了这个问题,检查后修改如下:
> module = "lightyellow"
> column = match(module, modNames)
> moduleGenes = moduleColors==module
> lightyellow_module<-as.data.frame(dimnames(data.frame(datExpr))[[2]][moduleGenes])
> names(lightyellow_module)="genename"
> MM<-abs(geneModuleMembership[moduleGenes,column])
> GS<-abs(geneTraitSignificance[moduleGenes, 1])
> lightyellow_MMGS<-as.data.frame(cbind(MM,GS))
> rownames(lightyellow_MMGS)=lightyellow_module$genename
> hub_b<-abs(lightyellow_MMGS$MM)>0.8&abs(lightyellow_MMGS$GS)>0.2
> table(hub_b)
FALSE TRUE
638 39
> lightyellow_hub_b<-subset(lightyellow_MMGS, abs(lightyellow_MMGS$MM)>0.8&abs(lightyellow_MMGS$GS)>0.2)
> write.csv(lightyellow_hub_b, "hubgene_MMGS_lightyellow.csv")
这里和上面一样了,39个gene。
另外在这个地方,我发现|MM|>0.8和上面|KME|>0.8选出来的hub gene是一样的,所以这两个是一个东西吗?有没有了解的大佬能帮我解答一下,不胜感激。(这个问题已经解决,评论区有一个大佬有回答)
d. chooseTopHubInEachModule()
WGCNA中有一个自带函数,chooseTopHubInEachModule(),可以获得每个module中最核心的一个hub gene,注意这个结果每个模块只返回一个hub gene。
> HubGenes <- chooseTopHubInEachModule(datExpr,moduleColors)
> write.csv (HubGenes,file = "TopHubGenes_of_each_module.csv",quote=F)
e. weighted
在将模块信息导出为Cytoscape格式时,计算了每个基因的weight,也可以作为筛选hub gene的标准。
WGCNA(5):模块导出至其他可视化软件 - 简书 (jianshu.com)
> cyt = exportNetworkToCytoscape(modTOM,edgeFile =
paste("CytoscapeInput-edges-", paste(module, collapse="-"), ".txt", sep=""),
nodeFile = paste("CytoscapeInput-nodes-", paste(module, collapse="-"), ".txt", sep=""),
weighted = TRUE,
threshold = 0.1,
nodeNames = modProbes, nodeAttr = moduleColors[inModule])
- weighted = TRUE,计算weighted值
- threshold = 0.1,筛选weighted的阈值,对于我的数据,0.1时edge只有27个,调整到0.08,则有218个。
- 也可以直接通过weighted值排序,直接选择最高的一部分基因作为hub,例如nTop = 30。
> nTop = 30
> IMConn = softConnectivity(datExpr[, modProbes])
> top = (rank(-IMConn) <= nTop)
> cyt = exportNetworkToCytoscape(modTOM[top, top],edgeFile =
paste("CytoscapeInput-edges-", paste(module, collapse="-"), "_top30.txt", sep=""),
nodeFile = paste("CytoscapeInput-nodes-", paste(module, collapse="-"), ".txt", sep=""),
weighted = TRUE,
nodeNames = modProbes, nodeAttr = moduleColors[inModule])
这篇帖子的初衷,是我发现在找hub基因的时候,大家有各种各样的办法,但是好像没有一个人把所有的方法系统整理出来。我很想把所有的方法都试一遍,然后选择一个适合自己数据的最优解。
但是在整理的时候发现,这里面有很多东西我都不是很理解,包括WGCNA说明书后面模拟数据的一大部分分析,我都没有特别理解,只能把自己大概的理解分享出来,如果有错误的地方,非常希望懂行的老师同学批评指导,也希望有想法的小伙伴可以互相交流。