有什么现成的工具可以对gff注释的gene、exon、mrna等元件的ID进行重新编号吗?
تم الإنشاء في: ٢١ ديسمبر ٢٠٢٥
تمت الإجابة باستخدام GPT-5.2 Thinking بواسطة Chat01
تم الإنشاء في: ٢١ ديسمبر ٢٠٢٥
تمت الإجابة باستخدام GPT-5.2 Thinking بواسطة Chat01
有什么现成的工具可以对gff注释的gene、exon、mrna等元件的ID进行重新编号吗?
有的,而且基本上AGAT是最“现成/省心”的一套(专门处理 GFF/GTF 的修复、标准化、改 ID 等)。
ID= 重新编号/改前缀agat_sp_manage_IDs.pl(你问的“重新编号”基本就用它)它会遍历 GFF3,把各类 feature 的 ID 重写成新的编号;默认类似 featureType-Number,也可以指定前缀、起始编号、以及不同风格的 ID。(AGAT)
常用点:
-p level2 / -p exon / -p cds 等(也可以 all)(AGAT)--prefix(AGAT)--nb(AGAT)--type_dependent(gene1/mRNA1/exon1…而不是全局一个流水号)(AGAT)--tair / --ensembl(AGAT)示例(按 AGAT 文档给的写法):
bashagat_sp_manage_IDs.pl --gff file.gff -p level2 -p cds -p exon -o out.gff
(AGAT)
AGAT 的 _sp_ 系列工具会先把文件标准化:补缺失的 parent feature、补 ID/Parent 这些必需属性、修复 ID 唯一性等。(GitHub Pages)
如果你拿到的是各种软件拼出来的 GFF(ID/Parent 不全、层级不稳),建议先跑一遍标准化再重编号。
agat_sq_manage_IDs.pl它的描述很明确:改 ID,并且会把受影响的 Parent 也一起同步改掉,避免断链。(AGAT)
如果你不关心特定编号规则,只想快速“去重并保持层级关系”,这是很实用的一招。
seqrenamer (sr encode/decode)这是个 Python 工具,支持 fasta/gff3/tsv/csv 的 ID 改名,也能用映射表做替换。它也强调 GFF3 里需要同时更新 ID 和 Parent 字段;并且对 GFF3 的“ID列”只支持 1-1 映射(因为多 Parent 会变得组合爆炸)。(GitHub)
适用场景:你已经有一张“旧ID ↔ 新ID”的表,想严格按表替换,而不是自动编号。
gffread 可以把注释“重写成更简洁的 GFF3”、并用 -E 暴露潜在格式问题。(GitHub)
但它的定位更像 cleanup/validation,不是专门的“批量重编号器”。
agat_sp_manage_IDs.pl。(AGAT)agat_sq_manage_IDs.pl。(AGAT)_sp_ 的标准化思路处理更稳(AGAT 会补 parent、补 ID/Parent、修复唯一性等)。(GitHub Pages)如果你愿意贴一小段(几行)你的 GFF3(gene/mRNA/exon 的那几行就够),我可以直接告诉你用 AGAT 的哪组参数最贴合你想要的编号风格(比如“基因按染色体递增”、“每个 gene 下 exon 从 1 计数”、“TAIR/Ensembl 风格”等)。
我想用AGAT实现基因按染色体递增。
可以,用 AGAT 做“gene 按染色体(seqid)+ 坐标递增”的关键点其实是两步:
agat_sp_manage_IDs.pl,它会把 ID 重写成“featureType-Number”或“prefix+Number”等形式(支持 --prefix / --nb / --ensembl / --type_dependent / --tair 等)(agat.readthedocs.io)agat_convert_sp_gxf2gxf.pl 的定位就是把任意 GTF/GFF 修复并输出“完整、已排序”的文件(GitHub)。而 tabix sorting 的用法在 AGAT 的“Topological sorting”页里给了示例:(agat.readthedocs.io)
bash# 生成带 --tabix 行为的本地配置(会在当前目录放一个 agat_config.yaml) agat config --expose --tabix # 输出排序后的 GFF(拓扑顺序 + 染色体/坐标顺序) agat_convert_sp_gxf2gxf.pl --gff in.gff3 -o in.sorted.gff3
这里的排序规则(AGAT --tabix)在文档里写的是:by chromosomes, by gene position, by type…(agat.readthedocs.io)
bashagat_sp_manage_IDs.pl \ --gff in.sorted.gff3 \ --prefix MyGene \ --type_dependent \ -p gene -p level2 -p level3 \ -o in.renum.gff3
--prefix:ID 会变成 $prefix.$letterCode.Number 这种形式(agat.readthedocs.io)--type_dependent:gene/mRNA/exon/CDS 各自从 1 计数(不然会混在一个流水号里)(agat.readthedocs.io)-p:限定要处理的 feature(可直接写 gene、或写 level2/level3 这类集合)(agat.readthedocs.io)--ensembl(agat.readthedocs.io)--nb 1(默认就是 1)(agat.readthedocs.io)AGAT 的 agat_sp_manage_IDs.pl 本身提供 按 feature type 分开计数(--type_dependent),但不提供“按 seqid 自动重置计数”的开关(文档选项里没有)。(agat.readthedocs.io)
要做到“每条染色体从 1 重新编号”,最稳的是按染色体拆开分别跑,再按染色体顺序拼回去:
bash# 先排序/标准化(推荐) agat config --expose --tabix agat_convert_sp_gxf2gxf.pl --gff in.gff3 -o in.sorted.gff3 # 按染色体依次处理(示例:chr01..chr12;你也可以换成自己的列表) for chr in chr01 chr02 chr03 chr04 chr05 chr06 chr07 chr08 chr09 chr10 chr11 chr12; do awk -v C="$chr" 'BEGIN{FS=OFS="\t"} /^#/ || $1==C' in.sorted.gff3 > "$chr.gff3" agat_sp_manage_IDs.pl \ --gff "$chr.gff3" \ --prefix "$chr" \ --type_dependent \ -p gene -p level2 -p level3 \ --nb 1 \ -o "$chr.renum.gff3" done # 合并时注意:GFF header(##gff-version 等)最好只保留一次 (head -n 1 chr01.renum.gff3; grep -v '^#' chr*.renum.gff3) > in.renum.byChr.gff3
chr1 chr2 ... chr10,很多工具(包括 tabix 生态)默认是字符串序,会出现 chr1 chr10 chr2。AGAT 文档只说 “by chromosomes”(agat.readthedocs.io),不保证“自然数值顺序”。chr01 chr02 ...(零填充),或者像上面方案 B 那样你自己给出染色体顺序列表。--tair(示例里会生成类似 AT1G01020 这种带 chr 编号的 ID)(agat.readthedocs.io)。但它更偏 TAIR 约定,是否完全符合你想要的命名规则要看你的 seqid 形式。如果你把 **一小段 GFF3(包含 2-3 个 gene/mRNA/exon/CDS)**贴出来,并告诉我你想要的 ID 长相(比如 chr01g000001 还是 Gene000001 / AT1G01010),我可以直接给你一条最贴合的命令组合。
Chr1A DB gene 5432890 5433534 . - . ID=TraesMM902_1A011200
Chr1A DB mRNA 5432890 5433534 . - . ID=TraesMM902_1A011200.1;Parent=TraesMM902_1A011200
Chr1A DB CDS 5432890 5433534 100 - 0 ID=TraesMM902_1A011200.1.cds1;Name=TraesCS1A03G0019600.1_CS;Parent=TraesMM902_1A011200.1;Target=TraesCS1A03G0019600.1_CS 645 1 .
Chr1A DB exon 5432890 5433534 100 - . ID=TraesMM902_1A011200.1.exon1;Name=TraesCS1A03G0019600.1_CS;Parent=TraesMM902_1A011200.1;Target=TraesCS1A03G0019600.1_CS 645 1 .
Chr1A DB gene 19337050 19337538 . + . ID=TraesMM902_1A034100
Chr1A DB mRNA 19337050 19337538 . + . ID=TraesMM902_1A034100.1;Parent=TraesMM902_1A034100
Chr1A DB CDS 19337050 19337538 100 + 0 ID=TraesMM902_1A034100.1.cds1;Name=TraesCS1A03G0075700.1_CS;Parent=TraesMM902_1A034100.1;Target=TraesCS1A03G0075700.1_CS 489 1 .
Chr1A DB exon 19337050 19337538 100 + . ID=TraesMM902_1A034100.1.exon1;Name=TraesCS1A03G0075700.1_CS;Parent=TraesMM902_1A034100.1;Target=TraesCS1A03G0075700.1_CS 489 1 .
Chr1B . gene 8684597 8724620 . - . ID=TraesMM902_1B007600
Chr1B . mRNA 8684597 8724620 . - . ID=TraesMM902_1B007600.1;Parent=TraesMM902_1B007600
可以的:agat_sp_manage_IDs.pl 是“按输入文件出现顺序”依次重写 ID,所以你要实现“gene 按染色体递增”,关键是 先把 GFF 按染色体 + gene 坐标排序,再重编号。
下面给你一套对你这种结构(gene → mRNA → exon/CDS)最稳的流程。
AGAT 文档里称为 tabix sorting:by chromosomes、by gene position、by type…,并且会在需要时修复/标准化。 (AGAT Documentation)
bash# 生成本地配置,并启用 tabix sorting agat config --expose --tabix # 输出排序后的(且更规范的)GFF3 agat_convert_sp_gxf2gxf.pl --gff in.gff3 -o in.sorted.gff3
这个步骤会让你的记录变成:Chr1A 的 gene 从小到大排、然后 Chr1B…(按 seqid 的排序规则来)。文档示例也就是用 agat config --expose --tabix 配合 agat_convert_sp_gxf2gxf.pl 得到 tabix sorting 的输出。 (AGAT Documentation)
⚠️注意:tabix/很多排序默认是按染色体名字符串序。像
Chr1A/Chr1B/Chr1D通常没问题;但如果你有Chr1和Chr10这种,字符串序会把Chr10排在Chr2前面——这时要么把染色体名改成零填充(Chr01…Chr10),要么用下面“按染色体拆分重编号”的方案自定义顺序。
agat_sp_manage_IDs.pl 依排序结果重写 ID(实现递增编号)agat_sp_manage_IDs.pl 会遍历 feature 重写 ID=;默认 featureType-Number,如果给 --prefix,则变成 $prefix.$letterCode.Number;还支持 --ensembl 生成 11 位补零编号。 (AGAT Documentation)
bashagat_sp_manage_IDs.pl \ --gff in.sorted.gff3 \ --prefix TraesMM902 \ --ensembl \ --type_dependent \ -p gene -p level2 -p level3 \ -o in.renum.gff3
解释下你最关心的几个参数(都在文档里):
--type_dependent:让 gene/mRNA/exon/CDS 各自单独从 1 开始计数,不会混成一个总流水号。 (AGAT Documentation)-p gene -p level2 -p level3:只处理 gene(level1)以及 level2(如 mRNA)和 level3(如 exon/CDS)这些层级。 (AGAT Documentation)--nb(可选):设置起始编号(默认 1)。 (AGAT Documentation)--prefix / --ensembl:控制新 ID 的格式(prefix + 字母码 + 11 位数字)。 (AGAT Documentation)排序后 Chr1A:5432890 那个 gene 会比 Chr1A:19337050 先编号;Chr1B 的 gene 会在 Chr1A 之后编号(取决于排序后的染色体顺序)。
例如使用 --prefix TraesMM902 --ensembl:
ID=TraesMM902.G00000000001ID=TraesMM902.G00000000002ID=TraesMM902.G00000000003
(mRNA/exon/CDS 会用各自的字母码与计数)agat_sp_manage_IDs.pl 提供按 feature type 分开计数(--type_dependent),但不提供按 seqid 自动重置的开关(文档选项里没有)。 (AGAT Documentation)
这种需求通常用“按染色体拆分 → 每条染色体跑一遍 → 合并”:
bash# 先确保已按 tabix sorting 排好 agat config --expose --tabix agat_convert_sp_gxf2gxf.pl --gff in.gff3 -o in.sorted.gff3 # 取排序后出现的染色体顺序(保持顺序,而不是 sort -u) chroms=$(awk '!/^#/ {print $1}' in.sorted.gff3 | uniq) first=1 > in.renum.byChr.gff3 for chr in $chroms; do # 拆分:保留注释行 + 当前染色体 awk -v C="$chr" 'BEGIN{FS=OFS="\t"} /^#/ || $1==C {print}' in.sorted.gff3 > ${chr}.gff3 # 每条染色体从 1 开始 agat_sp_manage_IDs.pl \ --gff ${chr}.gff3 \ --prefix ${chr} \ --type_dependent \ --nb 1 \ -p gene -p level2 -p level3 \ -o ${chr}.renum.gff3 # 合并:header 只保留一次 if [ $first -eq 1 ]; then cat ${chr}.renum.gff3 >> in.renum.byChr.gff3 first=0 else grep -v '^#' ${chr}.renum.gff3 >> in.renum.byChr.gff3 fi done
你贴出来的示例看起来像是“空格分隔”,但 GFF3 标准是 TAB 分隔 9 列。如果你的真实文件也是空格,先转成 tab(否则 AGAT 可能解析不稳)。
如果你告诉我你最终希望 gene ID 长什么样(比如还想保留 TraesMM902_1Axxxxx 这种“染色体+6位数字”风格,还是接受 PREFIX.G00000000001 这种),我可以把上面的 --prefix/--ensembl 组合和(必要的)后处理一步,直接改成最贴合你现有命名体系的版本。