做生信数据分析,特别是刚从测序公司拿到原始数据的时候,很多人第一个卡住的点往往不是复杂的差异分析,而是最基础的一步——怎么判断这批fastq数据到底能不能用。我自己带过不少入门的朋友,发现大家普遍有个误区:拿到数据就开始跑比对、找差异,结果后面越做越不对劲,回头排查才发现是数据源头就出了问题。FastQC就是用来解决这个问题的,它是生信领域最经典的测序原始fastq数据质控工具,没有之一。
这篇文章就是生信入门系列第七课,专门讲怎么用FastQC把测序原始数据“体检”一遍。我会从fastq格式本身的原理讲起,拆解FastQC报告里每一块到底在说什么,哪些指标必须看、哪些亮了红灯也不用慌,最后结合实际案例教你根据质控报告做下一步决策。不管你是刚接触生信的学生,还是自己动手分析GEO公共数据的研究者,这套内容都适用。
1. 先搞清楚质控到底在“控”什么
1.1 fastq格式本身藏着的关键信息
很多教程一上来就让你装FastQC跑报告,但对fastq文件长什么样、质量值怎么计算,讲得含糊。我个人认为,不理解fastq格式就去解读质控报告,等于没学会走就想跑,后面看到异常指标你根本不知道根因在哪。
一个标准的fastq文件里,每条测序读段(read)占用四行:
@EAS139:136:FC706VJ:2:2104:15343:197393 1:Y:18:ATCACG CTACATGATCATGACATGACATGACATGACATGACATGACATGACATGACATGA + IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII- 第一行以
@开头,是序列标识符,里面其实藏了测序仪编号、flowcell位置、lane、tile坐标这些信息,在排障时很有用,后面会细说。 - 第二行是碱基序列,就是ATCG的排列。
- 第三行是
+号,有些格式会在后面重复标识符,这个不影响分析。 - 第四行是质量字符,每个字符对应第二行对应位置的碱基质量。
这里最关键的是第四行。测序仪在读取碱基时会给每一个碱基算一个错误概率P,然后转换成Phred质量分数Q,公式是:
Q = -10 × log10(P)如果某个碱基测错的概率是1/100,那么Q = -10 × log10(0.01) = 20,对应的质量符号在ASCII表里是字符5。Q30代表错误率千分之一,Q20代表百分之一,这个对应关系建议记在心里,后面解释报告时要反复用到。
质量字符不能直接打印Q值,因为像Q35这种数字转成字符会出现控制字符,所以测序公司会把Q值加上一个偏移量再转成ASCII。最常用的两种编码是Phred+33和Phred+64。Illumina 1.8之后的测序仪都用Phred+33,也就是质量字符的ASCII码值减33就是真实Q值。如果你拿到的数据是老的Illumina 1.3到1.7版本,可能是Phred+64,质量字符的ASCII码减64才是Q值。FastQC会根据碱基质量分布自动判断编码体系,但偶尔也会出错,这个我放在后面的“常见问题”里专门讲。
1.2 质控解决的两个核心问题
为什么要做质控?总结起来就两个问题:测序过程有没有出问题,以及这份数据本身适不适合你要做的下游分析。
第一个问题面向测序实验。上机测序时,样本在flowcell上扩增、测序反应过程中可能出现各种异常,比如某个lane的簇密度不均匀、试剂残留污染、接头没有完全切除,这些都会在数据里留下痕迹。FastQC能通过碱基质量分布、GC含量分布、接头含量等指标,帮你判断这批数据来自哪个测序平台、用了什么建库策略,甚至能发现一些实验污染问题。
第二个问题跟你自己的分析相关。不同分析场景对数据质量要求不一样,所以同样的质控报告,在不同场景下解读结论可能完全不同。比如做全基因组重测序,要求比较高,Q30占比一般要超过85%;而如果是做16S扩增子测序,由于本身读长比较短、物种鉴定靠的是差异区段,对碱基精确度的容忍度会高一些。再比如,你从GEO数据库拿到一批别人上传的公开数据,想做数据挖掘和差异分析,那你更关心的是这批数据里有没有接头残留、测序深度够不够,能不能支撑后续的标准化分析。
在我的经验里,新手最容易犯的错就是把质控当成“通关任务”,看到报告里全是绿色就开心,看到红色就焦虑。实际上质控报告是用来辅助你做决策的,不是拿来打分定生死的。理解了这一点,再往下看工具的具体用法,你就会有完全不同的体会。
2. FastQC入手:装好、跑通、拿到报告
2.1 安装与批量运行
FastQC是一款Java写的桌面级软件,官方提供的下载包里已经打包好了可执行脚本,安装过程相对简单。最常见的安装方式有这样几种:
如果你用的是conda环境,一条命令就搞定:
conda install -c bioconda fastqc我推荐所有生信入门用户优先走conda路线,原因很简单:后面你会装的比对工具、变异检测工具、定量工具,几乎全都依赖conda管理依赖关系,FastQC只是第一个。
如果不想用conda,也可以直接从Babraham Bioinformatics官网下载二进制包,解压之后把fastqc脚本所在目录加进PATH就能用:
wget https://www.bioinformatics.babraham.ac.uk/projects/fastqc/fastqc_v0.12.1.zip unzip fastqc_v0.12.1.zip cd FastQC chmod 755 fastqc ./fastqc --helpFastQC依赖Java环境,如果跑不起来报Java相关的错误,先检查一下系统里有没有装合适版本的JRE。一般来说OpenJDK 8以上的版本都兼容。
实际项目里你往往不会只跑一个文件,通常是一批样本的正向和反向读段文件。FastQC支持一次传入多个文件,也支持用通配符匹配。我常用的命令长这样:
fastqc -t 8 -o ./qc_report ./raw_data/*.fastq.gz-t指定线程数,-o指定输出目录,后面的通配符会把raw_data目录下所有fastq.gz文件全部跑一遍。注意,如果你一次性指定的样本数特别多,超过了几十个,建议分组跑,防止单个节点内存被吃满。FastQC本身对内存的要求不算高,两三百兆足够,但文件数量太多时会占用一定的临时磁盘空间,输出目录要准备好足够容量。
2.2 高频参数一次讲清楚
FastQC的可调参数不算复杂,但有几个参数在实践场景里很常用,我列个表给你参考:
| 参数 | 作用 | 实际使用建议 |
|---|---|---|
-o | 输出目录 | 必须指定,否则报告会散落在当前目录 |
-t | 线程数 | 处理几百个文件时建议给4到8 |
--extract | 同时输出zip和txt文件 | 想用脚本批量汇总时很有用 |
-k | kmer长度 | 默认7,一般不需要改 |
--nogroup | 不压缩碱基位置分组 | 高深度数据想精细查看时用 |
-f | 强制指定文件格式 | 遇到文件后缀名异常无法识别时使用 |
其中--extract可能是最实用但容易被忽略的一个参数。很多人以为FastQC只生成HTML报告文件,实际上运行完会在输出目录同时生成一个以_fastqc.html结尾的HTML报告和一个_fastqc.zip压缩包。zip包里有一个fastqc_data.txt文本文件,里面包含所有模块的原始统计数据。当你处理几十个样本时,手动一个个点开HTML看不现实,写个小脚本去解析fastqc_data.txt里的数值,统一汇总成一张总表,效率高得多。后续如果你想用MultiQC把多个样本的报告合在一起,FastQC输出的这个zip包也是它的标准输入。
3. 报告逐项解读:看懂11个检查项
3.1 怎么看颜色和图标
报告打开后,顶部是文件名、文件类型和总序列数等基本信息,下面排列着11个模块的汇总图标。每个模块有一个状态标识,绿色代表通过,黄色代表警告,红色代表失败。
先说一个原则性问题:不要只盯着颜色看。FastQC的状态判定用的是经验阈值,但不同应用场景下同一个模块的阈值意义不一样。黄色的警告有时候只是提示你要人工确认,红色的失败也不一定意味着数据完全不能用于下游分析。相反,有的模块显示绿色,但在特定场景下反而有问题。我会在3.3里专门讲哪些“红灯”其实可以忽略。
报告中最上面的“Basic Statistics”是必看项,它会列出:文件名、文件类型(到底是常规fastq还是带碱基质量编码的旧格式)、编码体系(比如Sanger/Illumina 1.9)、总序列数、序列长度、以及GC含量。这里你可能已经注意到,前一节我特别解释了Phred编码,在这个模块里你就能看到FastQC对编码体系的判断结果。如果你知道自己这批数据用的是Illumina NextSeq或者NovaSeq平台,但Basic Statistics里显示编码是“Illumina 1.5”之类的老编码,那你就要警觉了,大概率是FastQC的判断逻辑被异常分布带偏了。
3.2 重点模块逐项拆解
接下来的10个分析模块,我按重要程度和使用频率分成三组。
第一组:质量分布相关,必看。
Per base sequence quality(每个碱基位置的质量分布)——这是很多人打开报告第一眼先看的图。横轴是read上的碱基位置(5'到3'),纵轴是质量分Q值。图上有一条黄色的中位数线、一条蓝色的均值线,以及一个由四分位距组成的箱线图区域。正常情况下,测序read开始位置质量略低,中间趋于平稳,末端逐渐下降,这是测序化学反应的正常规律。比较理想的图形是箱线图整体都落在Q20以上的绿色区域里(Q20以上算可以接受,Q30以上算优秀)。
你会看到背景上有三个色带:绿色代表Q28以上,黄色代表Q20到Q28,红色代表Q20以下。如果大片箱线区域掉进红色,尤其是一开始就在红色区域或者中段突然断崖式下跌,说明这批数据的技术质量有问题。这时你可以配合Per tile sequence quality模块看,这个模块按flowcell的物理位置展示质量差异,如果某一条tile颜色明显异常,基本可以确定是测序仪的某个区域出了问题。这种情况下,推荐直接找测序公司沟通。
Per sequence quality scores(每条序列的平均质量分布)——它展示的是所有read平均质量分的分布情况。正常数据会呈现一个集中在高分区间的尖峰,比如Q35附近。如果出现双峰甚至多峰,说明数据来源可能混合了两个质量差异显著的文库。
Per base sequence content(每个位置的碱基组成比例)——这个模块在WGS数据里一般很平,四条线(A、T、C、G)大致在25%附近波动。如果是RNA-seq数据,前几个碱基出现一定程度的偏离也是正常的,这跟RNA建库时随机引物结合的特性有关。但如果从头到尾出现明显分离,或者出现周期性的锯齿状波动,往往提示有接头污染或引物污染。
第二组:文库特征相关,看你了解文库质量。
Per sequence GC content(GC含量分布)——理论上,测序read的GC含量分布应该近似正态分布,而且峰的数值应该接近该物种基因组的真实GC含量。很多人容易忽略的是:不同物种的基因组GC含量差异很大,人类基因组大约41%,链球菌大约35%到40%,而有些真菌可以超过50%。如果GC峰明显偏了,不一定就是测序问题,先查一下你研究的物种本身的GC含量。另外,如果有两条明显分开的峰,一条在正常GC位置,一条偏离很远,那可能是混入了其他物种的DNA(比如建库时污染了细菌或人的DNA)。
Sequence Duplication Levels(序列重复水平)——这个模块展示的是不同重复程度的序列占所有reads的比例。测序深度越高,重复比例自然越高,所以这个模块对于高深度的WGS或RNA-seq并不需要过多担心。但如果你做的是宏基因组或低深度测序,重复率过高就要考虑是不是文库复杂度太低,也就是扩增阶段出了偏差。
第三组:污染与接头相关,看你的文库质量是否支撑后续分析。
Overrepresented sequences(过度表达的序列)——FastQC会把出现比例超过0.1%的序列单独列出来,自动比对到常见接头和rRNA序列库。如果识别出来的是Illumina接头序列,基本说明建库时接头切除不干净;如果没能自动识别出是什么序列,那就要手工去数据库比对来确定身份。
Adapter Content(接头含量)——这个模块直接展示read各位置匹配到接头序列的累积比例。曲线如果在尾部开始上升,说明read长度超过了插入片段长度,测到了插入片段尽头的接头。如果你后续要做变异检测或者定量分析,接头没有清除干净,会在比对时产生大量比对不上的read或者比对到错误位置的read,对结果影响很直接。
另外还有两个模块,Per base N content(每个位置的N比例)和Sequence Length Distribution(read长度分布)。前者正常情况下N的比例应该极低,接近0;如果某个位置的N非常高,往往是测序信号弱导致碱基无法判读,这和前面的质量分布模块互为印证。后者则看长度是否一致,常规双端测序read长度应该很均一,如果出现长度不齐的情况,有可能是软件在去接头时把read切短了。
3.3 哪些“红灯”其实不用紧张
经常会有新手截图一份FastQC报告问我:“老师,这么多模块标红,数据是不是废了,要不要重新测序?”说实话,每次看到这种问题,我都要先问一句:你跑的是哪个物种、什么类型的测序数据?因为很多在通用规则下被判为“警告”甚至“失败”的情况,在特定场景里反而属于正常。
举几个典型例子:
- Per base sequence content在RNA-seq里出现前几个碱基的AT/GC分离:这是RNA建库时随机六碱基引物结合偏好导致的,几乎无法避免,也不影响定量结果。只要后面几十个碱基恢复稳定,完全不用处理。
- Sequence Duplication Levels在高深度WGS里偏高:深度越高随机重复越多,这是正常现象。
- GC含量峰的轻微偏移:如果峰型是单一、尖锐的,即使中心位置和你预估的基因组GC含量偏差几个百分点,也不要太紧张。有时候参考基因组本身的GC组成跟你测的样本存在多态性差异。
- Overrepresented sequences里出现线粒体或核糖体序列:如果你做的是全转录组测序,线粒体reads和rRNA占比高是很常见的。这提示你可能需要额外的rRNA去除,但它不说明测序本身做得差。
所以,看FastQC报告一定要结合实验背景来判断。如果条件允许,把不同批次、不同样本的报告放在一起横向对比,比单独看一个样本更能发现问题。比如所有样本的某个模块都偏黄,那可能反映的是建库方法的系统偏好,不用单独处理;但如果只有某一个样本的某个模块异常突出,那就要重点怀疑这个样本是否出了实验或操作问题。
4. 质控之后怎么决策
4.1 接头污染怎么办
拿到FastQC报告后,最核心的问题是:要不要处理?怎么处理?
先说自己怎么判断接头污染。在Adapter Content模块里,如果出现了明显的曲线抬升,或者Overrepresented sequences模块识别出了Illumina通用接头序列,那就说明接头去除(trimming)做得到位。这时可以用cutadapt或Trimmomatic统一去接头。以cutadapt为例,假设你的数据是双端150bp,需要切除3'端可能的Illumina TruSeq接头序列:
cutadapt -a AGATCGGAAGAGCACACGTCTGAACTCCAGTCA \ -A AGATCGGAAGAGCGTCGTGTAGGGAAAGAGTGT \ -o clean_R1.fastq.gz -p clean_R2.fastq.gz \ -m 36 -q 20 raw_R1.fastq.gz raw_R2.fastq.gz-m 36表示去完接头后长度小于36bp的read直接丢弃,-q 20表示同时进行滑窗质量修剪。接头序列跑完后再用FastQC看一遍,Adapter Content曲线一般会拉平。
很多人会犯一个错误:接头序列识别出来以后,不知道如何确认版本。这里给一个通用规则,Illumina TruSeq单端接头几乎是固定的AGATCGGAAGAGC开头,双端第二段接头则是AGATCGGAAGAGCGTCGTGTAGGGAAAGAGTGT。如果在Overrepresented sequences里看到完全匹配或近似的序列,就放心大胆去处理。
4.2 低质量碱基怎么处理
如果报告里Per base sequence quality显示末端质量明显下降,最常见的策略是做质量修剪。这里我用一个实例帮你理解参数选择的过程。
假设你的数据是10万条150bp双端read,质量分布显示前10bp质量一直在爬升,后30bp明显掉到Q20以下。那么Trimmomatic的滑窗修剪策略比较适合:
trimmomatic PE -threads 8 \ raw_R1.fastq.gz raw_R2.fastq.gz \ clean_R1.fastq.gz clean_R1_unpaired.fastq.gz \ clean_R2.fastq.gz clean_R2_unpaired.fastq.gz \ ILLUMINACLIP:TruSeq3-PE.fa:2:30:10 \ LEADING:3 TRAILING:3 \ SLIDINGWINDOW:4:15 \ MINLEN:36SLIDINGWINDOW:4:15的意思是:以4个碱基为窗口,如果窗口内平均质量低于Q15,就从这里把read切掉。LEADING:3和TRAILING:3分别是把read开头和结尾质量低于Q3的碱基去掉。MINLEN:36表示处理完长度不足36bp的read丢弃。
这里有一个需要强调的点:修剪策略要“克制”。有些教程喜欢把阈值设得很高,比如SLIDINGWINDOW:4:20,这在qPCR定量或克隆测序里可能没问题,但如果你后续要做变异检测或表达定量,过度修剪会丢失可用信息。比较稳妥的做法是先用FastQC看整体质量,再结合下游分析工具的要求权衡阈值,没有一刀切的“最佳参数”。
修剪完成后,务必再跑一次FastQC,对比前后报告。这一步很多人偷懒跳过,但我强烈建议保留。我自己的习惯是给每个样本保留一个质控前、一个质控后的FastQC报告,这样写论文的时候可以直接引用对比图,也方便自己和合作者追溯每一步数据变化。
4.3 和GEO数据挖掘场景的关系
再补充一个大数据挖掘场景,这也是很多做GEO数据挖掘的人踩过的坑。在GEO数据库里下载公开测序数据时,你拿到的常常是SRA格式或已经经过预处理的fastq文件,但不少数据集的上传者并没有提供完整的测序质量信息。此时跑一遍FastQC同样适用,而且作用很明显。
举个例子,你从GEO下载了一批某个疾病和对照的RNA-seq数据,想自己重新走一遍流程做差异分析。如果不做质控,你根本不知道这些数据是被谁用什么方式处理过。有的数据集上传者已经去除过接头和低质量碱基,有的则是原始数据直接传上去,这两种情况跑出来的FastQC报告差异会非常大。如果你不做这一步就直接比对定量,后期发现某个样本的比对率异常低,排查方向会非常痛苦。
所以我建议在做GEO数据挖掘时,把FastQC当成第一道标准工序,先看每个样本的报告,再用MultiQC汇总到一起对比。有样本质量特别差的话,把它单独标记出来,后续PCA或者聚类分析时观察它是否表现为离群点。这不是“逃避”数据问题,而是把质控信息纳入分析流程的决策依据,属于更严谨的做法。
5. 实战中的坑与排查技巧
5.1 编码体系识别错误
先分享一个我实际踩过的坑。之前我帮人看一批数据,拿到raw data后我习惯性先跑FastQC,发现Per base sequence quality图里的质量分整体非常奇怪——所有位置都在Q20以下,乍一看像是数据质量极差。我第一反应是去查Basic Statistics里的编码体系,结果显示FastQC自动识别为Phred+33,但我从这个测序公司历史数据判断应该用的是老版本Illumina的Phred+64编码。
后来确认了这批数据确实是Phred+64编码,FastQC对编码体系的自动判断失效了,导致质量分数被严重低估。解决办法也简单,用--encoding参数强制指定:
fastqc --encoding='Illumina 1.5' sample.fastq.gz为什么会出现这种问题?FastQC的编码判断逻辑是基于质量值分布的,如果数据经过某些预处理(比如质量分整体偏移),或者文件格式不规范,自动判断就容易被带偏。遇到这种情况,你可以直接读取文件里的质量字符ASCII码范围来判断。用Linux命令行随手可以查:
zcat sample.fastq.gz | sed -n '2,4p;6,8p;10,12p;14,16p' | \ awk '{for(i=1;i<=length($0);i++){print i, substr($0,i,1)}}' | head -100更实用的方法是用seqkit工具,它有专门的命令查看质量编码:
seqkit stats sample.fastq.gz它会直接告诉你识别出的编码类型,比手动查ASCII更省事。这个小工具建议装一下,后面做fastq文件的格式转换、子采样、统计都会用得到。
5.2 双端测序文件顺序识别
另一个实战中很常见的坑是:双端测序的R1和R2文件搞混了。FastQC本身不会直接告诉你“这个文件是R1还是R2”,但你可以通过Quick check的模块和文件命名来判断。
双端测序数据里,R1和R2的碱基质量分布通常有细微差异,比如R1的质量整体略好于R2,末端掉质量的速度也稍有不同。更关键的是,如果你发现某对样本文件的Overrepresented sequences模块中,一个文件里识别出的是正向接头序列,另一个识别出的是反向接头序列,而你的预期刚好相反,就要小心是不是R1/R2标签贴反了。
确定方向后,再用seqkit检查一下并重新命名:
seqkit rename sample_R1.fastq.gz -o sample_R1_renamed.fastq.gz大部分情况下,检查一下文件的README或者SRA的元数据信息就能确认,不要只靠文件名猜测。文件名在数据传递过程中被人改过的情况真是太多了,我至少遇到不下五次。
5.3 常见问题速查表
把平时被问得最多的FastQC问题统一整理成一张速查表,方便你遇到问题直接对照。
| 问题现象 | 可能原因 | 处理思路 |
|---|---|---|
| 所有碱基位置质量都很低 | 编码体系识别错误,或测序仪本身异常 | 先检查Basic Statistics的编码,再用seqkit验证;排除编码因素后排查看测序反馈 |
| Adapter Content曲线整体抬升 | 建库时接头切除不彻底 | 用cutadapt或Trimmomatic切接头,再做FastQC验证 |
| Overrepresented sequences识别出核糖体序列 | RNA-seq样本核糖体RNA去除效果不佳 | 结合物种考虑;若比例太高,下游分析可用核糖体序列过滤 |
| GC分布出现双峰 | 可能有其他物种DNA污染,或样本混合 | 做物种分类比对或BLAST验证,必要时跟实验人员沟通 |
| 序列长度分布不齐 | 数据已被修剪过,或来自不同批次 | 结合文件来源判断,不一定要处理 |
| 处理报错提示“No sequences met the threshold” | 修剪参数过于严格,数据被全部丢弃 | 降低修剪阈值,检查输入文件是否正确 |
| 报告生成很久还不结束 | 输入文件过大或线程数不足 | 用-t加多线程;对超大文件可用--noextract降低IO压力 |
这7个问题覆盖了我日常答疑里80%以上的情况。还有一类问题是关于FastQC处理大文件时的内存占用:如果单个fastq文件真的特别大(比如超过10G),建议先试跑1百万条read子集,用下面的方式:
zcat sample_R1.fastq.gz | head -4000000 | gzip > sample_subsample.fastq.gz fastqc sample_subsample.fastq.gz子样本的质控结果基本能反映全文件的大体情况,等确认没问题后再跑全文件,万一参数有问题也来得及纠正,不至于白白等上半小时才发现命令写错。
从工具本身来说,FastQC其实没有什么高级技巧,它就是把测序原始数据的技术指标拆解开摊开给你看。但真正有价值的恰恰是解读和决策的过程,你越了解fastq格式底层的逻辑、越懂测序实验的流程,就越能从这个简单工具的报告里读出信息量。
根据我的个人经验,做质控最忌讳的就是“为了质控而质控”,跑一遍FastQC、看一眼报告、存个档就完事。我建议每次拿到新数据,都强迫自己把报告里的11个模块横向过一遍,边看边记录异常点,再结合样本本身的情况判断需不需要处理、怎么处理。这个过程看着琐碎,但很多下游分析里节省的排查时间,都值回这一遍功夫。
最后分享一个小技巧:现在很多人用MultiQC把几十个样本的FastQC报告汇总成一张网页,颜色对比确实方便,但我还是习惯先把每个样本的fastqc_data.txt解压出来,用脚本把Basic Statistics和关键模块的数值抽出来,合并成一张表格。这个表格丢进Excel里或者R里做批量判断,效率远高于鼠标点击翻网页。我自己的分析流程模板里,这一步已经固定成了标准动作,强烈建议你也养成这个习惯。