GO富集分析结果可视化集成方法 - 第1节
GO 富集分析概述:从基因列表到生物学故事
做生信分析的人,手里握着一堆差异基因,最常问的一个问题就是:“这些基因到底在干嘛?”
你拿到的是几百个上调、下调的基因名,但光看名字,很难说出个所以然来。这时候,就需要一个“翻译器”——把基因列表翻译成生物过程、细胞组分或者分子功能。嗯,这个“翻译器”就是 GO 富集分析。
我个人习惯把这个过程叫做“给基因组队”。每个基因都有它归属的“组织”和“职能”,GO 数据库就是记录了这些信息的巨大档案库。富集分析,说白了就是看你的基因集里,哪几个“职能”的成员特别多,多到不像是随机凑出来的。
GO 数据库:一个活着的基因词典
GO 全称 Gene Ontology,是一套结构化的、可计算的基因功能分类体系。它不是静态的,而是由全球科学家持续维护和更新的。
我第一次用 GO 的时候,以为它就是一套简单的分类标签。后来才发现,它的核心是一个有向无环图,每个节点代表一个术语,节点之间是层级关系。比如“细胞凋亡”是“程序性细胞死亡”的子类,“程序性细胞死亡”又是“细胞死亡”的子类。这种结构让分析既精细又可以在不同层级上做汇总。
在实际项目中,我们通常直接用 R 包或者在线工具去查询,但理解它的底层结构,对我们判断结果很有帮助。比如,如果你看到“定位”类术语在结果里扎堆,可能不是你关注的核心通路,而是基因普遍存在的属性,要慎重解读。
三大类别:BP、CC、MF
GO 把基因功能分成三个独立的 ontology,互不重叠。每个基因可能同时关联多个类别的多个术语。
我见过不少新手把 BP 和 MF 搞混,所以这里花点时间说清楚。
| 类别 | 全称 | 核心问题 | 典型例子 |
|---|---|---|---|
| BP | Biological Process | 这个基因参与了什么生物学过程? | DNA 修复、细胞周期调控、免疫应答 |
| CC | Cellular Component | 这个基因产物在细胞的哪个位置干活? | 线粒体膜、核仁、细胞质 |
| MF | Molecular Function | 这个基因产物在分子层面做什么? | 催化活性、转录因子结合、离子通道 |
富集分析的基本原理:超几何分布与 Fisher 精确检验
富集分析的核心逻辑很简单:你的基因列表里,某个 GO 术语出现的频率,是否显著高于随机期望?
怎么做呢?我们用一个 2×2 列联表来想。假设整个基因组有 N 个基因,其中 M 个属于“DNA 修复”这个 GO 术语。你手头有 n 个差异基因,其中 k 个属于“DNA 修复”。那问题就是:这 k 个基因是不是多得不正常?
统计上,这个问题可以用超几何分布来建模。说白了,就是从 N 个球里抽 n 个,其中属于特定颜色的球有 M 个,你抽到的 k 个属于这种颜色的概率有多大。
这个概率 p 值就是富集分析的显著性指标。p 值越小,说明这个 GO 术语越不太可能随机出现,越值得关注。
在实际中,我们通常用 Fisher 精确检验来做这件事,也可以用卡方检验做近似,但样本量小的时候,Fisher 更可靠。
嗯,这里要注意一个坑:因为同时检验了成百上千个 GO 术语,必须做多重假设检验校正。常用的方法有 BH(Benjamini-Hochberg)和 Bonferroni。我个人习惯用 BH,也就是 FDR(假发现率),因为它相对宽松一些,能保留更多可能真实的信号。如果样本量极小或者结果要求非常保守,再考虑 Bonferroni。
GO 富集分析的常见流程
说了这么多理论,我们来梳理一下标准流程。这样你拿到一个实际项目时,心里就有谱了。
- 获取差异基因列表:从 RNA-seq 或芯片数据中得到。一般是 p 值 + 差异倍数筛选出来的。
- 准备注释文件:需要知道每个基因对应的 GO 术语。常用数据库有 org.XX.eg.db 系列 R 包,或者用 DAVID、clusterProfiler 等工具。
- 执行富集检验:用超几何分布或 Fisher 精确检验,计算每个 GO 术语的 p 值。
- 校正 p 值:用 BH 或其他方法控制假阳性。
- 解读结果:筛选显著术语(通常 q-value < 0.05),进一步做可视化。
这里给出一个简单的 R 代码示例,用 clusterProfiler 包做 BP 的富集分析。
library(clusterProfiler)
library(org.Hs.eg.db)
# gene_list 是你的差异基因向量(Entrez ID)
# keyType 指定输入ID类型
# ont = "BP" 指定生物过程
ego <- enrichGO(gene = gene_list,
OrgDb = org.Hs.eg.db,
keyType = "ENTREZID",
ont = "BP",
pAdjustMethod = "BH",
pvalueCutoff = 0.05,
qvalueCutoff = 0.05)
# 查看结果
head(ego)
这段代码跑完,你会得到一个数据框,包含 GO ID、描述、富集基因数、p 值、校正后 p 值和基因列表。
对我来说,拿到结果后的第一步不是看 p 值,而是看富集基因数。如果一个术语富集了 200 个基因,而你的差异基因总共只有 300 个,那这个术语很可能太宽泛了,生物学意义有限。我通常会设置一个最小基因数(比如 5 个),再结合 p 值一起判断。
核心知识体系:一张图说清楚
下面我用一张 SVG 图把本章的核心逻辑串起来。你看了这张图,就应该能理解 GO 富集分析到底在解决什么问题。
从上往下看,流程很清楚:输入是你的差异基因,然后去 GO 数据库里找这些基因对应的 BP、CC、MF 信息,接着用统计检验算出哪些术语显著富集,最后做可视化解读。这里面每一步都有陷阱,后面几章我会一一展开。
我个人觉得,理解这张图比背下所有的 R 包语法更重要。因为工具会变,但底层逻辑不会变。你把这张图印在脑子里,无论以后换什么分析工具,都只是换了个壳而已。