3. 数据准备:从 10X Genomics 下载示例数据、构建 Seurat 对象、质量控制流程

好,咱们进入实操环节。这一章会带你走一遍标准的数据准备流程。说白了,就是把 10X 的原始数据变成能分析的 Seurat 对象。这部分我做过太多次了,有些坑不亲自踩一遍还真不知道。

3.1 从 10X Genomics 获取示例数据

我习惯直接使用 10X Genomics 官方提供的 pbmc3k 数据集做测试。这个数据集不大,跑起来快,适合拿来验证参数效果。你可以通过 SeuratData 包自动下载,也可以手动去官网拉。

用 SeuratData 安装(推荐方式):

install.packages("Seurat")
install.packages("SeuratData")
library(SeuratData)
InstallData("pbmc3k")

这样一来,数据就自动下载并缓存到你本地了。我个人觉得这是最省心的方式,尤其当你需要反复重建分析环境时。

手动下载(要是你网络不好可以用这个):

# 去 10X Genomics 官网找到 "pbmc3k" 数据集
# 或者直接用这个链接(注意版本)
# https://cf.10xgenomics.com/samples/cell/pbmc3k/pbmc3k_filtered_gene_bc_matrices.tar.gz
# 解压后你会得到三个核心文件:
#   barcodes.tsv.gz
#   features.tsv.gz
#   matrix.mtx.gz
注意: 我曾遇到过用 SeuratData 下载时,包版本不匹配导致数据文件读取失败的情况。建议先更新 SeuratData 到最新版。

3.2 构建 Seurat 对象

数据下载好了,下一步就是构建 Seurat 对象。这是之后所有分析的基础容器。我会用 Read10X() 函数来读取数据,然后传给 CreateSeuratObject()。

library(Seurat)
library(dplyr)

# 读取数据(注意路径)
pbmc.data <- Read10X(data.dir = "path/to/pbmc3k/filtered_gene_bc_matrices/hg19/")

# 构建 Seurat 对象
pbmc <- CreateSeuratObject(
  counts = pbmc.data,
  project = "pbmc3k",
  min.cells = 3,
  min.features = 200
)

这里我解释一下两个关键参数:

  • min.cells = 3: 只保留在至少 3 个细胞中检测到的基因。这能过滤掉那些极低表达、可能只是噪音的基因。
  • min.features = 200: 只保留检测到至少 200 个基因的细胞。空液滴或破裂的细胞通常基因数很少,这一步能帮你排除它们。

你想想看,这两个参数像是两道筛子。一个筛掉基因,一个筛掉细胞。我在项目中遇到过有些实验室的样本质量低,min.features 得调到 500 才行。所以这些值不是死数字,要看你的数据质量。

3.3 质量控制流程

构建完对象,咱们得做一次彻底的质量检查。QC 的核心是识别并剔除不合格的细胞。我通常会关注三个指标:

  1. nCount_RNA — 每个细胞的 UMI 总数
  2. nFeature_RNA — 每个细胞检测到的基因数
  3. percent.mt — 线粒体基因表达占比

先算线粒体比例:

pbmc[["percent.mt"]] <- PercentageFeatureSet(
  pbmc,
  pattern = "^MT-"
)

嗯,这里要啰嗦一句。人源的线粒体基因以 ^MT- 开头,小鼠是 ^mt-。别搞混了,否则你算出来的比例全是 0。我刚开始做的时候就犯过这个错。

可视化 QC 指标:

我个人习惯先用小提琴图看看数据分布,心里有个底。

# 画三个 violin 图
VlnPlot(
  pbmc,
  features = c("nFeature_RNA", "nCount_RNA", "percent.mt"),
  ncol = 3,
  pt.size = 0.1
)

图像出来后,你会发现大部分细胞集中在某个范围,但总有一些离群值。这些离群值就是我们要砍掉的。

设定过滤阈值:

这步没有标准答案。我一般会根据可视化结果来定。下面是一个比较通用的设置:

# 过滤细胞
pbmc <- subset(
  pbmc,
  subset = nFeature_RNA > 200 &
           nFeature_RNA < 2500 &
           percent.mt < 5
)

这张表总结了过滤逻辑:

指标阈值剔除原因
nFeature_RNA> 200基因数太少,可能是空液滴或死细胞
nFeature_RNA< 2500基因数太多,可能是双细胞(两个细胞被同一个液滴捕获)
percent.mt< 5%线粒体比例高,通常是细胞受损或正在凋亡
小技巧: 如果你处理的样本质量很差(比如长期保存的组织),把 percent.mt 的上限放宽到 10-15% 可能更实际。完全卡在 5% 会把太多细胞丢掉。我亲身经历过一次,样本几乎报废,最后靠放宽阈值才保住了分析。

3.4 本章知识脉络图

下面这张 SVG 把数据准备的全流程串起来了。从原始数据到干净的 Seurat 对象,一目了然。

数据准备核心流程 原始 10X 数据 barcodes + features + matrix Read10X() 读入稀疏矩阵 CreateSeuratObject() min.cells / min.features QC 指标计算 nCount / nFeature / percent.mt subset() 过滤细胞 关键过滤条件: • nFeature_RNA > 200 • nFeature_RNA < 2500 • percent.mt < 5% 输出: ✓ 干净的 Seurat 对象 ✓ 用于下游标准化与降维 注:过滤阈值需根据具体数据质量调整,这里展示的是标准参考值

从图里你能看到,数据准备是串联的流程。每多一个正确的参数,你的数据就更接近真实生物学信号。

3.5 本章小结

这一章我们走了三步:

  • 下载数据:用 SeuratData 或手动拉取 pbmc3k
  • 构建对象:Read10X() + CreateSeuratObject(),设好初步过滤
  • 质量控制:算 nFeature/nCount/percent.mt,用 subset() 砍掉坏细胞

这些操作看起来基础,但我敢说,很多 batch effect 问题其实在 QC 阶段就埋下了种子。如果过滤标准不一致,后面的批次校正就是你使劲给模型擦屁股。所以,花时间把这一步做扎实,绝对值得。