咱们今天不整那些虚头巴脑的学术套话,直接聊点硬核的。你是不是也遇到过这种情况:病人对靶向药一开始反应挺好,肿瘤缩了,结果过半年复发,再查发现耐药了?这时候你拿着 Bulk RNA-seq 数据看,发现差异基因一堆,但到底是谁在主导耐药?是哪个亚群在挣扎?Bulk 测序就像把一锅杂烩汤喝了一口,你知道味道变了,但分不清是哪块肉馊了。
单细胞测序(scRNA-seq 或 scDNA-seq)就是给你配了个显微镜,能看清汤里每粒米。而如果你想更进一步,把“基因表达”和“蛋白质功能”结合起来看——也就是蛋白质组+转录组联合分析(Multi-omics),那简直就是给癌症耐药研究开了上帝视角。
但这条路坑很多,新手进去容易踩得鼻青脸肿。今天我就把从实验设计到数据分析的全流程,掰开揉碎了讲给你听。
一、 为什么是“蛋白质+转录组”联合?单看转录组不够吗?
很多新手(包括几年前的我)有个误区:觉得测了 mRNA 就能代表一切。
大错特错。
中心法则虽然写着 DNA → RNA → Protein,但在真实的细胞里,转录和翻译之间隔着厚厚的调控层:
- mRNA 不稳定:有些耐药相关的转录因子,mRNA 量没变,但翻译效率被激活了。
- 蛋白质修饰:磷酸化、乙酰化这些修饰,决定了蛋白是不是“干活”状态,RNA 里可看不到这些信息。
- 降解调控:耐药细胞可能通过泛素-蛋白酶体系统加速降解某些药物靶点蛋白,RNA 水平反而假性升高。
所以,如果你想看清耐药真相,转录组看“潜力”,蛋白质组看“执行”。两者结合,才能找到真正的耐药驱动因子。
举个真实例子
我们之前研究过一种 EGFR 突变的肺癌耐药模型。Bulk 测序显示 ABCG2(一种外排泵)mRNA 没明显变化。但用 CITE-seq(Cellular Indexing of Transcriptomes and Epitopes by Sequencing)技术同时测 RNA 和蛋白,发现 ABCG2 蛋白在少数耐药亚群中强烈表达,而 mRNA 由于翻译抑制显得低调。这就解释了为什么基于 mRNA 的预测模型失效,而直接靶向 ABCG2 蛋白的抑制剂反而有效。
结论:联合分析不是炫技,是解决“转录后调控”黑箱的必选项。
二、 技术选型:你想看什么?选对工具成功一半
目前主流的“蛋白质+转录组”联合技术主要有三种,新手别盲目追新,要看你的样本量和预算。
| 技术 | 原理 | 优点 | 缺点 | 适合场景 |
|---|---|---|---|---|
| CITE-seq | 用带条形码的抗体(ADT)标记蛋白,与 scRNA-seq 共存于同一液滴 | 数据对齐完美,单细胞分辨率高 | 抗体数量受限(目前~200种),需预筛选抗体 | 免疫微环境、表面标志物明确的耐药研究 |
| REAP-seq | 类似 CITE-seq,但步骤略有不同 | 兼容性好 | 同 CITE-seq | 同 CITE-seq |
| SCoPE2 / plexDART | 质谱流式结合单细胞裂解 | 可同时检测细胞内蛋白、磷酸化位点 | 通量低,每个细胞都要单独进质谱,成本极高 | 机制深挖,关注胞内信号通路(如磷酸化) |
新手建议:
- 如果你的耐药机制主要涉及细胞表面受体上调、免疫检查点表达,选 CITE-seq。这是目前最成熟、数据最稳的方案。
- 如果你关心胞内信号通路的激活状态(比如 p-ERK, p-AKT),且预算充足、样本量不大(<50个细胞),可以考虑 SCoPE2。
- 避坑提醒:不要同时做 CITE-seq 和 SCoPE2,除非你钱多到烧。先明确科学问题,再定技术。
三、 实验全流程:从细胞到数据,步步惊心
第一步:样本制备——单细胞悬液是生命线
核心痛点:癌症组织往往纤维化严重,细胞容易死亡,蛋白容易降解。
实操要点:
- 新鲜样本优先:耐药模型如果是临床样本,从取到冻存最好在 2 小时内。如果是细胞系,传代次数别超过 20 代,否则表型会漂。
- 消化酶 cocktail:别只用胰酶。推荐用 Dispase + Collagenase Type IV + Hyaluronidase 混合消化,温度 37℃,时间控制在 30-45 分钟,每隔 10 分钟轻轻吹打。
- DNA 酶处理:死亡细胞释放的 DNA 会让细胞聚集成团,堵塞微流控芯片。务必加 DNase I (100 U/mL) 处理 5 分钟。
- 过滤:先用 100 μm 过滤,再用 40 μm 过滤。
- 活率控制:流式细胞术检测,活率必须 >85%,最好 >90%。蛋白抗体对死细胞非特异性结合极强,死细胞多了,背景噪音能把你淹没。
新手常见错误:为了凑细胞数量,大量吹打导致细胞破碎。记住:少而精,好过多多而脏。
第二步:抗体文库构建——CITE-seq 的灵魂
这是最容易被忽视、也是最容易出错的地方。
抗体选择:
- 选 Goat 或 Rabbit 源的二抗,避免人源抗体干扰。
- 优先选 Fab 片段,穿透性更好,非特异性结合更低。
- 预实验必做:用 FACS 跑一下单标对照,确认抗体特异性和表达丰度。别等建库完了才发现抗体根本不工作。
寡核苷酸标记(Oligo-labeling):
- 把 DNA 条形码连到抗体上。常用的是 BioLegend 的 Feature Barcode 技术。
- 关键点:标记反应要避光,室温 30-45 分钟,标记后要通过 SPR 或凝胶纯化去除游离寡核苷酸。残留的游离 oligo 会直接测序,产生大量无效数据。
抗体 pooling:
- 将所有标记好的抗体等摩尔比混合。
- 避坑:不同抗体分子量不同,等摩尔比不等于等体积比。务必用 Bradford 法测蛋白浓度,计算摩尔数后再混合。
第三步:文库构建——双端测序
目前主流是使用 10x Genomics Chromium 平台。
- 细胞捕获:将细胞悬液 + 抗体 cocktail + GEM 试剂一起上机,目标是捕获 5,000-10,000 个细胞(取决于你的细胞复杂度)。
- 逆转录:
- 同一个 GEM 液滴里,mRNA 和 ADT(抗体衍生标签)一起被逆转录。
- 关键点:逆转录酶要同时兼容 RNA 和 DNA。现在常用的有 Maxima H Minus 或 SuperScript IV。
- 文库分离:
- 裂解 GEM 后,通过链霉亲和素磁珠富集带生物素标签的 cDNA 和 ADT。
- 分别构建 scRNA-seq 文库 和 ADT 文库。
- 测序:
- scRNA-seq:Illumina NovaSeq,PE150,目标深度 50,000-100,000 reads/cell。
- ADT:Illumina NextSeq,PE50 足够,目标深度 500,000-1,000,000 reads/cell(ADT 分子数少,需要更高测序深度来覆盖)。
新手避坑:ADT 文库不要省测序深度!很多新手 RNA 测得飞起,ADT 只测 50万 reads,结果发现很多抗体信号根本测不到,白花钱。
四、 数据分析:如何把两套数据“聊”起来?
拿到 FASTQ 文件后,分析流程比单纯 scRNA-seq 复杂一倍。别慌,我用代码和逻辑带你走一遍。
步骤 1:数据质控(QC)—— 区分真假信号
scRNA-seq 质控:
标准流程,用 CellRanger 或 alevin-fwc 定量。剔除低质量细胞:
- 基因数 < 200 或 > 2,500
- 线粒体基因占比 > 10%
- 血红蛋白基因(如果是血液样本)占比高
ADT 质控 —— 重灾区! ADT 数据没有“基因数”概念,但有“UMI 数”。你需要建立 UMI 阈值 来区分真实信号和背景噪音。
import scanpy as sc
import numpy as np
import matplotlib.pyplot as plt
# 加载 ADT 数据 (假设已用 RCTD 或 featureCounts 处理过)
adata_adt = sc.read_10x_mtx('adt_counts/', var_names='gene_names')
# 绘制 UMI 分布直方图,找到“驼峰”
plt.hist(adata_adt.X.toarray().flatten(), bins=100)
plt.xlabel('UMI Count')
plt.ylabel('Frequency')
plt.title('ADT UMI Distribution - Find the Threshold')
plt.show()
# 经验法则:取所有 UMI 分布的 1% 分位数作为阈值,或手动设定
# 例如,如果分布呈双峰,取谷底
threshold = np.percentile(adata_adt.X.toarray(), 1)
print(f"ADT Threshold: {threshold}")
# 过滤掉 UMI 低于阈值的抗体特征
sc.pp.filter_genes(adata_adt, min_counts=threshold)
关键逻辑:ADT 数据的背景噪音远高于 RNA。一定要做 UMI 阈值过滤,否则后续聚类会被噪音主导。
步骤 2:数据标准化与整合
RNA 数据:
标准 LogNormalize。
ADT 数据:
ADT 数据通常呈长尾分布,建议用 CLR (Centered Log-Ratio) 转换,或者直接用 log1p 后做 ScaleData。
# Seurat R 语言流程示例
library(Seurat)
# 加载数据
rna <- Read10X(data.dir = "filtered_feature_bc_matrix")
adt <- Read10X(data.dir = "adt_filtered_feature_bc_matrix")
# 创建 Seurat 对象
seurat_obj <- CreateSeuratObject(counts = rna, project = "resistance")
seurat_obj[["ADT"]] <- CreateAssayObject(counts = adt)
# RNA 标准化
seurat_obj <- NormalizeData(seurat_obj, normalization.method = "LogNormalize", scale.factor = 10000)
seurat_obj <- FindVariableFeatures(seurat_obj, selection.method = "vst", nfeatures = 2000)
# ADT 标准化 - 关键!使用 CLR 或 log1p
seurat_obj <- NormalizeData(seurat_obj, assay = "ADT", normalization.method = "CLR")
# 或者简单点:
# seurat_obj[["ADT"]] <- LogNormalize(seurat_obj[["ADT"]], scale.factor = 10000)
# 找 ADT 的高变基因
seurat_obj <- FindVariableFeatures(seurat_obj, assay = "ADT", selection.method = "mvp", nfeatures = 50)
步骤 3:多维数据整合(Integration)
这是新手最容易崩的地方。RNA 和 ADT 的分布差异巨大,不能直接加在一起聚类。
推荐方案:
- 分别降维:RNA 做 PCA,ADT 做 UMAP/t-SNE。
- 权重拼接:使用
Harmony或Seurat v5的WeightedNN算法,给 RNA 和 ADT 不同的权重。 - 另一种思路:先用 RNA 聚类定义细胞类型,再用 ADT 在聚类内部做差异表达,验证和细化亚群。
# Seurat v5 推荐流程:使用 RPCA 锚点整合
seurat_obj <- RunPCA(seurat_obj, assay = "RNA")
seurat_obj <- RunPCA(seurat_obj, assay = "ADT")
# 计算整合权重
seurat_obj <- IntegrateData(
object = seurat_obj,
anchor.features = SelectIntegrationFeatures(object.list = list(seurat_obj)),
weights = c("RNA" = 1, "ADT" = 0.5) # 可以根据实际情况调整权重
)
# 降维与聚类
seurat_obj <- RunUMAP(seurat_obj, reduction = "integrated", dims = 1:30)
seurat_obj <- FindNeighbors(seurat_obj, reduction = "integrated", dims = 1:30)
seurat_obj <- FindClusters(seurat_obj, resolution = 0.5)
# 可视化
DimPlot(seurat_obj, reduction = "umap") +
ggtitle("Integrated RNA+ADT Clustering")
步骤 4:耐药机制挖掘 —— 找到那个“坏分子”
聚类完成后,你要回答科学问题:哪个亚群在耐药?
差异表达分析:
- 比较“敏感组” vs “耐药组”在每个亚群中的差异基因。
- 使用
FindMarkers,参数test.use = "MAST"(专门处理单细胞零膨胀数据)。
蛋白-RNA 一致性检验:
- 对于关键耐药基因,检查其 RNA 和蛋白是否一致上调。
- 如果 RNA 不变,蛋白上调 → 提示翻译调控或蛋白稳定性增加。
- 如果 RNA 上调,蛋白不变 → 提示转录后抑制或蛋白降解。
# 找出耐药特异性高表达基因
markers <- FindMarkers(
seurat_obj,
ident.1 = "Cluster_5", # 假设 Cluster 5 是耐药亚群
ident.2 = NULL,
group.by = "condition", # 假设你有 condition 注释
min.pct = 0.25,
logfc.threshold = 0.5
)
# 重点看蛋白-RNA 不一致的基因
# 例如:ABCG2
# 检查 ABCG2 在 Cluster 5 中的 RNA 和 ADT 表达
FeaturePlot(seurat_obj, features = c("ABCG2"), assay = "RNA")
FeaturePlot(seurat_obj, features = c("ABCG2"), assay = "ADT")
通路富集分析:
- 对差异基因做 GO/KEGG 富集,看看耐药是否集中在“药物外排”、“DNA 修复”、“凋亡抑制”等通路。
轨迹分析(Trajectory Inference):
- 使用
Monocle3或Slingshot,构建从“敏感”到“耐药”的伪时间轨迹。 - 观察哪些基因在轨迹早期/晚期表达变化,锁定耐药演化的关键节点。
- 使用
五、 新手常见坑 & 解决方案
坑 1:抗体交叉反应
现象:某个抗体在 CITE-seq 中信号很强,但在 FACS 中很弱或无信号。 原因:测序读到的可能是非特异性结合,或者抗体在 PCR 过程中形成聚集。 解决:
- 务必做 isotype control(同型对照)。
- 做 单标对照,排除荧光重叠。
- 数据分析时,用
CITE-seq R package中的ADT_VALET工具进行背景校正。
坑 2:细胞双重捕获(Doublets)
现象:出现一些同时表达 T 细胞和肿瘤细胞 marker 的“怪物”细胞。 原因:一个液滴里包了两个细胞。 解决:
- 测序前用
DoubletFinder或Scrublet预测并剔除。 - 控制上机细胞浓度,避免过饱和。
坑 3:批次效应
现象:不同实验批次的数据在 UMAP 上分开,而不是按生物学状态分开。 解决:
- 使用
Harmony或Seurat的IntegrateData进行批次校正。 - 实验设计上,尽量将不同组的样本混合在同一批次处理(如果条件允许)。
坑 4:ADT 数据零值过多
现象:大部分细胞的 ADT 数据都是 0。 原因:抗体亲和力低,或细胞表面蛋白表达量低。 解决:
- 不要直接用原始计数做聚类,先做 CLR 转换。
- 考虑使用 Imputation 工具(如
MAGIC或SAVER),但需谨慎,可能引入假阳性。
六、 总结:如何让你的研究更有说服力?
- 验证!验证!验证! 单细胞数据是假设生成器,不是结论。找到关键耐药蛋白后,务必用 WB、IHC、流式
