这次我们来看一个专门讲解WGCNA(加权基因共表达网络分析)的视频教程。这个教程的目标很明确:让零基础的研究者,特别是生物信息学或生物医学领域的学生和科研人员,能够快速上手并独立完成一次完整的WGCNA分析。WGCNA本身是一个强大的R语言工具包,用于从高通量基因表达数据中挖掘基因模块(module),并探索模块与表型性状之间的关联,是寻找生物标志物和功能基因的常用方法。
对于初学者,WGCNA的学习曲线往往比较陡峭,涉及R语言编程、复杂的参数调整和结果解读。而这个视频教程的核心价值在于,它试图将这一复杂流程“傻瓜化”,通过一个完整的实战案例,带你走通从数据预处理、网络构建、模块识别到结果可视化的全步骤。本文将基于这个教程的核心思路,为你拆解WGCNA分析的关键环节、环境准备、代码实操以及避坑指南,让你看完就能动手复现。
1. 核心能力速览:WGCNA教程能帮你做什么?
在深入代码之前,我们先快速了解通过这个教程你能掌握哪些核心技能,以及需要准备什么。
| 能力项 | 说明 |
|---|---|
| 分析目标 | 从基因表达矩阵(如RNA-seq、芯片数据)中构建加权共表达网络,识别基因模块,并关联临床性状,挖掘关键基因。 |
| 核心技术栈 | R语言 + WGCNA R包。这是分析的绝对核心,所有计算和可视化都基于此。 |
| 硬件门槛 | 极低。WGCNA是CPU和内存密集型计算,对显卡无要求。普通笔记本电脑即可运行,但大样本量(如数百个样本)或全基因组基因(数万个)分析需要较大内存(建议16GB以上)。 |
| 输入数据 | 一个表达量矩阵(行是基因,列是样本),以及一个样本性状表(可选,但强烈建议)。数据需要预先进行标准化和过滤。 |
| 主要输出 | 1. 基因模块划分结果(模块特征基因、模块成员关系)。 2. 模块-性状关联热图与显著性P值。 3. 关键模块内基因的网络图(TOM图)。 4. 与性状最相关模块的基因列表,用于后续功能富集分析。 |
| 学习成果 | 能够独立完成一次标准WGCNA分析流程,理解核心参数(如软阈值power)的选择,并能解读主要结果图表。 |
| 适合人群 | 生物信息学初学者、需要用到WGCNA的医学生物领域研究生、科研人员。 |
2. WGCNA分析流程全景与适用场景
WGCNA不是一个“黑箱”工具,理解其整体流程是成功分析的第一步。一个标准的流程通常包括以下步骤:
- 数据准备与清洗:整理表达矩阵和性状数据,处理缺失值,进行样本聚类检查离群样本。
- 软阈值(Soft Thresholding Power)选择:这是构建无尺度网络的关键,目的是使网络连接度分布接近无尺度拓扑结构。
- 构建加权共表达网络与识别模块:基于选定的软阈值,计算基因间的相关性,进而得到邻接矩阵、拓扑重叠矩阵(TOM),并利用动态树切割法识别基因模块。
- 关联模块与外部性状:计算每个模块的特征向量(Module Eigengene, ME)与样本性状之间的相关性,找出与目标性状显著相关的模块。
- 结果解读与可视化:生成模块-性状关联热图、绘制模块内基因关系网络图(TOM图)、导出关键模块的基因进行后续分析(如GO/KEGG富集)。
适用场景:
- 寻找疾病相关的关键基因模块:例如,在癌症组学数据中,找到与肿瘤分期、生存期、药物敏感性等临床性状最相关的基因共表达模块。
- 探索生物学过程:在非模式生物或特定处理条件下,探索共表达的基因群,推测其共同功能。
- 作为下游分析的输入:将WGCNA识别出的关键模块基因,作为蛋白互作网络(PPI)分析、机器学习特征筛选的输入,缩小研究范围。
使用边界与注意事项:
- 数据质量要求高:WGCNA对输入数据的质量非常敏感。样本量不宜过小(一般建议至少15-20个以上),基因表达量需要经过合适的标准化和过滤(低表达基因建议剔除)。
- 计算资源消耗:构建全基因的TOM矩阵时,内存消耗与基因数量的平方成正比。对于数万个基因,可能需要数十GB内存。可以考虑使用
blockwiseModules函数进行分块计算以降低内存压力。 - 生物学解释是关键:WGCNA给出的是统计关联,模块与性状的相关性并不等同于因果关系。必须结合生物学知识对关键模块进行功能富集分析,才能得出有意义的结论。
3. 环境准备与R包安装
工欲善其事,必先利其器。在开始分析前,你需要一个可运行的R环境。
3.1 R与RStudio安装
- R语言:前往 R官网 下载并安装最新版本。
- RStudio:推荐使用 RStudio IDE ,它提供了友好的代码编辑、环境和图形界面。
3.2 安装必要的R包
打开RStudio,在控制台(Console)中依次运行以下命令安装核心包。由于部分包依赖Bioconductor,需要先配置好镜像源以加速下载。
# 设置CRAN和Bioconductor镜像(以清华镜像为例,可替换为其他国内镜像) options(repos = c(CRAN = "https://mirrors.tuna.tsinghua.edu.cn/CRAN/")) if (!requireNamespace("BiocManager", quietly = TRUE)) install.packages("BiocManager") BiocManager::install(ask = FALSE, site_repository = "https://mirrors.tuna.tsinghua.edu.cn/bioconductor") # 安装WGCNA及其依赖包。WGCNA对R版本可能较敏感,若安装失败可尝试从源码安装。 install.packages(c("WGCNA", "reshape2", "ggplot2", "ggdendro", "RColorBrewer")) # 安装其他常用辅助包 install.packages(c("dplyr", "tidyverse", "corrplot", "pheatmap")) # 加载包检查是否安装成功 library(WGCNA)注意:WGCNA包的安装可能需要一些时间,并且可能需要系统安装一些编译工具(如在Windows上可能需要Rtools)。如果遇到编译错误,请根据提示安装相应的系统工具。
4. 数据准备:表达矩阵与性状表
这是所有分析的起点。假设你有一个RNA-seq差异表达分析后的基因表达量矩阵(例如TPM或FPKM值)。
4.1 表达矩阵(datExpr)
表达矩阵通常是一个数据框(data.frame)或矩阵(matrix),行名(rownames)为基因ID(如Gene Symbol或Ensembl ID),列名(colnames)为样本ID。
# 假设你的表达矩阵文件是“gene_expression_matrix.csv” # 格式示例: # Gene,Sample1,Sample2,Sample3,... # TP53,10.5, 12.1, 8.7,... # BRCA1,5.2, 6.8, 4.9,... datExpr <- read.csv("gene_expression_matrix.csv", row.names = 1, check.names = FALSE) # row.names=1 表示第一列是行名 # check.names=FALSE 防止R修改列名(如将‘-’改为‘.’) # 查看数据维度:基因数 x 样本数 dim(datExpr) # 确保数据是数值型矩阵 datExpr <- as.matrix(datExpr)4.2 性状数据(datTraits)
性状数据也是一个数据框,行名(rownames)为样本ID,与datExpr的列名完全一致且顺序匹配,每一列代表一个临床或实验性状(如年龄、分组、病理评分等)。
# 假设性状文件是“clinical_traits.csv” # 格式示例: # Sample,Group,Age,Tumor_Stage # Sample1,Control,45,II # Sample2,Disease,58,III # ... datTraits <- read.csv("clinical_traits.csv", row.names = 1, check.names = FALSE) # 确保样本顺序与表达矩阵一致 if(!identical(colnames(datExpr), rownames(datTraits))) { stop("样本ID在表达矩阵和性状表中不匹配!") }4.3 数据预处理与离群样本检查
在构建网络前,必须检查数据质量并移除离群样本。
# 1. 样本聚类检查离群值 sampleTree <- hclust(dist(t(datExpr)), method = "average") # 绘制样本聚类树 par(cex = 0.6) plot(sampleTree, main = "Sample clustering to detect outliers", sub="", xlab="") # 如果发现明显远离其他样本的离群枝,可以手动设定一个高度阈值进行切割 # 例如,切割高度为150 clust <- cutreeStatic(sampleTree, cutHeight = 150, minSize = 10) # 保留属于大簇的样本(clust == 1) keepSamples <- (clust == 1) datExpr <- datExpr[, keepSamples] datTraits <- datTraits[keepSamples, ]5. 核心步骤一:软阈值(Power)选择
这是WGCNA中最关键且必须理解的一步。软阈值(β值)用于将基因间的相关系数(Pearson correlation)进行幂次运算(cor^β),以构建一个符合无尺度网络特性的邻接矩阵。目标是选择一个使网络近似无尺度拓扑结构的β值。
# 启用多线程以加速计算(可选) enableWGCNAThreads(nThreads = 4) # 设置一组候选的power值 powers <- c(1:10, seq(12, 30, by = 2)) # 调用函数进行软阈值选择分析 sft <- pickSoftThreshold(datExpr, powerVector = powers, verbose = 5, networkType = "unsigned") # 可视化结果 par(mfrow = c(1,2)) # 图1:无尺度拓扑拟合指数(Scale Free Topology Model Fit)与power的关系 plot(sft$fitIndices[,1], -sign(sft$fitIndices[,3]) * sft$fitIndices[,2], xlab = "Soft Threshold (power)", ylab = "Scale Free Topology Model Fit, signed R^2", type = "n", main = paste("Scale independence")) text(sft$fitIndices[,1], -sign(sft$fitIndices[,3]) * sft$fitIndices[,2], labels = powers, cex = 0.9, col = "red") abline(h = 0.90, col = "red") # 通常以R^2 > 0.9作为参考线 # 图2:平均连接度(Mean Connectivity)与power的关系 plot(sft$fitIndices[,1], sft$fitIndices[,5], xlab = "Soft Threshold (power)", ylab = "Mean Connectivity", type = "n", main = paste("Mean connectivity")) text(sft$fitIndices[,1], sft$fitIndices[,5], labels = powers, cex = 0.9, col = "red")如何选择power值?
- 首要标准:选择使无尺度拓扑拟合指数(左图红点)首次达到或超过0.9(红色参考线)的power值。这表示网络已具有较好的无尺度特性。
- 次要标准:在满足首要标准的前提下,选择平均连接度(右图)相对较高的power值。连接度过低意味着网络太稀疏。
- 常见范围:对于大多数转录组数据,power值通常在6到12之间。上图中,假设power=6时R^2>0.9,且平均连接度尚可,则选择
softPower <- 6。
6. 核心步骤二:构建共表达网络与识别模块
选定softPower后,即可一步构建网络并识别模块。这里使用blockwiseModules函数,它能自动分块处理大数据,避免内存溢出。
# 设置选定的软阈值 softPower <- 6 # 一步法构建网络并识别模块 net <- blockwiseModules(datExpr, power = softPower, networkType = "unsigned", # 无符号网络(考虑正负相关) TOMType = "unsigned", minModuleSize = 30, # 最小模块基因数,可根据数据调整 mergeCutHeight = 0.25, # 模块合并阈值,值越大合并越多 numericLabels = TRUE, # 模块用数字标签 pamRespectsDendro = FALSE, saveTOMs = TRUE, # 保存TOM矩阵,供后续可视化 saveTOMFileBase = "MyNetworkTOM", verbose = 3) # 查看模块数量及大小 table(net$colors) # 模块颜色标签(将数字转换为颜色,灰色模块通常为未归入任何模块的基因) moduleColors <- labels2colors(net$colors) table(moduleColors)关键参数解析:
minModuleSize:每个模块最少包含的基因数。太小会产生过多琐碎模块,太大可能丢失生物学意义。通常设置在30-100之间。mergeCutHeight:模块合并的阈值。基于模块特征基因的相关性进行层次聚类,切割高度高于此阈值的模块将被合并。降低此值会得到更多、更小的模块。numericLabels:设为FALSE则直接用颜色命名模块(如“blue”,“red”),更直观。
7. 核心步骤三:关联模块与外部性状
识别出模块后,下一步是找出哪些模块与我们关心的样本性状(如疾病状态、治疗反应)最相关。
# 计算模块特征基因(Module Eigengene, ME) MEs0 <- moduleEigengenes(datExpr, moduleColors)$eigengenes # 对MEs进行排序,使其与模块颜色顺序一致 MEs <- orderMEs(MEs0) # 计算模块特征基因与性状的相关性及P值 moduleTraitCor <- cor(MEs, datTraits, use = "p") moduleTraitPvalue <- corPvalueStudent(moduleTraitCor, nSamples = ncol(datExpr)) # 绘制模块-性状关联热图 textMatrix <- paste(signif(moduleTraitCor, 2), "\n(", signif(moduleTraitPvalue, 1), ")", sep = "") dim(textMatrix) <- dim(moduleTraitCor) par(mar = c(6, 8.5, 3, 3)) labeledHeatmap(Matrix = moduleTraitCor, xLabels = names(datTraits), yLabels = names(MEs), ySymbols = names(MEs), colorLabels = FALSE, colors = blueWhiteRed(50), textMatrix = textMatrix, setStdMargins = FALSE, cex.text = 0.5, zlim = c(-1,1), main = paste("Module-trait relationships"))结果解读: 热图中每个单元格显示了模块(行)与性状(列)之间的相关系数和P值(括号内)。例如,“MEblue”模块与“Disease”性状的相关系数为0.85 (P<0.01),表明蓝色模块的基因表达模式与疾病状态高度正相关。你需要重点关注那些相关系数绝对值高且P值显著的模块,它们是你后续深入分析的目标。
8. 结果可视化与深入挖掘
8.1 模块内基因关系可视化(TOM图)
对于关键模块,可以绘制其拓扑重叠矩阵(TOM)的热图,直观展示模块内基因的共表达紧密程度。
# 选择你感兴趣的关键模块,例如“blue”模块 module <- "blue" # 获取属于该模块的基因 genes <- colnames(datExpr) inModule <- (moduleColors == module) modGenes <- genes[inModule] # 加载之前保存的TOM矩阵(注意:需要与构建网络时使用相同的power和基因顺序) load(file = "MyNetworkTOM-block.1.RData") # 文件名根据实际保存情况调整 # TOM矩阵通常名为`TOM` dim(TOM) # 提取该模块对应的TOM子矩阵 modTOM <- TOM[inModule, inModule] dimnames(modTOM) <- list(modGenes, modGenes) # 绘制热图(此步骤计算量大,基因多时可对矩阵进行抽样或仅绘制部分) library(pheatmap) pheatmap(modTOM, cluster_rows = TRUE, cluster_cols = TRUE, treeheight_row = 0, treeheight_col = 0, color = colorRampPalette(c("white", "blue"))(50), main = paste("TOM heatmap of", module, "module"), show_rownames = FALSE, show_colnames = FALSE)8.2 导出关键模块基因列表
将与目标性状最相关的模块基因导出,用于后续功能富集分析(如DAVID、Metascape、clusterProfiler)。
# 假设我们关注与“Disease”性状最相关的“blue”模块 trait <- "Disease" module <- "blue" # 获取模块内所有基因 moduleGenes <- (moduleColors == module) # 创建一个数据框,包含基因名、模块颜色、以及与目标性状的相关性(GS)和显著性(p.GS) geneInfo0 <- data.frame(Gene = colnames(datExpr), ModuleColor = moduleColors, stringsAsFactors = FALSE) # 计算基因显著性(Gene Significance, GS),即基因表达与性状的相关性 GS <- as.numeric(cor(datExpr, datTraits[, trait], use = "p")) GenePvalue <- as.numeric(corPvalueStudent(GS, nSamples = ncol(datExpr))) geneInfo0$GS <- GS geneInfo0$p.GS <- GenePvalue # 筛选出目标模块的基因,并按GS绝对值排序 geneInfo <- geneInfo0[moduleGenes, ] geneInfo <- geneInfo[order(-abs(geneInfo$GS)), ] # 保存到CSV文件 write.csv(geneInfo, file = paste0(module, "_Module_Genes_GS_for_", trait, ".csv"), row.names = FALSE)9. 常见问题与排查方法
WGCNA分析流程长,参数多,新手常会遇到各种报错或结果不理想的情况。下表汇总了常见问题及解决思路。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
pickSoftThreshold运行极慢或内存不足 | 基因数量过多(>20000)。 | 检查dim(datExpr)。 | 1.过滤低表达/低方差基因:在分析前,使用goodSamplesGenes或根据方差过滤掉大部分不表达的基因。2.使用 blockwiseModules:它专为大数据设计。 |
| 软阈值选择图中,所有power的R^2都很低(<0.8) | 1. 数据噪声太大。 2. 样本量太少。 3. 基因表达量未正确标准化。 | 1. 检查样本聚类图是否有严重离群样本。 2. 检查样本量。 3. 回顾表达矩阵预处理流程。 | 1. 严格过滤样本和基因。 2. 增加样本量(如果可能)。 3. 尝试不同的标准化方法。如果仍无法改善,需谨慎解读结果,或考虑数据本身是否适合WGCNA。 |
| 识别出的模块数量极少(如只有1-2个) | 1.mergeCutHeight参数设置过高。2. minModuleSize设置过大。3. 软阈值 power过高,导致网络过于稠密。 | 1. 检查net对象中模块数量table(net$colors)。2. 回顾参数设置。 | 1. 降低mergeCutHeight(如从0.25降至0.15)。2. 适当减小 minModuleSize(如从50降至30)。3. 重新评估软阈值选择,尝试稍低的power值。 |
| 模块-性状关联热图中没有显著相关的模块 | 1. 选择的性状与基因表达确实无强关联。 2. 模块识别不理想。 3. 性状数据为分类变量未做合适处理。 | 1. 检查性状与表达数据的生物学合理性。 2. 查看模块特征基因(MEs)本身是否具有明显模式。 | 1. 尝试其他性状或对性状进行数值化转换。 2. 调整网络构建参数,重新识别模块。 3. 对于分类性状,确保其在 datTraits中是数值型(如Control=0, Disease=1)。 |
运行blockwiseModules时报错:“Error in …” | 1. 内存不足。 2. 输入数据格式不对。 3. 函数参数冲突。 | 1. 查看错误信息。 2. 检查 datExpr是否为数值矩阵,有无NA/Inf值。 | 1. 尝试设置更大的内存,或使用blockwiseModules的maxBlockSize参数减小分块大小。2. 使用 goodSamplesGenes(datExpr)检查并清理数据。3. 仔细阅读 ?blockwiseModules帮助文档,确认参数用法。 |
| 后续分析(如GO/KEGG)输入基因列表太长 | 关键模块包含基因过多(如>1000)。 | 查看geneInfo数据框的行数。 | 1. 利用**基因显著性(GS)**进行排序,只取GS最高(即与性状最相关)的前几百个基因进行富集分析。 2. 计算模块成员度(MM),选取MM高的核心基因。 |
10. 最佳实践与进阶建议
完成一次基础分析后,以下建议能帮助你更稳健、更深入地使用WGCNA。
- 从小数据开始练习:首次学习时,不要直接用自己数万个基因、上百个样本的全量数据。使用教程提供的示例数据或从GEO数据库下载一个样本量适中(~30个样本,~10000个基因)的数据集进行全流程演练,熟悉每一步的输出和参数影响。
- 保存关键中间结果:
pickSoftThreshold的结果sft、网络对象net、以及TOM矩阵(saveTOMs=TRUE时)都非常占用计算资源。务必保存为R数据文件(.RData),避免重复计算。save(sft, net, moduleColors, MEs, file = "WGCNA_network_construction_results.RData") - 理解并尝试不同的网络类型:本文演示的是
networkType = "unsigned"(无符号网络,考虑所有相关性)。还有signed(有符号网络,只考虑正相关)和signed hybrid。不同网络类型适用于不同的生物学假设,可以比较其结果差异。 - 深入挖掘关键模块:
- 模块内连通性(Intramodular Connectivity, kWithin):在关键模块内,识别处于网络中心位置(高连通性)的“枢纽基因(Hub Genes)”,它们往往具有更重要的生物学功能。
- 模块成员度(Module Membership, MM):计算模块内每个基因与模块特征基因(ME)的相关性,MM值越接近1或-1,说明该基因与该模块的表达模式越一致。
- 与下游分析无缝衔接:WGCNA的结果是上游。导出的关键基因列表应立刻导入功能富集分析工具(如R包
clusterProfiler)、蛋白互作网络分析工具(如STRING、Cytoscape)或机器学习模型中进行验证和深入挖掘。 - 版本控制与代码可复现:使用R Markdown或Jupyter Notebook记录你的整个分析过程,包括每一步的代码、参数设置和结果解读。这不仅能让你日后快速复现,也是科研可重复性的基本要求。
WGCNA是一个功能强大但需要耐心调参的工具。第一次成功运行出模块-性状关联热图并找到有意义的信号,会带来巨大的成就感。这个教程视频的价值就在于压缩了漫长的试错过程,提供了一个经过验证的、可运行的代码框架。你的任务是在此框架上,替换成自己的数据,理解每个参数的意义,并根据自己数据的特点进行微调。记住,生物学问题的驱动和合理的实验设计永远是第一位的,WGCNA是帮助你发现规律的显微镜,而不是制造规律的机器。