小失误,大麻烦:读 Tommy Tang 的生信常见错误清单

bioinformatics
command-line
Published

October 12, 2026

2 min read

生信分析里的错误,大多并不高深:索引从错误的数字开始,没人记下用的是哪个基因组版本,或者 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》。完整清单和更多资源请阅读原文。