第3章:QC参数配置 —— nFeature_RNA、nCount_RNA、percent.mt的计算与过滤阈值

大家好。数据拿到手了,矩阵也构建好了,接下来就是咱们单细胞分析里最良心的一步:质量控制(QC)。

说白了,QC就是帮你筛掉那些“坏”细胞——死细胞、空液滴、双细胞(两个细胞掉进一个液滴里)。如果这一步偷懒,后面的降维聚类全都会被污染。我也见过一些人跳过QC,结果跑出来一群“死细胞簇”,特征基因全是线粒体基因……那画面,别提多尴尬了。

所以今天咱们就好好聊聊三个最核心的QC指标:nFeature_RNA、nCount_RNA 和 percent.mt。它们的计算逻辑是什么?阈值怎么定?哪些坑最容易踩?

单细胞质量控制(QC)决策流程 原始UMI矩阵 nCount_RNA nFeature_RNA percent.mt 阈值设定:低通、高通、百分比上限 基于violin图 + 经验值 + 实验背景 ✅ 高质量细胞(通过QC) ❌ 丢弃:死细胞/空液滴 ❌ 丢弃:双细胞/碎片 💡经验阈值

3.1 三个核心指标,各代表什么?

我们先把这三个指标搞明白。你想想看,一个细胞样本经过测序后,每个基因被检测到的次数叫UMI Count(Unique Molecular Identifier)。

  • nCount_RNA:细胞中检测到的总UMI数。说白了,就是给这个细胞测了多少条RNA片段。数值太低,可能这个液滴是空的或者细胞已死;数值太高,很可能一个液滴里塞了两个细胞(双细胞)。
  • nFeature_RNA:细胞中检测到的基因种类数。我习惯叫它“基因覆盖度”。你可以理解为:这个细胞里有多少种不同的基因被打开了。正常细胞的nFeature应该在几百到几千之间。
  • percent.mt:线粒体基因的UMI占总UMI的比例。死细胞的膜会破损,细胞质RNA漏出去,但线粒体因为双层膜结构,DNA/RNA更容易被保留下来。所以percent.mt一高,大概率是细胞在“临终”状态。

一个小实验:我做过一次PBMC数据,其中一个样本的percent.mt平均到了40%以上。当时我还以为是处理流程有问题,后来一查,是样本在胰酶消化时拖太久了。从此我定了个规矩:样本处理步骤必须记录时间戳。

3.2 怎么计算这些指标?

在Seurat里,计算这些指标其实一行代码就够了。但前提是你得先有一个矩阵——稀疏矩阵或者数据框。CreateSeuratObject这一步会自动算好nCount_RNA和nFeature_RNA。

# 标准创建流程
pbmc_data <- Read10X(data.dir = "filtered_gene_bc_matrices/hg19/")
pbmc <- CreateSeuratObject(counts = pbmc_data, project = "pbmc3k")

# 这时候 pbmc@meta.data 里已经有 nCount_RNA 和 nFeature_RNA 了
head(pbmc@meta.data)

那percent.mt呢?需要手动添加。Seurat提供了一个非常方便的函数PercentageFeatureSet,你只需要告诉它染色体前缀就行——对人类的线粒体基因,前缀是"MT-"。

# 计算线粒体比例
pbmc[["percent.mt"]] <- PercentageFeatureSet(pbmc, pattern = "^MT-")

# 再查看
head(pbmc@meta.data)

等等,如果你在做小鼠数据,线粒体基因的前缀是"mt-",大小写不同。我之前帮同事排查时,他用了"^MT-"在小鼠数据上,结果percent.mt全为0,找了一下午……嗯,这个问题确实烦人。

3.3 阈值怎么定?—— 这是个“经验活”

阈值设置是QC里最艺术的地方。没有一刀切的万能参数,但有几个经验法则可以帮你快速起步。

指标 典型正常范围 可能的原因(超出范围)
nFeature_RNA 200 - 5000(不同组织差异大) 低:死细胞/空液滴;高:双细胞或多细胞
nCount_RNA 多数在500-30000之间 低:测序质量差或空液滴;高:双细胞或碎片团
percent.mt 通常 < 15% (PBMC),< 30% (某些组织) 高:细胞膜破损,正在经历凋亡

我的个人习惯:第一次跑QC时,先画一个小提琴图(VlnPlot)和散点图(FeatureScatter),看看数据的真实分布,然后再拍脑袋定阈值。千万别直接输入一个死数字。

# 绘制QC小提琴图
VlnPlot(pbmc, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)

3.4 过滤参数的代码实现

假设我定好了阈值:nFeature_RNA在200~2500之间,percent.mt小于5%,nCount_RNA小于25000。那在Seurat里过滤是这样的:

# 结合三个条件的过滤
pbmc <- subset(pbmc, subset = nFeature_RNA > 200 & nFeature_RNA < 2500 
               & percent.mt < 5 
               & nCount_RNA < 25000)

⚠️ 一个容易忽略的陷阱:nCount_RNA和nFeature_RNA是高度正相关的。如果你同时设了两个高阈值,可能会导致大量细胞被误杀。我建议,优先看nFeature_RNA作为“基因多样性的直接指标”,nCount_RNA的阈值可以设得宽松一些,主要用于排除极端情况。

我曾经在分析一个肿瘤样本时,nFeature_RNA的分布很特殊,出现了两个峰。后来发现第二个峰值是双细胞,而不仅仅是高表达细胞。这时候只靠nFeature_RNA不够,还得配合DoubletFinder做双细胞预测。

3.5 指标之间的关系 —— 帮你识别异常

有时候某个指标单独看没问题,但几个指标组合起来就暴露出问题了。

  • nCount_RNA 高 + nFeature_RNA 高:可能是双细胞。因为两个细胞的基因并集肯定比单个细胞大。
  • nCount_RNA 高 + nFeature_RNA 低:很可能是某个基因家族过度表达,比如免疫球蛋白基因在B细胞里的情况。这属于生物学信号,不是技术噪声。
  • nCount_RNA 低 + percent.mt 高:典型的死细胞特征。RNA已经大量降解,只有线粒体基因残留。

如何快速检查双细胞风险?

# 散点图:nCount_RNA vs nFeature_RNA
FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "nFeature_RNA")
# 如果散点图右上角出现“尾巴”或单独的小簇,要警惕双细胞。

3.6 常见误区与避坑指南

  • 误区:只看percent.mt,不看nFeature_RNA
    实际上,一个细胞如果只有100个基因,即便percent.mt很低(比如2%),它也很可能是空液滴或碎片。nFeature_RNA才是“细胞完整度”的最佳指标。
  • 误区:阈值设得太宽
    我见过有人把nFeature_RNA设为 0~100000,理由是“不想丢失数据”。但这样会把大量空液滴和双细胞放进来,后续聚类会出现很多“伪簇”。说白了,这是在自欺欺人。
  • 误区:把过滤后的细胞数跟期望值对比
    有些新人做完QC发现只剩50%的细胞,就慌了。其实很正常,尤其在组织样本中(比如脑组织或肿瘤组织),死细胞碎片占比较大,丢失30%-50%是可以接受的。
  • 关于不同组织类型:PBMC的线粒体比例通常控制在5%-10%以下,但肝细胞、心肌细胞的线粒体本就很丰富,上限可以放到20%-30%。你想想看,能量代谢旺盛的组织,mito比例自然高。

3.7 实战技巧:QC之后必做的“质量确认”

过滤完千万别直接往下跑。我一般会再做一步:

# 查看过滤后的总细胞数
ncol(pbmc)

# 看各指标的分布
summary(pbmc@meta.data$nFeature_RNA)
summary(pbmc@meta.data$percent.mt)

# 再画一次小提琴图确认过滤效果
VlnPlot(pbmc, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)

如果小提琴图的尾巴还没有被去掉(例如nFeature_RNA依然有一小戳细胞在5000以上),就需要回头调整阈值。这一点我在教学时总跟学员强调:QC是一个迭代过程,不是一锤子买卖。

最后的提醒:不要把论文里的阈值直接搬来用。每个实验室、每个样本、每台仪器做出来的数据分布都不一样。比如我最近拿到一批冷冻样本,nFeature_RNA均值只有800,而同一批新鲜样本能到2000。如果我用PBMC的标准去过滤,冷冻样本的细胞会全被扔掉。说白了,阈值要“因地制宜”。