第4章 细胞过滤策略:阈值设定与实操要点

过滤细胞,说白了就是扔掉那些“不合格”的细胞。你可能会问:凭什么判断一个细胞合不合格?

我从单细胞数据分析第一天起,最头疼的就是这一步。阈值设得太松,垃圾细胞进来,下游降维聚类直接跑偏;设得太严,稀有的亚群被误杀,后面找新细胞类型就彻底没戏。所以这一章,我把我这些年踩过的坑、总结的经验,统统摊开来讲。

4.1 三个核心指标:UMI总数、检测基因数、线粒体比例

判断一个细胞的质量好不好,主要看这三个数:

  • UMI 总数:每个细胞捕获到的独特 mRNA 分子数。太高可能是双细胞(多个细胞粘在一起被当作一个),太低可能是细胞破裂或RNA降解。
  • 检测基因数:每个细胞里至少检测到1个UMI的基因种类数。同理,太高可能是双细胞,太低可能是空液滴。
  • 线粒体比例:线粒体基因UMI占全部UMI的百分比。比例高通常意味着细胞膜受损,mRNA泄漏,只剩线粒体内RNA还残留。

我当年做小鼠大脑皮层数据时,有一批细胞线粒体比例飙到30%以上,一开始以为是某种细胞亚型的特征,后来发现是样本处理时过度吹打导致细胞膜破损。你想想看,这种垃圾细胞如果混进降维,会硬生生拉出一个“高线粒体亚群”,特别容易误导人。

# 用Seurat计算这三个指标(示例)
pbmc[["percent.mt"]] <- PercentageFeatureSet(pbmc, pattern = "^MT-")
# 查看分布
VlnPlot(pbmc, features = c("nCount_RNA", "nFeature_RNA", "percent.mt"), ncol = 3)

4.2 阈值怎么定?——没有统一标准,但有通用公理

我知道你很想要一个万能的阈值公式。抱歉,没有。

阈值高度依赖组织类型、建库方法、测序深度。举个例子:10x 平台的人外周血 PBMC,一般 UMI 总数下限 500~1000,基因数下限 200~500,线粒体比例上限 5%~10%。但如果是肿瘤组织,RNA降解多,线粒体比例15% 的细胞可能仍然有生物学意义。

我的习惯是三步走:

  1. 先看原始分布图——画小提琴图和散点图,直观感受异常尾巴在哪。
  2. 设定保守的初筛阈值——用中位数加减若干个MAD(绝对中位差),而不是死板的固定数。
  3. 结合下游反馈迭代——跑一轮聚类后检查“中间群”是不是由低质量细胞驱动,再回来调阈值。

tips:我个人习惯用 MAD 替代标准差。UMI 分布常常有长尾,标准差会被极端值拉大,而 MAD 更稳健。代码:

lower <- median(nCount_RNA) - 3 * mad(nCount_RNA)
upper <- median(nCount_RNA) + 3 * mad(nCount_RNA)

4.3 常见坑与避雷指南

⚠️ 注意:不要同时设置上下限太紧。

我曾经有一个数据设定 UMI 总数上限 5000,结果丢弃了一群真实的髓系细胞(它们天然有多聚体 RNA)。后来发现那些细胞只是体积大、RNA 多,根本不是双细胞。正确做法是:先用 DoubletFinder 等软件检测双细胞,再把 UMI 上限放宽到 99% 分位数。

另一个经典错误:线粒体比例只设上限,不设下限。极少数情况(比如细胞质被完全抽空)下线粒体比例会接近 100%,但更多情况是线粒体比例 <1% 的细胞也有问题?其实是那些空液滴,几乎没有捕获到基因,线粒体基因自然也没几个,比例反而低。所以建议设一个更合理的条件:

# 合理的过滤条件(R伪代码)
keep_cells <- nCount_RNA > 500 & 
              nFeature_RNA > 200 & 
              percent.mt < 25

核心逻辑:三个指标要联动判断,不能只看单个指标。例如:一个细胞 UMI 总数很高但基因数也很高,并且线粒体比例正常,那很可能是正常的“高表达”细胞。但一个细胞 UMI 总数很低、基因数很低、线粒体比例却很高,这基本就是坏死细胞无疑。

4.4 不同场景的推荐阈值参考

组织/样本类型 UMI总数下限 UMI总数上限 检测基因数下限 线粒体比例上限
人PBMC(10x) 500 ~8000 200 10%
小鼠脑组织(10x) 400 ~6000 150 15%
肿瘤组织(snRNA-seq) 300 ~10000 100 20%
空间转录组(Visium) 1000 ~15000 300 10%

你看表格里的空间转录组,要求更高,因为每个 spot 包含多个细胞,UMI 总数天然更高。我遇到过空间数据用 PBMC 的阈值去过滤,结果一大半 spot 被清掉。所以一定要按实际平台调整。

4.5 可视化检查三件套

不要只信数字,一定要用图看一眼。我每次跑完过滤都会画下面三张图:

  1. 小提琴图:过滤前 vs 过滤后,看分布变化。
  2. UMI vs 基因数散点图:正常细胞应呈明显的正相关,如果出现低UMI但高基因数的点,可能是空液滴污染。
  3. 线粒体比例 vs UMI 散点图:线粒体比例高的细胞往往会聚集在低UMI区域,如果高UMI的细胞也有高线粒体比例,要警惕双细胞。

嗯,这里要注意:散点图的颜色可以用密度或类别来标记,否则几十万个点叠在一起根本看不清。

# Seurat散点图示例
FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "nFeature_RNA")
FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "percent.mt")

4.6 本章核心流程一览

下面这张图把整个细胞过滤的逻辑串起来了,你过滤之前一定在心里过一遍这个流程。

细胞过滤决策流程 原始单细胞矩阵 计算 UMI / 基因 / 线粒体% 小提琴图 + 散点图检查分布 设定初筛阈值(MAD法) 过滤后重新画图 + 检查双细胞 迭代调整 核心原则:先看分布再定阈值,下游聚类结果反过来验证过滤是否合理

4.7 实战中的一点坚持

我从不把阈值写死成固定数值放在 pipeline 里。每个数据集我都会手动画图,看分布尾巴的位置。有些文章喜欢把阈值设定成“行业标准”,比如线粒体 < 5% 就是好,但我在坏死的脑组织切片中看到正常细胞都有 10% 以上,你一刀切下去,真正有用的细胞全死了。

另一个容易忽略的点:过滤完细胞之后,记得看一眼过滤掉的细胞有什么特征。用聚类后的细胞类型注释跟过滤掉的低质量细胞做对比,有时候会发现某种细胞只有高线粒体比例的状态(比如肝细胞在分离时更容易损伤)。这时候可能需要保留它们,但在下游差异分析中特殊处理。

经验之谈:一次过滤不要干掉超过30%的细胞。如果超过30%,大概率是你的样本质量不行,或者阈值太激进。先回去排除建库批次效应、组织解离方案的问题,再来调过滤参数。

好了,这一章就讲到这里。拿起你的数据,打开 Seurat 或 Scanpy,按照这个流程跑一遍,你会发现自己对数据的理解立刻不一样了。