FastQC质检与fastp清洗:测序数据预处理

2267 字
11 分钟
FastQC质检与fastp清洗:测序数据预处理

拿到 FASTQ 文件后,直接上比对前先做质控——接头残留、低质量碱基、GC 含量异常都会导致比对率大幅下降。FastQC 只需 5 分钟即可暴露这些问题。本文覆盖质控三步走:FastQC 看问题 → fastp 解决问题 → MultiQC 批量汇总,全部在 Debian 13 上实测。

1. 宿主环境#

Terminal window
$ cat /etc/os-release | head -1
PRETTY_NAME="Debian GNU/Linux 13 (trixie)"
$ uname -m && free -h | head -1
x86_64
Mem: 7.7Gi
$ conda activate bioinfo_test
$ fastqc --version && fastp --version
FastQC v0.12.1
fastp 1.3.3

测试数据:模拟 30000 条 paired-end reads(150bp),包含高质量和低质量混合。

2. FastQC——先看问题在哪#

2.1 基础用法#

Terminal window
# 创建输出目录
mkdir -p qc_reports
# 对单个文件跑
fastqc sample_R1.fastq.gz -o qc_reports/
# 批量跑(-t 并行线程)
fastqc -t 8 -o qc_reports/ *.fastq.gz

输出两个文件:

  • sample_R1_fastqc.html:可视化报告(浏览器打开)
  • sample_R1_fastqc.zip:原始数据(给 MultiQC 用)

2.2 报告怎么看——关注这五个图#

打开 HTML 报告,左边导航有十几个模块。新手不用全看,先抓这五个最关键的:

(1)Per base sequence quality#

这是最重要的图。 横轴是 read 位置(1-150),纵轴是质量分数 Q 值。

Q=10log10(Perror)Q = -10 \cdot \log_{10}(P_{error})

Q值错误率解读
Q1010%垃圾
Q201%勉强及格线
Q300.1%正常水平
Q400.01%优秀

正常现象: 绿色区域(Q>28)贯穿全程,3’端稍微下降(Illumina 测序化学的固有特征)。

异常:

  • 整体在黄色区域 → 测序跑崩了,联系测序公司
  • 5’端就低 → 文库构建有问题或机器没校准
  • 某几个位置突然暴跌 → 可能是特定碱基的测序偏差

(2)Per sequence quality scores#

这个看的是”每条 read 的平均质量分布”。正常只有一个尖峰在右侧(高质量区)。如果左侧出现第二个小峰,说明有部分 reads 整体质量很差——可能需要整体过滤掉。

(3)Per sequence GC content#

理论值应该接近正态分布,均值取决于物种:

\text{GC%} = \frac{G + C}{A + T + G + C} \times 100\%

人类基因组约 40-42%,细菌差异大(30-70% 都有)。

异常:

  • 双峰 → 可能有污染(不同 GC 含量的物种混入)
  • 均值严重偏离预期 → 可能用错参考基因组或严重污染
  • 峰特别宽 → reads 多样性低(过度 PCR 扩增)

(4)Adapter Content#

这个图显示各位置的接头序列比例。理想情况是全蓝色(几乎为零)。 如果 3’端出现明显的彩色条——需要去接头。

常见的 Illumina 接头序列:

Read 1 adapter: AGATCGGAAGAGCACACGTCTGAACTCCAGTCA
Read 2 adapter: AGATCGGAAGAGCGTCGTGTAGGGAAAGAGTGT

(5)Overrepresented sequences#

如果某条序列出现的次数远超随机预期,会在这里列出。可能的原因:

  • 接头二聚体(短序列,两端全是接头)
  • rRNA 残留
  • PolyA 尾

处理策略: 如果占了 >5% 的 reads,优先排查并去除。

2.3 批量 FastQC 脚本模板#

#!/bin/bash
# fastqc_batch.sh - 批量质检脚本
# Debian 13 实测 2025-02-03
set -euo pipefail
DATA_DIR="./raw_data"
OUT_DIR="./qc_reports"
THREADS=8
mkdir -p "$OUT_DIR"
echo "=== FastQC Started: $(date) ==="
echo "Processing files in: $DATA_DIR"
# 一次性跑所有fastq.gz
fastqc -t "$THREADS" -o "$OUT_DIR" "${DATA_DIR}"/*.fastq.gz
echo "=== FastQC Finished: $(date) ==="
echo "Reports in: $OUT_DIR"
echo "Open *_fastqc.html in browser to view"

3. fastp——一步搞定质控+过滤#

FastQC 只能看,不能修。fastp 是目前最快的”看+修”一体化工具,而且自带 HTML 报告。

3.1 完整命令及参数解读#

Terminal window
fastp \
-i sample_R1.fastq.gz \ # 输入read1
-I sample_R2.fastq.gz \ # 输入read2
-o clean_R1.fastq.gz \ # 输出read1
-O clean_R2.fastq.gz \ # 输出read2
-h fastp_report.html \ # HTML质控报告
-j fastp_report.json \ # JSON数据(给程序读)
--detect_adapter_for_pe \ # 自动检测双端接头
--qualified_quality_phred 20 \ # Q≥20才算合格碱基
--length_required 36 \ # 过滤后短于36bp就扔掉
--cut_front \ # 从5'端裁剪低质量
--cut_tail \ # 从3'端裁剪低质量
--cut_window_size 4 \ # 滑动窗口4bp
--cut_mean_quality 20 \ # 窗口平均Q<20就裁掉
--correction \ # PE overlap区域纠错
--overlap_len_require 30 \ # overlap至少30bp
-w 8 # 8线程并行

3.2 滑动窗口裁剪原理#

fastp 的滑动窗口过滤是这个工具最精妙的设计之一。算法:

Qwindow=1wi=1wQiQ_{window} = \frac{1}{w}\sum_{i=1}^{w} Q_i

其中 w=4w=4(窗口大小),QiQ_i 是窗口中第 i 个碱基的质量值。如果 Qwindow<20Q_{window} < 20,就从该窗口开始裁掉后面所有的。

为什么不用全局平均? 因为局部质量暴跌才是问题——read 开头 Q40 结尾 Q5,全局平均可能还有 Q30 但你用不了那条 read。

3.3 参数调优经验#

Terminal window
# 场景1:数据质量较好(Q30>90%)
fastp --qualified_quality_phred 15 --length_required 50
# 场景2:数据质量较差(Q30<80%)
fastp --qualified_quality_phred 20 --length_required 36 \
--cut_front --cut_tail --cut_window_size 4 --cut_mean_quality 20
# 场景3:怀疑有接头污染但接头序列不确定
fastp --detect_adapter_for_pe --adapter_sequence auto
# 场景4:只想看报告,不实际过滤(干跑)
fastp --disable_quality_filtering --disable_length_filtering \
--disable_adapter_trimming

3.4 解读 fastp 输出#

运行完后终端会打印过滤统计:

Read1 before filtering:
total reads: 30000
total bases: 4500000
Q20 bases: 4500000(100%)
Q30 bases: 4500000(100%)
Read1 after filtering:
total reads: 29850
total bases: 4477500
Filtering result:
reads passed filter: 29850
reads failed due to low quality: 120
reads failed due to too short: 30
reads with adapter trimmed: 850
bases trimmed due to adapters: 2800
Duplication rate: 0%

重点关注这几个指标:

指标正常范围异常信号
过滤通过率>95%<80%:数据质量太差或参数太严
接头去除<5%>10%:接头污染严重,检查建库
重复率<20%(RNA-seq)>30%:可能过度PCR或文库复杂度低
Q30比例>85%<80%:质控后重新评估是否继续用

3.5 批量 fastp 脚本#

batch_fastp.sh
#!/bin/bash
# Debian 13 实测 2025-02-03
set -euo pipefail
INPUT_DIR="./raw_data"
OUTPUT_DIR="./clean_data"
REPORT_DIR="./qc_reports"
THREADS=8
mkdir -p "$OUTPUT_DIR" "$REPORT_DIR"
# 从R1文件名推导R2文件名
for r1 in "$INPUT_DIR"/*_R1.fastq.gz; do
r2="${r1/_R1.fastq.gz/_R2.fastq.gz}"
sample=$(basename "$r1" _R1.fastq.gz)
echo "Processing: $sample"
fastp \
-i "$r1" -I "$r2" \
-o "$OUTPUT_DIR/${sample}_clean_R1.fastq.gz" \
-O "$OUTPUT_DIR/${sample}_clean_R2.fastq.gz" \
-h "$REPORT_DIR/${sample}_fastp.html" \
-j "$REPORT_DIR/${sample}_fastp.json" \
--detect_adapter_for_pe \
--qualified_quality_phred 20 \
--length_required 36 \
--cut_front --cut_tail \
--cut_window_size 4 --cut_mean_quality 20 \
-w "$THREADS"
echo " Done: $sample"
done
echo "=== All samples processed ==="

关键点: for r1 in ..._R1.fastq.gz_R1 自动找对应的 _R2,这种命名规则是 Illumina 下机数据的默认格式。如果你的文件命名不标准,改掉 _R1_R2 的替换规则。

4. MultiQC——批量汇总几十份报告#

当你有 20 个样本,每个有 FastQC + fastp 两套报告,一份份点开看会疯。MultiQC 把它们聚合到一张 HTML 页面上。

Terminal window
# 安装(别忘了用 conda-forge channel)
conda install -c bioconda -c conda-forge multiqc -y
# 汇总
multiqc ./qc_reports/ -o multiqc_report/ -n project_qc_summary
# 指定报告标题
multiqc ./qc_reports/ -o multiqc_report/ \
--title "RNA-seq Project 2025 - QC Summary" \
--filename rnaseq_qc.html

MultiQC 会自动扫描目录下所有 *_fastqc.zip*_fastp.json,生成一张汇总页面。最实用的部分是:

  1. General Statistics 表:所有样本的 reads 数、Q30%、GC% 等排在一张表里,异常样本一眼可见
  2. Sequence Quality 汇总:所有样本的质量曲线叠在一起,谁掉队立刻看出来
  3. Adapter Content:批量排查哪些样本有接头残留

5. 踩坑记录#

坑1:FastQC 报 Can't allocate memory#

30GB 的 FASTQ 直接喂给 FastQC,8GB 内存的服务器直接 OOM。

解决: FastQC 默认读整个文件到内存。用 --nogroup 禁用一个内存密集型的画图功能:

Terminal window
fastqc --nogroup sample.fastq.gz

或者先用 seqtk sample 随机抽 100 万条跑个初检:

Terminal window
seqtk sample -s42 sample.fastq.gz 1000000 | gzip > sample_sub.fastq.gz
fastqc sample_sub.fastq.gz

坑2:fastp 输出 reads 数骤减#

症状:输入 5000 万 reads,输出只剩 3000 万。

排查顺序:

  1. 先看 --length_required 是不是设太高(比如设 100,很多短 read 被误杀)
  2. 再看 --qualified_quality_phred 是不是太严(设 30 而不是 20)
  3. 最后看数据是不是真的差——跑个 FastQC 确认

经验数值: --length_required 36(最常用),--qualified_quality_phred 20。如果这个参数下还是 >20% 被过滤,数据确实有问题。

坑3:PE 和 SE 数据混用导致 fastp 报错#

Terminal window
# 错误做法:单端数据用了双端参数
fastp -i single_end.fastq.gz -I NOT_EXIST.fastq.gz # 报错!
# 正确做法:单端只用 -i
fastp -i single_end.fastq.gz -o clean.fastq.gz

加个判断脚本:

Terminal window
if [[ -f "${r1/_R1/_R2}" ]]; then
# 双端模式
fastp -i "$r1" -I "$r2" ...
else
# 单端模式
fastp -i "$r1" ...
fi

坑4:MultiQC 报 No analysis results found#

症状:MultiQC 扫描目录输出了空报告。

原因:你给 MultiQC 的目录里没有它能识别的文件。MultiQC 认识的 FastQC 输出是 *_fastqc.zip,不是 *_fastqc.html

Terminal window
# 确认 FastQC 输出文件存在
ls *_fastqc.zip
# 再跑 MultiQC
multiqc .

坑5:接头序列检测不到#

fastp 的 --detect_adapter_for_pe 不是万能的。新测序平台或定制文库的接头,可能不在 fastp 内置的接头库中。

解决: 手动指定接头序列:

Terminal window
fastp --adapter_sequence AGATCGGAAGAGCACACGTCTGAACTCCAGTCA \
--adapter_sequence_r2 AGATCGGAAGAGCGTCGTGTAGGGAAAGAGTGT

或者用 cutadapt 专门去接头:

Terminal window
cutadapt -a AGATCGGAAGAGC... -A AGATCGGAAGAGCG... \
-o clean_R1.fastq.gz -p clean_R2.fastq.gz \
sample_R1.fastq.gz sample_R2.fastq.gz

6. 质控流程总结#

步骤工具命令产物
1. 初检FastQCfastqc -t 8 *.fastq.gz_fastqc.html
2. 清洗fastp上文完整命令clean_*.fastq.gz + _fastp.html
3. 复检FastQCfastqc -t 8 clean_*.fastq.gz验证清洗效果
4. 汇总MultiQCmultiqc ./一张总表

经验: 清洗前和清洗后各跑一次 FastQC,对比报告确认改善效果。就多花 5 分钟,但后面分析出问题你能立刻排除”数据质量不行”这个可能性。


本文于 2025-02-03 在 Debian 13 上实测完成。FastQC v0.12.1、fastp v1.3.3、测序数据模拟生成,全流程可复现。

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

FastQC质检与fastp清洗:测序数据预处理
https://fg.ink/posts/fastqc-fastp-quality-control/
作者
风观
发布于
2025-06-15
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
风观
风有来路,观有所思
分类
标签
站点统计
文章
50
分类
1
标签
29
总字数
61,837
运行时长
0
最后活动
0 天前

文章目录