小失误,大麻烦:读 Tommy Tang 的生信常见错误清单
生信分析里的错误,大多并不高深:索引从错误的数字开始,没人记下用的是哪个基因组版本,或者 shell 命令里多了一个空格。这些错误容易犯、不容易发现,而且常常“静悄悄”:流程顺利跑完,结果看起来也挺合理。
1. 数数,比想象中难
不同文件格式的坐标系不同。 BED 是 0-based、左闭右开;GTF 和 GFF 是 1-based、两端闭合。染色体的第一个碱基,在 BED 里记为 0,在 GTF 里记为 1。格式转换时如果不调整起始位置,所有区域都会整体错开一个碱基,足以改变一个密码子,或错过剪接位点。
编程语言的计数起点不同。 Python 从 0 开始数,R 从 1 开始数。代码从一种语言改写到另一种,可能不报任何错,却总是取到相邻的那个元素。
染色体名不宜直接按普通文本排序。 普通文本排序会把 chr10 排在 chr2 前面,不符合通常按染色体编号排列的习惯。若要得到 chr1、chr2、…、chr10 的顺序,应使用自然排序;对于 BED 等区间文件,还需在每条染色体内按起始坐标排序。
好习惯:坐标每次跨越文件格式或编程语言时,先手动核对一个已知位置,比如某个熟悉基因的起点,再相信转换结果。
2. 数据和你以为的不一样
基因组版本必须一致。 比对到 hg19 的 reads,如果套用 hg38 的注释来看,会落在外显子之外。参考序列、索引和注释文件都应来自同一个组装版本,最好也是同一个发布版本。
链方向很重要。 负链上的区域,提取序列前要先做反向互补。漏掉这一步,得到的序列格式完全正常,但内容是错的。
计数前,需要明确如何处理同时匹配多个基因的 reads。 基因之间可能相互重叠,甚至嵌套。统计 reads 前如果没想好共享区域怎么算,就可能漏掉某些特征,或把同一条 read 算两次。
换行符也有暗坑。 Windows 保存的文件用 \r\n 换行,Unix 工具期望的是 \n。最后一行如果没有换行符,简单的循环也可能把它漏掉。dos2unix 和一次 tail 检查就能避免很多麻烦。
好习惯:把基因组版本和注释版本写进文件名,也写进项目的 README。
3. Shell 错误
误删、误覆盖。
- 一个多余的空格,会把
rm *.fasta变成rm * .fasta,删掉整个文件夹里的文件。 >会覆盖文件内容,>>才是追加。用>往~/.bashrc里写东西,原来的配置就没了。- 在错误的目录里运行
rm *,删了就回不来。
本该交给程序的字符,被 shell 先处理了。
awk {print $2}会出错,因为 shell 先展开了$2和花括号;应写成awk '{print $2}'。grep > file.fasta不是在找序列标题,而是把输出重定向了;应写成grep '>' file.fasta。find . -name *.txt中的通配符可能在find看到之前就被展开;模式要加引号。
忘了默认设置。
cut默认按制表符切分,处理 CSV 需要加-d,。mkdir要创建多层目录,需要加-p。rm删除目录,需要加-r。- 用
cat打开几个 GB 的 FASTQ 会刷满整个终端,head或less -S更合适。 chmod 777给所有人完全权限,通常chmod u+x就够了。
好习惯:用通配符删除前,先用同样的模式跑一次
ls。在 Bash 中,set -o noclobber可以防止>覆盖已有文件。
4. 流程上的错误,比代码错误影响更久
尽量使用现成工具,避免重复造轮子。 读取 FASTQ、GenBank 或 BLAST 输出时,优先使用 Biopython、pysam、Bioconductor 等经过测试的库,省去自己编写读取代码的工作,也能减少遗漏特殊情况导致的错误。分析单细胞 RNA-seq 数据时,优先使用 Scanpy 或 Seurat 完成质控、降维和聚类,把精力放在研究问题上,无需自己从头编写代码。
正则表达式要测试。 用“应该匹配”和“不应该匹配”的例子各试一遍。
数据和代码都要有版本管理。 分析悄悄用了旧版输入,结果就很难复现。Git、Git LFS 或工作流管理工具能让输入一目了然。
记录决策,用对统计方法。 说不清怎么得到的结果,或依赖不合适的检验、不充分的随机化,还不能算发现。
5. 单细胞分析中的常见错误
把细胞当作独立样本做差异表达。 比较健康与疾病两组、每组有多个样本时,常见做法是把每组所有细胞合在一起,在细胞水平做差异表达分析。但同一样本的细胞并不相互独立;成千上万个细胞会让 p 值被严重低估,产生大量假阳性。更稳妥的做法是伪批量(pseudobulk)分析:先把每个样本的细胞计数汇总,再以样本为单位比较。
过度解读 UMAP。 UMAP 是非线性降维方法,图上点与点、簇与簇之间的距离并没有明确的定量含义。它适合用来直观展示数据结构,不宜据此判断细胞群之间的远近关系。
默认批次校正是安全的。 批次校正和多数据集整合都建立在一定的假设之上,过度校正可能把真实的生物学差异一并抹去。一项比较了七种常用方法的研究发现,许多方法会在数据中引入可测量的人为改变,只有 Harmony 在所有测试中表现稳定,因此作者仅推荐 Harmony 用于 scRNA-seq 批次校正。Antonsson & Melsted, 2024
好习惯:差异表达以样本为单位;UMAP 只作可视化;批次校正后,检查已知的生物学差异是否仍然存在。
一张简短的检查表
| 在做这件事之前…… | 检查 |
|---|---|
| 转换坐标 | 0-based 还是 1-based?左闭右开还是两端闭合? |
| 合并文件 | 基因组和注释版本一致吗?染色体命名一致吗(chr1 还是 1)? |
| 提取序列 | 哪条链? |
运行 rm、> 或 mv |
目录对吗?模式先用 ls 确认过吗? |
把代码传给 awk、grep 或 find |
加引号了吗? |
| 比较不同条件的表达 | 以样本为单位(pseudobulk)分析了吗? |
| 分享结果 | 输入、版本和参数都记录了吗? |
避免这些错误并不需要高深的知识,只需要多检查一下。这比重跑一遍分析便宜得多。
本文主要内容来自阅读 Tommy Tang 博客 Chatomics 上的文章《The Most Common Stupid Mistakes In Bioinformatics》。完整清单和更多资源请阅读原文。