3. 输出文件解析:理解 profile、biom、sam 等输出格式及其字段含义

跑完 MetaPhlAn,你会拿到一堆文件。新手最容易犯的错——盯着屏幕看半天,不知道哪个文件是干嘛的。

我个人习惯,先搞清楚每种格式的定位,再去抠细节。这样内存占用小,效率高。

3.1 核心输出总览

MetaPhlAn 默认生成三个主要文件,外加一个可选的中间文件。我把它们的关系画了张图,你看完心里就有谱了。

MetaPhlAn 输出文件体系 输入:clean reads (fq.gz) SAM 文件(中间产物) reads vs 标记基因,全局比对结果 BIOM 文件 标准 OTU 表,JSON 格式 PROFILE 文件 物种相对丰度表 功能表(可选) --add_viruses 等扩展 下游分析、工具交换 可视化、统计分析 功能通路、菌群潜力 三者选一:实际分析用 profile,归档用 biom,调试用 sam

3.2 Profile 文件——最常用的结果文件

这是你的主力文件。默认文件名是 sample_name_profile.txt。说白了,它就是个物种丰度表,但带了完整的分类学路径。

3.2.1 列字段详解

列名 含义 避坑提示
clade_name 分类学谱系,从界到种的全路径 用 | 分隔,别漏看了层级
NCBI_tax_id NCBI 分类学 ID 不同数据库版本可能不同
relative_abundance 该分类的相对丰度(百分比) 所有行加起来等于 100
estimated_number_of_reads 该分类对应的估计 reads 数 是估计值,不是精确计数
additional_species 如果当前节点是属,会列出下属的种 种级分辨率不够时参考

我的小技巧:拿到 profile 后,先看 relative_abundance 最高的那几行是不是 contaminants。我去年分析一个土壤项目,发现第一行是 Pseudomonas 占了70%,结果是因为水样被污染了。查了 lab log 才确认。

3.2.2 示例片段

#clade_name	NCBI_tax_id	relative_abundance	estimated_number_of_reads	additional_species
k__Bacteria|p__Proteobacteria|g__Pseudomonas	286	45.30	45200	
k__Bacteria|p__Firmicutes|g__Clostridium	1506	22.10	22100	
k__Bacteria|p__Bacteroidetes|g__Bacteroides	816	15.80	15800	
k__Archaea|p__Euryarchaeota|g__Methanobrevibacter	2172	0.05	50	

3.3 BIOM 文件——标准交换格式

BIOM 其实是 JSON 格式,结构比较复杂。不过我建议你别手动去编辑它,用 biom 命令行工具或者 Python 的 biom-format 包来读写。

3.3.1 核心结构

一个 BIOM 文件包含以下层级:

  • matrix_type:矩阵类型,通常是 "dense" 或 "sparse"。
  • shape:矩阵维度,[物种数量, 样本数量]。
  • data:丰度数据,按列展开或按稀疏格式存储。
  • rows:观测元数据(物种信息)。
  • columns:样本元数据。

注意:MetaPhlAn 生成的 BIOM 文件默认只包含一种数据类型(OTU 表),不包含功能注释。如果需要功能信息,请使用 --add_viruses 或 --add_archaea 等扩展参数。

3.3.2 通过命令查看

biom summarize-table -i output.biom -o table_summary.txt

你会看到类似这样的输出:

Num observations: 3421
Num features: 1
Num samples: 1
Total count: 100000.0
Table density: 100%

嗯,这里要注意——密度 100% 说明每个物种都有非零丰度,但在宏基因组里不太可能。其实是因为 MetaPhlAn 把所有检测到的物种都平铺进去了。

3.4 SAM 文件——比对原始数据

这个文件大部分情况下你不需要碰。我只有在调试参数或者怀疑比对出问题时才会打开它。

3.4.1 SAM 格式的核心列

列号 字段 说明
1 QNAME 查询序列名称(read ID)
2 FLAG 比对标志位(0 = 唯一比对,256 = 次优选)
3 RNAME 参考序列名称(标记基因 ID)
4 POS 比对位置(1-based)
5 MAPQ 比对质量值(越高越可信)
6 CIGAR 比对操作字符串(如 150M)
10 SEQ 序列碱基
11 QUAL 质量值字符串

3.4.2 有用的标记(Tags)

SAM 文件的第 12 列开始是一些 key-value 对。MetaPhlAn 会写入几个重要的 tag:

  • NM:编辑距离(错配数)。值越低越好。
  • AS:比对得分。比对软件保留下来的。
  • X1:MetaPhlAn 的标记基因分类信息。

我曾经犯过一个低级错误:用 SAMtools 统计唯一比对 reads 数时,没过滤掉 flag=256 的次优选。结果多算了一倍的 reads,丰度全乱套。记住——只统计 flag=0 或 flag=16 的。

3.5 如何选择输出格式

我的选择逻辑很简单,你参考一下:

  1. 日常分析:只用 profile 文件,文本格式好处理。
  2. 和同事/工具交换数据:用 BIOM 格式,标准化程度高。
  3. 调试性能或者查 bug:保留 SAM 文件,用 --sam_output output.sam 指定路径。

核心原则:别在不需要的时候生成 SAM 文件。我见过有人每次跑都带 --sam_output,结果磁盘被撑爆了。一个 10M reads 的样本,SAM 文件能到 5GB 以上。

3.6 实战:用 Python 解析 Profile 文件

如果你喜欢用脚本处理,这段代码帮你快速上手:

import pandas as pd

df = pd.read_csv("profile.txt", sep="\t", skiprows=1)
df.columns = ["clade_name", "NCBI_tax_id",
              "relative_abundance", "estimated_number_of_reads",
              "additional_species"]

# 只看种水平
species = df[df["clade_name"].str.count("\|") == 6]

# 找 top10
top10 = species.nlargest(10, "relative_abundance")

print(top10[["clade_name", "relative_abundance"]])

运行后会显示丰度最高的10个物种,直接拿去画柱状图就完事了。

3.7 避坑清单

  • Profile 文件第一行是注释,以 # 开头,读取时记得跳过。
  • 相对丰度加总不一定正好等于100,因为有未分类的 reads,浮点误差也可能。
  • BIOM 文件用 gzip 压缩,别直接 less 打开。可以用 zcat output.biom | python -m json.tool 看结构。
  • SAM 文件不要随便用 grep,用 samtools view -hS 来读,否则 header 会乱。

明白了这些文件长什么样,你的 MetaPhlAn 之旅就成功了一半。剩下的一半,是让参数替你把活干好。