跳转至

单细胞多组学CITE-seq

一句话概述

CITE-seq(Cellular Indexing of Transcriptomes and Epitopes by Sequencing)能在同一个细胞中同时检测转录组和表面蛋白——白话说就是:以前单细胞测序只能看基因"说了什么"(mRNA),CITE-seq还能看细胞表面"戴了什么帽子"(蛋白标记),两种信息结合让细胞分类更准确。


核心知识点表格

知识点说明
CITE-seq原理抗体偶联DNA标签(ADT),和mRNA一起被10x Chromium捕获测序
ADTAntibody-Derived Tag,抗体连接的DNA条形码
RNA assay传统scRNA-seq部分,反映基因表达
ADT assay蛋白表达部分,类似流式细胞术的表面marker
WNNWeighted Nearest Neighbor,Seurat整合RNA+ADT的核心方法
多模态Seurat对象一个Seurat对象包含多个assay(RNA + ADT)
CLR归一化Centered Log-Ratio,ADT数据推荐的归一化方法
totalVIscvi-tools中的CITE-seq分析工具,基于深度学习的VAE方法
MOFA+多组学因子分析,可解释各模态贡献
10x Feature Barcode10x平台的CITE-seq实现方案

各步骤详解

第一步:理解CITE-seq实验原理

白话解释: 在做10x单细胞测序之前,先用带DNA标签的抗体"染"细胞。这些抗体会粘在细胞表面的蛋白上。当细胞被微液滴包裹后,细胞表面的抗体标签(ADT)和细胞内的mRNA一起被捕获、反转录、测序。最终得到两张"成绩单"——一张是基因表达(RNA),一张是表面蛋白表达(ADT)。

CITE-seq工作流:
1. 抗体panel(如CD3、CD4、CD8等200+蛋白marker)偶联DNA标签
2. 抗体与细胞混合孵育 → 抗体结合到细胞表面蛋白
3. 10x Chromium捕获 → 每个液滴含1个细胞
4. 反转录 → mRNA和ADT标签一起被反转录
5. 文库构建 → 分别生成RNA文库和ADT文库
6. 测序 → 两个文库可以混合在一起测
7. Cell Ranger分析 → 得到RNA矩阵 + ADT矩阵

第二步:Cell Ranger预处理

白话解释: Cell Ranger的multi命令可以同时处理RNA和Feature Barcode(ADT)数据。

# Cell Ranger multi处理CITE-seq数据
# 需要准备config.csv配置文件

# config.csv示例内容:
# [gene-expression]
# reference,/ref/refdata-gex-GRCh38-2024-A
# [feature]
# reference,/ref/feature_reference.csv
# [libraries]
# fastq_id,fastqs,feature_types
# GEX_sample,/data/gex_fastqs/,Gene Expression
# ADT_sample,/data/adt_fastqs/,Antibody Capture

# feature_reference.csv(抗体对照表)示例:
# id,name,read,pattern,sequence,feature_type
# CD3,CD3,R2,5PNNNNNNNNNN(BC),AACAAGACCCTTGAG,Antibody Capture
# CD4,CD4,R2,5PNNNNNNNNNN(BC),TGTTCCCGCTCAACT,Antibody Capture

cellranger multi \                       # 多模态分析命令
  --id=cite_seq_sample \                 # 样本ID
  --csv=config.csv                       # 配置文件

第三步:创建多模态Seurat对象

白话解释: 把RNA和ADT两种数据装进同一个Seurat对象,就像一个学生的"档案袋"里放了语文成绩和体育成绩。

library(Seurat)                          # 加载Seurat

# 方法1:从Cell Ranger输出创建
# Cell Ranger multi的输出在 outs/per_sample_outs/sample/count/
cite_data <- Read10X(
  data.dir = "outs/per_sample_outs/sample/count/filtered_feature_bc_matrix/"
)

# cite_data是一个list,包含两个矩阵:
# cite_data$`Gene Expression` → RNA计数矩阵
# cite_data$`Antibody Capture` → ADT计数矩阵

# 创建Seurat对象(先用RNA数据)
cite <- CreateSeuratObject(
  counts = cite_data$`Gene Expression`,  # RNA计数矩阵
  project = "CITE-seq",                  # 项目名
  min.cells = 3                          # 基因至少在3个细胞中表达
)

# 添加ADT数据作为新的assay
cite[["ADT"]] <- CreateAssayObject(
  counts = cite_data$`Antibody Capture`  # ADT计数矩阵
)

# 查看对象
cite                                     # 显示两个assay信息
Assays(cite)                             # 列出所有assay:RNA, ADT

# 方法2:从已有矩阵创建
# rna_matrix <- Read10X_h5("rna.h5")
# adt_matrix <- Read10X_h5("adt.h5")

第四步:独立预处理各模态

白话解释: RNA和ADT数据要分别用不同的方法处理——RNA用SCTransform,ADT用CLR归一化(因为ADT的数据分布特点不同)。

# ===== RNA预处理 =====
# 质控
cite[["percent.mt"]] <- PercentageFeatureSet(cite, pattern = "^MT-")  # 线粒体比例

# 过滤低质量细胞
cite <- subset(cite,
  subset = nFeature_RNA > 200 &          # 至少200个基因
    nFeature_RNA < 5000 &                # 最多5000个基因
    percent.mt < 15                      # 线粒体<15%
)

# SCTransform归一化
DefaultAssay(cite) <- "RNA"              # 切换到RNA assay
cite <- SCTransform(cite, verbose = FALSE)  # SCTransform归一化
cite <- RunPCA(cite, verbose = FALSE)    # PCA降维

# ===== ADT预处理 =====
DefaultAssay(cite) <- "ADT"              # 切换到ADT assay

# CLR归一化(ADT推荐方法)
# CLR = Centered Log-Ratio
# 白话:每个蛋白的值取log后减去所有蛋白的平均log值
cite <- NormalizeData(
  cite,                                  # Seurat对象
  normalization.method = "CLR",          # CLR方法
  margin = 2                             # 按细胞归一化(margin=2)
)

# ADT数据不需要选高变基因(panel本身就是精选的)
# 直接对所有ADT做降维
cite <- ScaleData(cite)                  # 标准化
cite <- RunPCA(
  cite,                                  # Seurat对象
  features = rownames(cite),             # 用所有ADT marker
  reduction.name = "apca",               # 命名为apca(区别于RNA的pca)
  verbose = FALSE
)

第五步:WNN整合分析(核心步骤)

白话解释: WNN(加权最近邻)是Seurat的"杀手锏"——它会学习每个细胞中RNA和ADT各自的"有用程度",自动分配权重。比如某些细胞的RNA信息更有用,某些细胞的ADT信息更关键,WNN会聪明地加权组合。

# WNN分析:同时利用RNA和ADT信息
cite <- FindMultiModalNeighbors(
  cite,                                  # Seurat对象
  reduction.list = list("pca", "apca"),  # RNA的PCA和ADT的PCA
  dims.list = list(1:30, 1:18),          # RNA用30个PC,ADT用18个PC
  modality.weight.name = "RNA.weight"    # 权重名称
)

# 基于WNN图进行聚类
cite <- FindClusters(
  cite,                                  # Seurat对象
  graph.name = "wsnn",                   # 使用WNN图(不是普通的snn图)
  algorithm = 3,                         # Leiden算法
  resolution = 0.8,                      # 分辨率
  verbose = FALSE
)

# WNN-UMAP可视化
cite <- RunUMAP(
  cite,                                  # Seurat对象
  nn.name = "weighted.nn",               # 使用WNN近邻图
  reduction.name = "wnn.umap",           # 命名为wnn.umap
  reduction.key = "wnnUMAP_"             # 前缀
)

# 同时做RNA-only和ADT-only的UMAP(用于对比)
cite <- RunUMAP(cite, reduction = "pca", dims = 1:30,
  reduction.name = "rna.umap", reduction.key = "rnaUMAP_")
cite <- RunUMAP(cite, reduction = "apca", dims = 1:18,
  reduction.name = "adt.umap", reduction.key = "adtUMAP_")

# 三种UMAP对比可视化
p1 <- DimPlot(cite, reduction = "rna.umap", label = TRUE) + ggtitle("RNA only")
p2 <- DimPlot(cite, reduction = "adt.umap", label = TRUE) + ggtitle("ADT only")
p3 <- DimPlot(cite, reduction = "wnn.umap", label = TRUE) + ggtitle("WNN")
p1 + p2 + p3                            # 三图并排展示

# 查看各模态权重分布
VlnPlot(cite, features = "RNA.weight", group.by = "seurat_clusters") +
  ggtitle("RNA weight per cluster")      # 每个cluster中RNA的权重

第六步:蛋白表达可视化与标注

白话解释: 用ADT数据(表面蛋白)来辅助细胞类型注释——就像用"身份证"(蛋白marker)来确认"居民"(细胞)的身份。

# ADT marker可视化
DefaultAssay(cite) <- "ADT"              # 切换到ADT assay

# 特征图:在UMAP上显示蛋白表达
FeaturePlot(
  cite,                                  # Seurat对象
  features = c("CD3", "CD4", "CD8a", "CD14", "CD19", "CD56"),  # 关键marker
  reduction = "wnn.umap",               # 使用WNN UMAP
  ncol = 3                              # 每行3个图
)

# 热图:各cluster中蛋白表达水平
DoHeatmap(
  cite,                                  # Seurat对象
  features = rownames(cite),             # 所有ADT marker
  group.by = "seurat_clusters"           # 按cluster分组
) + scale_fill_viridis_c()               # 配色方案

# 双轴散点图:蛋白双标(类似流式散点图)
FeatureScatter(
  cite,                                  # Seurat对象
  feature1 = "CD4",                      # x轴:CD4蛋白
  feature2 = "CD8a",                     # y轴:CD8蛋白
  group.by = "seurat_clusters"           # 按cluster着色
)

# 基于蛋白marker的细胞类型注释
# CD3+CD4+ → CD4 T cells
# CD3+CD8+ → CD8 T cells
# CD14+ → Monocytes
# CD19+ → B cells
# CD56+ → NK cells
new_labels <- c(
  "0" = "CD4 T", "1" = "CD8 T", "2" = "Monocyte",
  "3" = "B cell", "4" = "NK cell"        # 根据实际结果修改
)
cite <- RenameIdents(cite, new_labels)   # 重命名cluster

常见报错与解决

报错原因解决方案
ADT assay has 0 featuresADT数据没正确导入检查feature_reference.csv和Cell Ranger输出
FindMultiModalNeighbors errorRNA和ADT的降维维度不匹配调整dims.list,ADT维度不超过marker数
CLR normalization: NaN有细胞ADT全为0过滤掉ADT总UMI<10的细胞
UMAP: too few neighbors细胞数太少增加样本量或降低n.neighbors参数
CreateAssayObject: dimnames mismatchRNA和ADT的细胞barcode不一致确保两个矩阵的列名(barcode)一致
SCTransform crash内存不足减少ncells参数或增加内存

速查表

# ========== CITE-seq分析速查(Seurat WNN)==========

# 1. 创建多模态对象
data <- Read10X("filtered_feature_bc_matrix/")
obj <- CreateSeuratObject(counts = data$`Gene Expression`)
obj[["ADT"]] <- CreateAssayObject(counts = data$`Antibody Capture`)

# 2. RNA预处理
DefaultAssay(obj) <- "RNA"
obj <- SCTransform(obj) |> RunPCA()

# 3. ADT预处理
DefaultAssay(obj) <- "ADT"
obj <- NormalizeData(obj, method="CLR", margin=2) |> ScaleData() |>
  RunPCA(features=rownames(obj), reduction.name="apca")

# 4. WNN整合
obj <- FindMultiModalNeighbors(obj,
  reduction.list=list("pca","apca"), dims.list=list(1:30,1:18))
obj <- FindClusters(obj, graph.name="wsnn", resolution=0.8)
obj <- RunUMAP(obj, nn.name="weighted.nn", reduction.name="wnn.umap")

# 5. 可视化
DimPlot(obj, reduction="wnn.umap", label=TRUE)
FeaturePlot(obj, features=c("CD3","CD4"), reduction="wnn.umap")

面试高频问题

Q1: CITE-seq和流式细胞术有什么区别?

流式细胞术只能检测蛋白(一般10-30个marker),CITE-seq可以同时检测蛋白(200+marker)和全基因组转录组。CITE-seq的优势:(1) 蛋白和RNA来自同一个细胞,天然配对;(2) 蛋白panel可以扩展到200+;(3) 获得全转录组信息。劣势:成本更高,通量可能低于流式。

Q2: WNN是什么?为什么不直接把RNA和ADT数据拼在一起?

WNN(Weighted Nearest Neighbor)会学习每个细胞中每种模态的"信息量",给有用的模态更高权重。直接拼接的问题:(1) RNA有20000+基因,ADT只有200个marker,维度严重不平衡;(2) 两种数据的噪声特征不同;(3) WNN允许权重因细胞而异——比如T细胞的ADT标记很清晰(高权重),但某些稀有细胞可能RNA更有用。

Q3: ADT数据为什么用CLR归一化而不是SCTransform?

ADT数据和RNA数据的特点不同:(1) ADT只有几十到几百个marker(vs RNA的20000+基因),不适合做高变基因选择;(2) ADT的信号分布更接近log-normal;(3) CLR(Centered Log-Ratio)专门处理这种"低维组合数据",能保留marker之间的相对关系。

Q4: 除了WNN,还有什么方法整合CITE-seq数据?

(1) totalVI(scvi-tools):基于VAE的深度学习方法,同时建模RNA和ADT,适合batch校正和缺失数据插补;(2) MOFA+:贝叶斯因子分析,可解释每个因子由哪种模态驱动;(3) CiteFuse:专门为CITE-seq设计的整合方法。WNN是最主流且最易用的。

Q5: CITE-seq数据有哪些常见质控问题?

(1) ADT背景噪音:游离抗体或非特异性结合导致假阳性,需要包含同型对照(isotype control);(2) 抗体浓度不平衡:不同抗体的信号强度差异大;(3) 空液滴(empty droplets)的ADT信号:空液滴也能捕获游离抗体标签,需用Cell Ranger的背景过滤。