单细胞RNA‑seq分析概述与Seurat简介
大家好,我是这门课的主讲人。在正式动手跑Seurat之前,我们先聊聊:单细胞测序到底在解决什么问题?Seurat又凭什么成了行业标配?
我们为什么需要单细胞测序?
传统bulk RNA‑seq测的是一个组织的“平均基因表达”。比如取一块肿瘤组织,测出来的是癌细胞、基质细胞、免疫细胞全部混在一起的平均信号。问题来了——如果这片组织里只有5%的细胞是耐药克隆,那么它们在bulk数据里几乎被淹没,根本没法单独分析。
单细胞RNA‑seq(scRNA‑seq)就不一样了。它能一次捕获数千到数万个细胞,每个细胞独立测一遍。说白了,就是给每个细胞做一次“转录组快照”。
我在项目中遇到过一件挺典型的事:有个样本的bulk差异分析结果显示某个免疫检查点基因显著上调,但做了单细胞以后才发现,上调的其实只是少量的CD8+ T细胞,而巨噬细胞里那个基因是下调的。你看,如果光看bulk结果,治疗策略完全会选错方向。
单细胞RNA‑seq数据的特点
你拿到手的数据长什么样?
| 维度 | bulk RNA‑seq | scRNA‑seq |
|---|---|---|
| 样本数 | 几个到几十个(生物学重复) | 一个样本就能产出数万个细胞 |
| 基因数 | 约2万个基因 | 每个细胞只能检测到1k~5k个基因 |
| 稀疏性 | 大部分基因有表达 | 80%~90%的表达矩阵是零 |
| 技术噪声 | 相对低 | 高dropout、批次效应、扩增偏差 |
| 分析目标 | 差异表达、通路富集 | 聚类、注释、拟时序、互作 |
因为每个细胞捕获到的mRNA分子数非常有限(尤其是10x Genomics数据),所以表达矩阵里绝大多数是零。你想想看,两万个基因,一个细胞可能只表达了不到三千个——这就是scRNA‑seq最头疼的问题:dropout事件。我曾经有一次因为没处理好稀疏矩阵,聚类直接分出了两团“噪声”而毫无生物学意义……后来把参数调了一下,才恢复了正常的细胞亚群。
Seurat是什么?
Seurat是Satija实验室开发的一个R包,专门用来做scRNA‑seq数据分析。从2015年v1到现在v5,它已经成了这个领域事实上的“标准流程”。
- 数据读入:支持10x Genomics、Smart‑seq2、Drop‑seq等多种平台。
- 质控与标准化:过滤低质量细胞、归一化、找高变基因。
- 降维与聚类:PCA、UMAP/t‑SNE可视化、图聚类。
- 差异分析与注释:找marker基因、自动或手动注释。
- 整合分析:多批次或多模态数据的对齐(CCA、RPCA、Harmony)。
我个人习惯先把所有步骤写在一个R脚本里,一行一行跑通,再封装成函数。这样调试起来特别清晰。
Seurat的设计哲学
Seurat把分析过程封装在Seurat对象(SeuratObject)里。你只要学会对同一个对象不断调用函数,它就会往对象里添加新的降维、聚类结果、差异结果。说白了,你不需要手动维护一堆中间矩阵,所有东西都在一个对象里。
举个例子:
# 创建Seurat对象
pbmc <- CreateSeuratObject(counts = pbmc.mtx, project = "pbmc3k")
# 质控与过滤
pbmc[["percent.mt"]] <- PercentageFeatureSet(pbmc, pattern = "^MT-")
pbmc <- subset(pbmc, subset = nFeature_RNA > 200 & nFeature_RNA < 2500 & percent.mt < 5)
# 标准化
pbmc <- NormalizeData(pbmc)
# 找高变基因
pbmc <- FindVariableFeatures(pbmc, selection.method = "vst", nfeatures = 2000)
# 降维
pbmc <- ScaleData(pbmc)
pbmc <- RunPCA(pbmc)
# 聚类与UMAP
pbmc <- FindNeighbors(pbmc, dims = 1:10)
pbmc <- FindClusters(pbmc, resolution = 0.5)
pbmc <- RunUMAP(pbmc, dims = 1:10)
# 可视化
DimPlot(pbmc, reduction = "umap")
是不是很连贯?每个步骤都往同一个对象里塞东西,最后只需要一行DimPlot就能看到结果。
整体工作流
下面这张图是我自己整理的标准流程路线图。你看一下,后面我们所有的课程都会沿着这个流程走。
流程不是线性的,但核心骨架就是这套。从原始数据到完成聚类注释,每一步都有成熟的函数,我们后面会逐一拆解。
安装与加载
Seurat的安装非常简单,直接在R里运行:
install.packages("Seurat")
# 如果需要最新开发版或额外功能,推荐用remotes安装
# remotes::install_github("satijalab/seurat", "seurat5")
加载的话:
library(Seurat)
packageVersion("Seurat") # 检查版本,建议 >= 5.0
注意事项
- 内存管理:scRNA‑seq数据集经常超过10万个细胞,内存很容易吃掉32GB甚至更多。我建议至少配16GB RAM,64GB更好。
- 版本差异:Seurat v4和v5的对象结构略有不同,脚本可能会不兼容。本书统一使用Seurat v5,如果你还在用旧版,建议迁移。
- 不要过度优化:刚开始学的时候,按默认参数走一遍,理解每一步做了什么,再慢慢调。我曾经一上来就调分辨率、调nfeatures,结果连基础聚类都看不懂。
CreateSeuratObject默认会保留所有基因,包括线粒体和核糖体基因。如果不预先过滤线粒体比例高的细胞,后续聚类很可能出现“死细胞”组成的奇怪亚群。