注释矛盾:生物信息学中最隐蔽的“坑”

我入行第三年,接过一个癌症转录组项目。两批测序数据,分别用Ensembl和RefSeq注释,结果同一个基因的转录本数量差了3倍。当时我盯着差异表达列表发愣——这到底算不算差异?老板催着交报告,我只能硬着头皮解释。

从那以后,我就特别留意注释矛盾的问题。说白了,就是不同来源、不同版本、不同流程给你的基因/转录本/蛋白质编号不一样,导致后续分析没法对齐。

什么是注释矛盾

注释矛盾,指在整合多批次或多来源数据时,同一条生物实体(基因、转录本、蛋白质)被赋予了不一致的标识符、结构描述或功能标签。它不光是ID不同,还包括:

  • ID映射丢失:同一基因在不同数据库里ID不互通
  • 转录本结构不一致:同一基因在不同参考基因组上的外显子坐标不一样
  • 功能注释打架:同一个蛋白被标成“激酶”和“磷酸酶”

我会在下一个项目里避免这种问题——但说实话,很多人根本意识不到注释矛盾已经发生了。

常见场景归纳

我把这几年踩过的坑和同行交流的案例整理成了一张表。你对照着看,基本能覆盖80%的情况。

场景类型 典型矛盾 易发阶段
不同公共数据库间 Ensembl的ENST vs RefSeq的NM 交叉比对、Meta分析
同一数据库不同版本 GRCh37 vs GRCh38的坐标偏移 跨版本整合
不同注释工具 STAR vs HISAT2的转录本组装 定量、融合基因检测
多批次数据融合 芯片平台A vs RNA-seq平台B的探针ID 批次效应校正
自定义注释冲突 实验室内部GTF与公共注释重叠 新转录本注释

场景1:不同公共数据库间的“ID战争”

这个最经典。Ensembl和RefSeq使用两套完全不同的编号体系。你拿Ensembl的基因ID去NCBI查,大概率空手而归。反过来也一样。

我个人的习惯:能用一个数据库就死磕一个。如果非要用两个,必须提前建好对应表。别信那些号称“自动映射”的工具——我试过,至少会丢5%的对应关系。

举个例子,人类基因BRCA2:

Ensembl: ENSG00000139618
RefSeq: 675
UCSC: uc001vne.4

这三个ID指向同一个基因,但没有任何公共字段能直接连起来。你只能通过外部ID映射(比如Entrez Gene ID或HGNC symbol)来桥接。桥接也不是万能的——有些基因在某个数据库里根本不存在。

场景2:同一数据库的版本跨越

这个坑我印象最深。以前做TCGA数据整合,发现样本的参考基因组版本不统一:有的用GRCh37(hg19),有的用GRCh38(hg38)。同一个基因的起始位置差了上万bp。如果没有做liftOver,直接合并坐标算表达量,结果完全乱套。

为什么会这样?

  • 参考基因组版本升级:例如从hg19到hg38,染色体坐标整体重排
  • 基因模型修正:新版本可能改了某个基因的外显子边界
  • ID淘汰:老版本里的稳定ID在新版里被废弃
我曾经吃过一个亏:两个公开数据集分别标注了“hg19”和“GRCh37”,我还以为差别不大。结果发现Ensembl的GRCh37其实对应hg19,而UCSC的hg19和NCBI的GRCh37在某些region上表达不一致。最后浪费了一周时间做坐标重映射。

场景3:不同注释工具的“暗战”

高通量数据分析中,不同工具会给出不同的注释结果。比如做转录组定量时:

  • STAR + RSEM:基于STAR的splice-aware比对,再通过RSEM做定量,注释依赖给定的GTF
  • HISAT2 + StringTie:HISAT2比对后,StringTie会重新组装转录本,产生一套新的GTF

两套GTF可能合并出不同的基因模型。如果一个项目混合了两种定量结果,直接合并counts矩阵,你会发现同一个基因出现了多个不同ID的转录本。

# 软件A输出的转录本ID示例
transcript_id "ENST00000380152"
gene_id "ENSG00000012048"

# 软件B输出的转录本ID示例
transcript_id "STRT.1.1"   # StringTie自动编号
gene_id "STRG.1"           # 虚构的基因ID

除非你强制两者使用相同的GTF输入,否则结果基本没法直接对比。

最佳实践:在项目设计阶段就统一注释来源。比如全用GENCODE v34,所有工具都基于同一个GTF跑。

场景4:多批次数据融合时的注释冲突

这个场景做Meta分析、公共数据库整合的人经常碰到。假设你要合并来自GEO、ArrayExpress、SRA三个数据库的100个样本,它们的注释格式千奇百怪:

  • 部分使用Illumina探针ID(如ILMN_123456)
  • 部分使用RefSeq转录本ID(NM_001234)
  • 部分甚至只给了基因symbol

我见过一个极端案例:同一个探针ID在两个批次里映射到了不同的基因symbol。原因是平台更新了探针序列,但ID没有变。注释矛盾就这样悄无声息地混进了数据里。

批次 原始ID 映射基因A 映射基因B
批次1 ILMN_123456 TP53 —
批次2 ILMN_123456 BRCA1 —

这种矛盾如果不提前做探针序列比对,你永远发现不了。我一般会拉出每个批次的探针与参考基因组的比对结果,看看是否出现不一致的对齐位置。

场景5:自定义注释与公共注释的较量

很多课题组会发布自定义的注释文件,比如实验室自己预测的新基因、新转录本。把这些自定义GTF和公共GTF合并到一起时,名字空间冲突是家常便饭。

# 公共GTF中的基因
chr1     GENCODE  gene    1000    5000    .   +   .   gene_id "ENSG00000123456.10"

# 实验室自定义GTF中的基因
chr1     custom   gene    1000    5000    .   +   .   gene_id "GENE001"

如果两个文件都含有名为“GENE001”的基因,且坐标不同,合并后就会出现歧义。更麻烦的是,有些自定义注释故意保留“novel_gene_v1”这种名字,跟公共注释里某个旧版基因冲突。

避坑指南:自定义注释一定要加特殊前缀,比如“lab_”开头。同时记录每个自定义ID对应的公共ID(如果有的话)。这能省掉后续80%的烦恼。

注释矛盾的常见源头(思维导图)

我画了一张图,把这些场景串起来。你看一眼就能记住核心矛盾点在哪里。

注释矛盾的常见源头 注释矛盾 数据库差异 版本升级 注释工具不同 多批次融合 自定义注释冲突 箭头表示:不同源头最终汇聚到同一个注释矛盾问题 解决思路:统一参照、记录版本、提前映射

小结

注释矛盾不是小问题。它会导致:

  • 差异基因列表不可复现
  • Meta分析效应量估计偏差
  • 临床标志物筛选失败

我自己的做法是:项目开始前花1小时统一注释标准,胜过后面花1周去拆雷。遇到不确定性时,多查两个数据库的原始比对结果,别轻易相信ID对ID的自动映射。