3. 常见错误类型总览与分类归纳

GFF 和 GTF 文件的错误,说白了就那几大类。我早期做基因组注释时,经常被各种报错搞得焦头烂额。后来接触的项目多了,发现大部分错误其实都逃不出这几类。咱们先把它们捋清楚,后面才好一个个地修。

3.1 按错误性质分四大类

我把遇到过的错误归纳成四类:结构错误、语义错误、坐标错误、属性错误。下面这张图能帮你快速建立整体印象。

GFF/GTF 常见错误类型分类 四大类错误 结构错误 语义错误 坐标错误 属性错误 列数不对   分隔符错 字段顺序乱   空行/注释 feature类型非法 strand/phase 值错误 start > end 跨染色体   负坐标 ID/Name 缺失 引号不匹配 错误来源 手动编辑 · 脚本生成BUG · 数据库导出 · 格式转换

3.2 结构错误——最基础也最容易犯

结构错误指的是文件格式本身不满足规范。我一开始手写 GTF 时,经常漏掉制表符或者多打个空格。你想想看,GFF/GTF 是严格的制表符分隔文件,每行必须有 9 列,一个都不能少。

常见表现:

  • 列数不对:某行只有 8 列或 10 列。原因往往是漏了第 9 列的属性,或者属性里含有制表符被误认为分隔符。
  • 分隔符错误:用了空格、逗号或者混合制表符。我见过用 Excel 导出的 GFF,制表符被替换成空格,解析直接崩掉。
  • 字段顺序错乱:比如 seqid 和 source 写反了。GFF 的前 8 列顺序是固定的,不能乱。
  • 空行或注释行:某些工具会把空行当有效行处理,导致解析中断。

一条正常 GFF 行的结构(9列):

seqid    source    type    start    end    score    strand    phase    attributes

每列之间必须用单个制表符(\t)分隔。

3.3 语义错误——工具认不出来的标签

结构对了,但内容不符合规范。我记得有一次用 GFF 跑 cufflinks,老是报“unknown feature type”。查了半天,原来是我把“CDS”写成了“Cds”——大小写敏感。

典型场景:

  • feature type 不在标准列表内:比如你写成“exon”而不是“exon”,或者用了自定义名称如“my_gene”,但下游工具只认“gene”。
  • strand 值错误:只允许“+”或“-”,偶尔允许“.”(表示未知)。填成“+”加号后面多个空格就直接报错。
  • phase 值超出范围:只能填 0、1、2 或“.”。我见过有人填了“-1”,解析器直接终止。

我的小经验:如果不确定 feature type 是否合法,去查看 GFF3 或 GTF2.2 的官方规范文档,里边有枚举列表。或者直接参考你的参考基因组注释文件里的 type 值。

3.4 坐标错误——注释位置不合理

坐标错误是最隐蔽的一类,因为程序不一定报错,但结果完全错位。我遇到过一个案例,注释说某个外显子从 1000 到 500,显然是 start 大于 end,但因为是 GFF 第三、四列,有些工具不会主动检查。

常见情形:

  1. start > end:正链上应该 start ≤ end。负链也一样,坐标顺序永远是 start(较小编号)在前。
  2. 坐标超出染色体长度:比如染色体 chr1 只有 2M,你写了个 5M 的位置。最好用序列文件(fasta)的 .fai 索引对照一下。
  3. 跨染色体错误:同一个基因的 exon 居然分布在 chr1 和 chr2 上?一般是组装时搞混了。
  4. 负坐标或零坐标:GFF 坐标必须是正整数,不能是 0 或负数。

警告:坐标错误会导致下游分析(比如 reads 计数、变体注释)产生荒谬结果。一定要做边界验证,别等跑完才知道。

3.5 属性错误——第九列的坑最多

属性列是自由格式,但也有很多规则。尤其是 GTF 和 GFF3 对属性列的语法要求不一样,混用就会出问题。

常见问题:

错误类型示例后果
键值对格式错误gene_id ABC(缺少“=”或引号)解析器无法提取 ID
引号不匹配gene_id "ABC(缺少闭合引号)整行属性被吞掉
ID 重复两个基因使用相同 ID工具合并或覆盖
必需属性缺失GTF 缺少 gene_id被标准工具拒绝
分号使用错误属性末尾多分号或少分号解析结果偏移

3.6 分类之间的重叠与联动

其实很多错误是交织的。比如你少写了一个制表符(结构错误),导致后面几列串位,进而出现 start 大于 end(坐标错误),同时还丢失了属性中的 gene_id(属性错误)。所以修错时最好从结构层面开始排查——结构对了,再检查语义,最后做坐标和属性验证。

我曾经踩过的坑:有一次脚本批量处理 200 个 GFF,只检查了列数没检查属性引号,结果跑完才发现一半样本的 gene_id 是空字符串。自那以后我写了一个校验脚本,把四大类错误全部自动化检测,成本低见效快。

3.7 分类总览表——快速定位错误类型

这张表把常见错误和它们所属的类别、严重程度以及修复重点列在一起,方便你对照排查。

错误描述所属类别严重程度修复重点
列数不足/过多结构错误致命检查分隔符,补全列
feature type 不合法语义错误致命对照规范,修改名称
start > end坐标错误致命交换或验证坐标
ID 重复属性错误严重生成唯一标识
引号缺失属性错误严重补全或修复引号
strand 值错误语义错误严重替换为 + / - / .
坐标超出染色体坐标错误严重比对 .fai 文件修正
属性键值对格式错属性错误中等重写属性字符串
空行/注释行结构错误中等删除或加 #
phase 值非法语义错误中等修改为 0/1/2/.

3.8 记住一条原则

不管什么错误,先确认第 9 列(属性列)的完整性。因为它最自由,最容易被误改。我个人的习惯是:写任何 GFF/GTF 处理脚本后,第一件事就是用格式校验工具跑一遍结构检查,再跑一遍属性检查。剩下的坐标和语义问题,通常靠写几个 awk 或者正则就搞定了。

一句话总结:结构决定能否被解析,语义决定工具认不认,坐标决定位置对不对,属性决定信息全不全。后面的章节,咱们针对每一类慢慢拆解修复方法。