1. 先交代这份笔记是从哪来的
我最早接触单细胞数据分析,跟大家一样,找了一套 Seurat 的标准代码,从 Read10X 到 NormalizeData、FindVariableFeatures、ScaleData、PCA、UMAP、FindClusters 一路跑通。跑 PBMC demo 数据集的时候一切顺利,图也漂亮,当时我以为自己已经会了。直到换上自己课题里的肿瘤组织数据,才发现真实项目的复杂程度完全是另一个量级:上游比对出来的矩阵结构异常、质控阈值怎么定都像在瞎猜、UMAP 上样本各自分离根本没法看、注释出来的细胞亚群用 marker 验证没有一个站得住脚。
这篇笔记就是我从那些失败经验里整理出来的。它不是一份纯代码手册,而是把单细胞数据分析从 fastq 到生物学结论这条链路上,每个环节“为什么这么做、怎么做、哪些地方容易踩坑”串起来的一份系统整理。适合刚接触单细胞数据分析的入门者建立全局框架,也适合已经能跑通标准分析、但想在质控、批次校正和注释环节做得更扎实的研究者参考。单细胞数据分析最核心的部分其实不是跑代码,而是每一步都在做判断和取舍,这篇笔记想把判断的依据讲清楚。
2. 上游比对不做对,后面全是白做
2.1 三种主流定量方案怎么选
单细胞测序数据分析的起点是测序仪下机的 fastq 文件,但在把它变成基因表达矩阵之前,得先选一条定量路线。目前主流的方案主要有三个:10x 平台配套的 Cell Ranger、基于 STAR 比对器的 STARsolo、以及基于伪比对的 kallisto|bustools。另外还有 Alevin 等方案,但我实际项目里用得最多的还是前三者。
Cell Ranger 是 10x 官方出品的流程,从比对、UMI 去重、空液滴鉴定到表达矩阵生成全部打包,输出目录结构规范,Seurat 读起来非常顺。它的最大优势是“傻瓜化”,但也正因为太一体化,想改中间参数或者排查具体问题的时候灵活性不够。STARsolo 是 STAR 比对器在单细胞数据上的专门模式,同样能做比对和 UMI 定量,但自由度更高,可以通过 soloType、soloFeatures 自定义输出内容,也方便和 Cell Ranger 的结果做交叉验证。kallisto|bustools 走的是伪比对路线,速度极快,适合先快速跑一版看看数据整体情况,但比对敏感性和复杂转录本的处理能力不如 STAR 系。
我自己比较固定的习惯是:10x 平台的常规项目,直接用 Cell Ranger;样本量特别大、需要快速预探索的时候,拿 kallisto 先跑一版;涉及自定义参考基因组、非标准注释或者想对比对过程有更多控制的时候,用 STARsolo。不管选哪条路,强烈建议保留原始比对文件和中间产物,不要跑完只留一个过滤后的表达矩阵。否则后面发现问题想排查,只能从头重跑,十几个小时就这么没了。
2.2 参考基因组版本不能随手选,也不能中途乱换
参考基因组版本这个问题,看起来是个小选择,实际影响非常大。同一套数据用 GRCh37 和 GRCh38 的注释跑出来,检测到的基因数、UMI 分布、甚至下游差异基因列表都会有差别。如果项目里混用了两个版本,合并矩阵时基因 ID 的转换匹配会损失掉几千个基因,而且这种损失不是均匀分布的,某些功能类别可能受影响更大。
更重要的原则是版本锁定:整个课题从第一个样本到最后一个样本,参考基因组和注释文件尽量保持完全一致。真遇到不得不换版本的情况,比如某个基因在新注释里被重命名了,那必须把新旧矩阵在关键 marker 基因上的表达量做前后对照,确认没有系统性偏移之后才能合并分析,绝对不要直接把两个不同版本的矩阵塞进同一个 Seurat 对象。
常见的参考来源有 ENSEMBL、GENCODE、UCSC 三套,它们对同一版本基因组的外显子注释细节有差异。我建议固定用其中一套,并且把具体版本号记录在分析文档里。别小看这个动作,单细胞项目周期长,三个月后你自己回头都会忘记当时用的哪一版,更不用提课题组里其他人的协作。
2.3 读入表达矩阵时那些基础但高频的坑
Cell Ranger 的 filtered_feature_bc_matrix 目录下有 matrix.mtx.gz、features.tsv.gz 和 barcodes.tsv.gz 三个文件。听起来很简单,但我在实际分析里见过太多人栽在这几个基础地方:旧的 10x 输出里第三个文件叫 genes.tsv,新版本才改成 features.tsv,代码没做兼容就报错;features.tsv.gz 旧格式只有两列,新格式三列且带 Feature 类型;Read10X 读取后没有检查行列数,直接往下跑,结果发现基因数和 Cell Ranger 报告对不上。
我的建议是,读入后第一步就先核对三个数:矩阵行数是否等于注释文件的基因数,列数是否等于 barcodes 文件的行数,总 UMI 数是否和 Cell Ranger 的 metrics_summary 对得上。这三个数任何一个对不上,都说明读取过程有遗漏或者文件不完整,这时候停下来排查比带着错误数据往下跑要省时间得多。
另外要提醒的是,Cell Ranger 会输出两个矩阵:raw_feature_bc_matrix 和 filtered_feature_bc_matrix。常规做法是用 filtered 矩阵,也就是排除了空液滴后的结果,但我不建议把 raw 矩阵丢掉。有些真实细胞如果本身表达量极低,比如静息状态下的细胞或衰老细胞,很可能落在过滤边界附近被误伤。主分析可以用 filtered,保留 raw 作为备用,等需要排查特定样本或重新评估空液滴判定阈值的时候,raw 矩阵就是救命稻草。
3. 质控过滤:固定阈值是最省事也是最危险的做法
3.1 三个核心指标的真实含义
质控阶段大家最先接触的指标是 nFeature_RNA(每个细胞检测到的基因数)、nCount_RNA(每个细胞的 UMI 总数)和 percent.mt(线粒体基因 UMI 占比)。教程里通常会给出“nFeature 大于 500、percent.mt 小于 20%”这类固定阈值,但真实项目里单看任何一个指标都会有不少盲区。
nFeature 高不一定是好事,它完全可能是两个细胞被同一个液滴捕获,基因组合并到一起的产物;nFeature 低也不一定是坏细胞,比如外周血里的中性粒细胞,在 10x 平台上本来就被 dropout 效应折磨得厉害,基因数低是它的真实状态而不是质量问题。percent.mt 高的细胞,通常是因为细胞膜破裂导致胞质 mRNA 流失,线粒体 RNA 相对稳定所以占比被动上升;但也有些组织本身线粒体代谢旺盛,比如肝脏细胞和某些肿瘤细胞,线粒体比例天然偏高,如果按常规阈值一刀切,这些细胞会被全部杀光。
正确的操作是先画四个分布图再看,而不是一上来就定阈值:nFeature 和 nCount 的散点关系、percent.mt 的分布直方图、nFeature 和 percent.mt 的联合散点图、以及每个样本各指标的箱线图。联合散点图特别重要,它能帮你区分“高线粒体+低基因数”的破碎细胞和“高线粒体+高基因数”的难判断细胞,这两类在处理策略上是完全不同的。
3.2 用中位数和 MAD 代替拍脑袋定阈值
固定阈值最大的问题是不适配数据本身。不同组织、不同解离批次、不同测序深度,基因数和 UMI 的基线水平差异巨大。同样一个“nFeature 小于 500 过滤”的规则,在一批平均基因数 3000 的数据里几乎不起作用,在另一批平均基因数 800 的数据里可能把大半细胞都误杀了。
更稳的做法是使用中位数和绝对中位偏差(MAD)来定义离群值。基本逻辑是:对每个质控指标,先算出中位数和 MAD,然后把中位数加减若干倍 MAD 作为上下界,超过这个范围的细胞标为离群。这个方法的优势在于它会根据数据自身的分布自动调整,检测深度高的样本阈值自动放宽,检测深度低的样本阈值自动收紧。
实际执行时,每个样本要单独跑 QC,不要把所有样本合并在一起计算阈值。原因是样本间的批次效应会直接污染统计分布,比如某个测序深度特别高的样本会把整体中位数拉上去,导致低深度样本的正常细胞被批量标记为离群。我见过不少项目团在一起跑 QC,结果最后全样本 nFeature 阈值变成一个毫无意义的数字。
3.3 双细胞预测:不省这一步,后面会被假象坑
双细胞(doublet)就是同一条液滴里捕获了两个或以上细胞,表达谱是两个细胞类型的“混血儿”。如果不过滤,聚类结果里特别容易产生一个位于两类细胞之间的过渡 cluster,表面看像新的细胞状态,用 marker 一验证才发现是双阳性的混合物。
常用的工具有 DoubletFinder、scDblFinder、Scrublet。我的建议是在基础 QC 之后、标准化之前就跑双细胞预测,并且参考预期双细胞率来设定参数。10x 官方有一个对应表:上样约 10000 个细胞时双细胞率大约在 4% 左右,上样 20000 时可能到 8% 以上。你可以用这个比例作为先验值,再根据预测结果微调阈值。
不过要清楚,双细胞预测不是万能的。两个相同类型的细胞形成的同源双细胞,表达谱和单个细胞几乎一模一样,任何工具都没法识别。还有一类情况是双细胞比例极低,比如低于 1%,工具可能会为了降假阳性而把它们放过。所以双细胞过滤只解决了一部分问题,后续聚类之后发现某 cluster 同时高表达两套不相关 lineage 的 marker,要果断回过来检查它是不是漏网的双细胞。
3.4 哪些细胞不能无脑过滤
质控阶段经常被误杀的是那些“本身就低表达”的真实细胞。比如静息 T 细胞、静止的干细胞,甚至某些组织的基质细胞,它们的基因数和 UMI 数天然比活跃增殖的细胞低一个量级。如果按全样本统一阈值过滤,它们是最先被清掉的一批。
另外,红细胞污染和血小板污染也值得单独判断。红细胞几乎没有细胞核,但它的珠蛋白基因表达量极高,如果解离过程溶血严重,血红蛋白基因会占掉相当大比例的 UMI,反过来压低其他基因的检出。血小板则更特殊,它们没有细胞核,但会粘附在其他细胞表面,导致某些 cluster 里出现高水平的血小板标志基因 PF4、PPBP,这通常不是真的新亚群,而是污染信号。
对这些干扰,合理的策略是做针对性处理而不是统一过滤。比如把血红蛋白基因和血小板标志基因放进一个排除列表,在 ScaleData 或者高变基因选择阶段把它们移除,而不是直接把整个细胞删掉。造血组织的真实巨核细胞是正常细胞类型,不能因为表达血小板标志就把它们和血小板污染混为一谈。
4. 标准化、降维和聚类:这一步决定你所有下游图的走向
4.1 LogNormalize 与 SCTransform 的选型逻辑
Seurat 的 NormalizeData 默认方法是 LogNormalize,核心是先把每个细胞的 UMI 总数缩放到一个统一的文库大小,再取对数。它简单、稳定、生态支持最全,对大部分转录组项目完全够用。SCTransform 则是基于负二项回归的方差稳定化方法,它会把 UMI 深度与基因表达之间的关联建模并移除,在处理测序深度差异极大的数据集时,聚类往往更干净,代价是计算量显著上升。
我的取舍标准很简单:样本数不多、细胞类型清晰、测序深度比较均匀的项目,用 LogNormalize 就好,没必要为了“新方法”而新。如果样本之间测序深度差异悬殊,比如不同批次取材时间隔了一整年,或者下游计划跑 SCTransform 配套的整合流程,那就用 SCTransform。有一点要特别注意,用 SCT 的时候不要再额外做一遍 LogNormalize 再跑整合,因为 SCT 的模型已经包含了 UMI 深度的校正,叠加标准流程会把方差结构搅乱。
4.2 高变基因数和主成分数不是固定的
FindVariableFeatures 默认选 2000 个高变基因,这个参数在大部分项目里够用,但数据越复杂越需要增加。肿瘤微环境这种上皮、免疫、基质多种细胞类型混在一起的数据,我会先跑 2000 看一版,然后加到 3000 或 4000 再跑一版,比较两批特征基因的组成和聚类稳定性。如果某类细胞的 lineage marker 根本没有进入高变基因列表,那聚类结果几乎不可能把这类细胞分开。
主成分数的选择更是这样。ElbowPlot 只是一个参考工具,它显示的“拐点”不代表标准答案。我在实操中会跑一个 30 到 50 维的 PCA,然后分别用不同的 PC 数做聚类,观察哪一组数据得到的 UMAP 分离度和注释结果最稳定。如果注释结果对 PC 数特别敏感,比如少一个 PC 就丢一个亚群,说明数据里噪声偏多或者标志信号不够强,这时候应该回到上游检查过滤参数,而不是继续加 PC 硬撑。
4.3 UMAP 和 tSNE 不是同一类工具,别混着用
很多教程会把 UMAP 和 tSNE 并列介绍,好像它们是同一个目的下的两个可选项。实际上它们保留的信息结构不同:tSNE 更偏局部结构,对局部邻域的保持非常敏感,代价是全局拓扑会被拉伸变形;UMAP 在局部和全局之间找平衡,聚类边界往往更清楚,但某些细微的过渡状态可能被忽略。
聚类判断的依据是聚类结果本身,不是 UMAP 图的“一堆点长得像不像”。我遇到过不少次,UMAP 上看起来两个 cluster 是分开的,但用 FindMarkers 验证后发现差别的基因全是核糖体蛋白或应激基因,没有真正的生物学意义。反过来也有 UMAP 上几乎贴在一起的几个 cluster,通过 marker 验证被证明是不同细胞类型。
画 UMAP 的时候,n.neighbors 和 min.dist 这两个参数值得手动调一下。n.neighbors 小,局部结构更细腻但容易碎成散点;n.neighbors 大,全局结构更清楚但小亚群可能被糊掉。我有一次分析 T 细胞亚群,默认参数下 CD4 和 CD8 完全没有分开,把 n.neighbors 调到 20、min.dist 调到 0.1 之后,两组细胞边界清楚得多。所以 UMAP 参数本身就是可视化调优工具,在聚类结果不变的前提下,调到最能反映 cluster 边界的参数是合理的。
4.4 聚类分辨率:多出来的群不一定是真的
FindClusters 的 resolution 参数直接决定 cluster 数量,也是新手最爱调的一个旋钮。分辨率越高分群越多,但多出来的群不一定是真实生物学亚型。最常见的情况是原本一群 T 细胞在 resolution 从 0.5 升到 1.2 后被劈成七八个碎块,其中大部分没有 marker 支撑,只是被增殖基因、热休克蛋白基因或线粒体转录本驱动出来的“伪差异”。
我的方法是从低分辨率开始,先看大类是否清晰,然后逐级上调。每上调一档,新增的 cluster 都要做一轮验证:它和邻近 cluster 的差异基因是什么、这些差异基因有没有已知的 marker 支撑、在独立样本里能不能稳定复现。如果新 cluster 的唯一区别是 HSP 基因和核糖体基因高表达,那它大概率是应激造成的裂解,不是生物学上值得关注的新亚群,直接合并或者忽略都行。
5. 批次效应:什么时候校正、怎么校、校过头了怎么办
5.1 先判断是不是真的需要校正
批次校正工具不是无脑用的,它们会拟合出一个“批次偏移”并把它抹掉,如果在不需要校正的数据上强行使用,代价是真实的生物学差异被一起抹掉。所以在任何校正之前,先画一张按样本着色的 UMAP,问自己三个问题:样本是完全分离还是混在一起?分离的维度是否对应实验分组(比如处理组和对照组)?如果不对应实验分组,分离是不是来自技术批次(上机时间、测序平台、试剂批次)?
如果分离主要来自实验分组,那这是生物学差异,不是批次效应,不能校正。如果分离来自技术批次,还要再看有没有一个隐蔽因素:各样本中细胞类型群落比例本身就不同。比如一组样本上皮细胞比例高、另一组免疫细胞比例高,UMAP 上也会呈现明显分组,但这种分组来自组织构成的真实差异,套用批次校正反而会抹掉肿瘤微环境的核心特征。
5.2 Harmony 与 Seurat 整合的适用场景
批次校正目前最常用的两条路线是 Harmony 和 Seurat 的 IntegrateData。Harmony 直接在 PCA 降维之后的 embedding 上做迭代校正,然后基于校正后的 embedding 跑聚类和 UMAP。它的速度极快,内存压力小,适合动辄十万、几十万细胞的规模化数据。由于它不改变原始表达矩阵,下游做差异表达时仍然可以用原始的 RNA assay 数据,这让它的“侵入性”相对较小。
Seurat 的 IntegrateData 则更重,它基于 CCA 或 RPCA 锚定细胞对来整合数据,再把多个样本对齐到共享空间中。CCA 整合比较擅长跨平台、跨物种或者差异极大的数据,比如正常组织和肿瘤组织的联合分析;RPCA 是 CCA 的高效版本,适合细胞量大的场景。代价是整合过程计算开销大,而且整合后的对象结构更复杂,刚上手很容易搞不清到底该用哪个 assay 做下游分析。
我个人习惯:同一批次内多个样本,或者批次来源比较单一的数据,优先用 Harmony;跨批次、跨平台甚至跨物种的数据,优先考虑 Seurat 整合。但不管用哪条路线,校正后都要重新验证一遍已知细胞类型 marker 的表达,确认校正没有把能够区分的细胞群糊到一起。
5.3 过度校正的三个识别信号
过度校正的第一个信号,是我前面提到的:原本能够区分的细胞类型被混到了一起。比如肿瘤上皮和正常上皮本来表达差异明显,校正后完全叠成一团,找不出差异基因。第二个信号是“塑料感”比例:各样本的细胞类型比例在整合后变得高度一致,等于说生物学上的样本间差异被强行抹平了,这种情况下后续样本间比较会变得非常“干净”,但这种干净是假的。
第三个识别方法是回到 marker 基因做验证。校正后随机的跑几个已知 lineage 标志基因,比如 T 细胞的 CD3D、巨噬细胞的 CD68,看它们的表达是不是仍然集中在对应 cluster。如果这些标志基因在整合后被打散到多个 cluster 且表达量接近背景,说明校正强度过大,需要调整参数或者换一种校正策略。
6. 细胞类型注释:自动注释只是参考,手动注释决定论文质量
6.1 自动注释工具为什么只能做参考
用 SingleR、CellTypist 这类工具跑自动注释已经很普及,它们的原理是一致的:把待注释细胞的表达谱与参考数据集的已知类型做相似性比对,返回最可能的标签。问题在于参考数据集本身有覆盖偏差。大部分公开参考集在免疫细胞和血液细胞上训练得最充分,遇到组织特异性细胞、罕见亚群、肿瘤细胞时,给出的标签经常不可信。
我自己测试过的常见错误包括:上皮细胞被注释成巨噬细胞(因为肿瘤上皮高表达某些髓系相关基因)、内皮细胞被注释成成纤维细胞(因为间质基因的重叠)、γδT 细胞被注释成 NK 细胞(因为共享杀伤功能相关基因)。这些错误单个看有它的“合理性”,但整体上离真实生物学非常远。
自动注释的正确用法是提供初始感知:这团细胞大概率属于淋巴系还是髓系、间质还是上皮。它相当于一个粗筛,不能作为最终注释写进任何报告。真正的注释必须落到手动验证上。
6.2 手动注释的执行顺序:先大类后亚群
手动注释看起来玄学,实际上有一套固定框架。我的顺序分两层:第一步,在较低分辨率的聚类结果上确定每个 cluster 的大类,比如 T/NK、B、髓系、上皮、内皮、成纤维细胞。这一步的关键是找公认稳定的 lineage marker,用 DotPlot 把候选 cluster 和 marker 基因做成矩阵对比,比一个一个画 FeaturePlot 高效得多。
第二步,对感兴趣的细胞大类做二次聚类,进入亚群注释。T 细胞要区分 CD4、CD8、Treg、γδT,就必须把 T 细胞单独圈出来重新做降维聚类,因为全数据层面的 cluster 分辨率不够,亚群会被淹没在主群里。二次聚类时要注意重新选择高变基因和主成分数,不能复用全局参数。这一步是手动注释的核心工作量所在,也是注释质量的分水岭。
6.3 marker 验证三件套:只看 UMAP 等于没验证
注释完之后,每个人都觉得自己的 UMAP 很漂亮,但漂亮不代表正确。我要求自己至少做三层验证。
第一层,FeaturePlot 画关键 marker,看表达是否集中在对应 cluster,而不是全图弥散。第二层,DotPlot 把每个注释类型的 3 到 5 个核心 marker 放在一起,看点的大小和颜色是否和预期一致。第三层,用 VlnPlot 或平均表达量表,把每个 cluster 的 marker 表达量做成数值表格。如果某个 cluster 同时高表达 CD3D 和 CD68,基本只有两种可能:它是 T 细胞-髓系双细胞,或者注释流程有问题,两种情况都说明这个 cluster 不能直接拿来用。
marker 来源我一般用三层交叉:CellMarker 2.0 数据库、PanglaoDB、以及目标组织近五年的单细胞论文。不同组织的同类细胞 marker 有差异,盲目套用血液免疫的 marker 列表到肝脏或脑组织,很容易出错。
6.4 “新细胞类型”要先怀疑,再验证
手动注释中最让人激动的瞬间是发现一个“教科书里没写过的新亚群”。我的建议是,对这类发现保持高度警惕,尤其是它同时具备以下特征:没有专一的核心 marker,差异仅由应激基因、核糖体蛋白基因或低表达基因组驱动;在 UMAP 上位置正好位于两个已知亚群之间;在不同样本间不能稳定复现。
这类情况大概率是双细胞、过渡状态或者批次残留,不是真正的罕见亚群。一个可信的罕见亚群一定有自己稳定的核心 marker 组合,并且在独立样本中能重复出同样的 cluster 和 marker 模式。判断新类型之前,先回到原始数据里把它自己一个个细胞翻出来看,图片来源、批次、双细胞分数、marker 共表达情况都查一遍,再做结论。
7. 差异表达、富集、拟时序与细胞通讯的实际教训
7.1 FindMarkers 的默认参数会漏掉低表达但重要的基因
Seurat 的 FindMarkers 默认用 Wilcoxon 检验,logfc.threshold 默认为 0.25,这个阈值会把表达变化不剧烈的基因全部过滤掉。很多细胞因子、趋化因子、受体分子的表达量本来就很低,fold change 也不大,但生物学意义很强,默认参数跑下来它们全部不显著。
我的做法是跑两轮差异表达。第一轮按默认参数稍加严格,得到核心差异基因集,用于火山图和总览。第二轮不设 logfc.threshold,只按调整后 P 值筛选,专门找那些低表达但显著的基因。然后把两轮结果交叉比对,重点看第二轮里有哪些基因是已知的信号分子或调控因子。这个方法虽然会让差异基因列表变长,但确实比单跑一轮默认参数稳得多。
7.2 富集分析不要只拿“显著基因”跑
很多人把差异表达结果中调整后 P 值小于 0.05 的基因提取出来,然后喂给 clusterProfiler 跑 GO 或者 KEGG。这种做法本身没错,但它有一个天然的不稳定性:差异基因数量越少,富集结果就越脆弱。如果最终显著基因只有三五十个,富集出来的通路往往是由两三个种子基因强行拉起来的,换一版阈值结果就翻天覆地。
更稳的方案是做全基因排序的 GSEA。用 log2FC 对整个基因列表排序,不管它是不是显著,然后跑 fgsea 或 clusterProfiler 的 GSEA 功能。这样做所有基因都对结果有贡献,不会被显著性阈值左右,重复实验之间的结果稳定性也好很多。富集分析的本质是找“协调变化的一组基因与哪些通路相关”,而不是验证“我手里的几十个基因在哪些通路富集”。
7.3 拟时序的“方向”不是算法告诉你的
monocle3 是目前做拟时序分析最常用的工具,但很多人不知道算法本身不知道你的生物学故事该从哪头开始。如果不显式设定根细胞,默认的根节点可能是随机的,或者是算法按自己规则定的,跑出来的“分化轨迹”有时候正好和你的预期反向。
正确流程是:先明确轨迹的起点应该是什么细胞状态。比如分析 T 细胞耗竭轨迹,起点应该是 naive 或记忆 T 细胞,终点是耗竭 T 细胞。在 monocle3 里要显式设定 root 节点,选哪些细胞作为根需要结合 marker 表达和领域知识来判断,不能拍脑袋。轨迹方向的错误很难通过看图发现,因为反向的轨迹看起来也像一条平滑的“分化路径”,但它讲出来的故事是完全错误的。
7.4 细胞通讯分析最容易过度解释
CellChat、CellPhoneDB、NicheNet 这类工具在单细胞论文里几乎成了标配,但它们也是单细胞数据分析里最容易被过度解读的部分。这些工具的本质是基于配体-受体数据库做富集判断,数据库覆盖度、输入细胞类型的分辨率、归一化方式都会强烈影响结果。跑出来一堆“显著通讯”,并不代表这些配体-受体对在组织里真的发生了互作。
我自己内部设了一套验证标准:先看总通讯强度排在最前面的几对细胞类型是否在生物学上有意义,再看这些配体-受体关系在文献中有没有支持,最后看配体和受体基因在对应细胞亚群里的实际表达量。如果某个通讯连接在文献里没有先例、只有一条很小的 P 值支持,我不会把它写进报告。细胞通讯分析应该作为假设生成工具,而不是用来“证明”某个机制的手段。
另外,如果你想在单细胞项目里分析免疫组库(BCR/TCR),比如与标题相关的 BCR 单细胞分析,那要明确这是另一套数据逻辑。免疫组库分析依赖 cellranger vdj 流程产出的克隆型数据,核心看克隆组成、克隆扩增、V/J 基因使用频率,再把这些信息与表达矩阵的细胞亚型关联起来。不要试图把 VDJ 信息硬塞进 Seurat 的 RNA assay 里当普通表达数据算,两套数据各自处理之后再做联合分析才是合理的路线。
8. 最后以我实际踩坑换来的几条提醒
这篇笔记里的每一条经验,都是拿真实课题数据换来的。跑通单细胞标准流程只需要一天,但真正理解每个环节在做什么、为什么这么做,需要好几个项目周期反复锤炼。我最后再分享几个对我最有用的检查习惯。
第一,每更换一批数据,质控参数必须重新评估,哪怕它是同一类组织。我见过同一套立式流程跑完新样本之后,硬生生把一个细胞类型整体过滤掉了,只因为新样本的平均基因数比训练样本低一截。第二,zUMI 跑完聚类后,先不要急着注释,先按样本着色看一遍 UMAP、按已知 marker 看一遍 DotPlot,这两个动作能帮你避开大部分假阳性。第三,遇到任何“看起来很好”的结果,特别是新亚群、强通讯、显著富集,先怀疑数据,再怀疑自己,最后才考虑写进报告。这样虽然过程慢,但最终拿到的结论经得起审稿人和合作者反复追问。