☰
单细胞数据整合实战:Harmony参数调优与过度整合避坑指南
2026/10/14 0:04:28 网站建设 项目流程

单细胞转录组测序这几年从"新鲜技术"变成了很多课题组的常规武器,但真正让做分析的人头疼的,往往不是测序本身,而是手上攒了七八个样本、横跨三四个批次之后,怎么把它们揉成一个能用的对象。我见过太多人在这步翻车:要么整合完细胞类型全混在一起,要么过度整合把真实的生物学差异抹平了,最后图是画出来了,结论却站不住脚。这篇就围绕单细胞数据整合这件事,把我在实际项目里踩过的坑、试过的方案、以及每个参数背后的逻辑,尽量讲透。不管你是刚拿到一批数据的新手,还是已经跑过几轮整合但结果总不太对劲的老手,下面这些内容应该都能对上你的某个具体问题。

1. 先搞清楚:整合到底在解决什么问题

1.1 批次效应的本质不是"错误",而是技术噪声

很多人一上来就把批次效应当成bug,恨不得除之而后快。这个理解是偏的。批次效应的来源非常具体:不同时间点建库、不同操作人员、不同试剂批次、不同测序仪通道,甚至同一个样本分两次上机,都会引入系统性的表达偏移。它的本质是技术因素导致的、与生物学无关的表达差异。

关键在于"与生物学无关"这个限定。如果两个批次之间本来就存在真实的生物学差异(比如一个批次全是处理组、另一个批次全是对照组),那你在整合时就必须格外小心,因为算法分不清哪些差异该保留、哪些该消除。这就是为什么实验设计阶段要尽量让每个批次里都包含各种实验条件,做到"批次与生物学条件不共线"。我见过一个项目,四个批次里前两个全是对照组、后两个全是处理组,整合完之后处理效应几乎被抹平,这种设计上的硬伤,后期任何算法都救不回来。

所以整合的目标从来不是"让所有细胞混在一起",而是在保留真实生物学差异的前提下,消除技术性的批次偏移。这个目标听起来简单,但它是后面所有参数选择的判断标准。

1.2 不整合会怎样:三个典型症状

不整合直接合并(比如简单地把多个对象的count矩阵cbind起来)会出现什么?我总结下来有三个典型症状,你可以对照自己的数据看看。

第一个是聚类按样本分而不是按细胞类型分。UMAP图上每个样本自成一坨,同一类细胞在不同样本里被拆成好几个cluster。这时候你去做差异分析,得到的全是样本间差异,不是细胞类型间差异。

第二个是标记基因表达出现"断层"。比如某个T细胞标记基因,在A样本的T细胞里高表达,在B样本的T细胞里却几乎不表达,但两个样本的T细胞明明是同一类。这种断层就是批次造成的。

第三个是细胞类型比例失真。如果不同批次对某些细胞类型的捕获效率不同,合并后比例会严重偏离真实情况,下游的组成分析全部不可信。

这三个症状里,第一个最容易观察到,也最容易被误判成"我的样本异质性就是这么大"。判断方法很简单:看cluster和样本的对应关系,如果高度重合,基本就是批次问题。

1.3 什么情况下可以不整合

不是所有多样本数据都需要整合。如果你的所有样本是同一时间、同一操作者、同一批次建库测序的,批次效应可能非常微弱,这时候强行整合反而可能引入假象。判断标准是:先做一次不整合的合并,看UMAP上样本是否明显分离。如果样本间混合得很好,细胞类型也能对上,那就没必要整合。

另一个例外是样本间生物学差异本身就是研究目标。比如你就是要比较疾病组和对照组,且两组是不同批次测的,这时候整合要非常保守,甚至可以考虑不整合、改用其他策略(比如分别分析再比较)。整合是一把双刃剑,用之前先想清楚你要保留什么。

2. 主流整合方案的技术路线对比

2.1 从CCA到RPCA再到Harmony:三代方法的演进逻辑

单细胞整合方法这几年迭代很快,但主线其实很清晰。第一代以Seurat的CCA(典型相关分析)为代表,思路是找到两个数据集之间表达模式最相关的维度,然后在这些共享维度上做对齐。它的优点是能捕捉比较复杂的非线性关系,缺点是计算量大、对细胞数敏感,而且容易过度整合。

第二代是RPCA(鲁棒主成分分析),Seurat v3之后主推。它不再找"共享"维度,而是把每个数据集投影到一个公共空间,同时保留各自的特异结构。相比CCA,RPCA在保留生物学差异上更稳,计算也更快,是目前Seurat工作流里的默认推荐。

第三代是Harmony,思路完全不同。它不重构表达矩阵,而是在PCA降维之后,迭代地调整每个细胞的低维坐标,让批次间的同一类细胞靠拢。Harmony的优势是快、内存友好、对大数据集友好,而且它直接在降维空间操作,不改变原始表达值,所以下游做差异分析时不会因为整合而失真。这也是为什么Harmony在很多场景下成了首选。

三代方法没有绝对的优劣,关键看你的数据规模、批次复杂度和研究目标。下面这张表是我根据实际使用经验整理的对比,参数和表现都是常见实践下的典型值。

方法核心思路适用规模计算速度过度整合风险典型场景
CCA找共享相关维度对齐中小规模(<5万细胞)慢较高批次差异大、样本少
RPCA投影到公共空间保留特异结构中等规模中等中等Seurat默认工作流
Harmony降维空间迭代校正坐标大规模(>10万细胞)快较低多样本、多批次常规整合

2.2 为什么Harmony在多数场景下更省心

我自己的项目里,Harmony用得最多,原因很实际。第一,它不碰原始表达矩阵,这意味着你整合完之后做差异表达分析,用的还是真实的count值,不会因为整合算法"编造"了表达量而得到假阳性。第二,它的输入就是PCA坐标,你前面怎么降维、选多少主成分,它都能接,灵活。第三,它对批次数量不敏感,五六个批次和十几个批次都能处理,不像CCA那样批次一多就崩。

但Harmony也有它的边界。它假设批次效应在降维空间里是可以用线性方式校正的,如果批次效应非常复杂、非线性很强,Harmony可能校正不干净。另外,Harmony的校正强度由参数控制,调不好同样会过度整合。所以"省心"是相对的,参数还是得调。

2.3 选型决策:三个问题帮你定方案

面对一个具体项目,怎么选?我一般问自己三个问题。

第一个问题:细胞总数多少?超过10万,优先Harmony,CCA基本不用考虑,RPCA也要看机器内存。5万以下,三个都能试。

第二个问题:批次之间差异有多大?如果UMAP上样本分离得非常厉害,说明批次效应强,可以考虑CCA或RPCA这种"力度大"的方法;如果只是轻微分离,Harmony足够。

第三个问题:下游要不要做严格的差异分析?如果要,优先Harmony,因为它不改表达值。如果只是做细胞类型注释和比例分析,三个都行。

这三个问题问完,方案基本就定了。实际项目里我经常是先用Harmony快速跑一版看整体结构,如果发现某些批次校正不理想,再回头试RPCA做对比。

3. Harmony整合的完整实操链路

3.1 整合前的数据准备:质控和标准化不能省

Harmony虽然是在降维空间操作,但前面的质控、标准化、降维一步都不能马虎,因为这些步骤直接决定了PCA坐标的质量,而PCA坐标就是Harmony的输入。输入是垃圾,输出必然是垃圾。

质控阶段我通常关注三个指标:每个细胞检测到的基因数(nFeature_RNA)、每个细胞的总count数(nCount_RNA)、以及线粒体基因占比(percent.mt)。阈值没有统一标准,得看组织类型。比如PBMC这种细胞类型单一的样本,nFeature在200到2500之间比较合理,percent.mt控制在10%以下;但如果是肿瘤组织或心肌这类线粒体本来就丰富的组织,percent.mt的阈值可能要放宽到20%甚至更高。我一般会先画小提琴图看分布,再定阈值,而不是套用网上的固定数字。

标准化用LogNormalize,scale因子默认10000。这一步是把每个细胞的count除以自己的总count再乘10000,然后取log,目的是消除测序深度差异。做完标准化后,找高变基因(HVG),通常选2000个。HVG的选择会影响后续PCA,进而影响Harmony,所以这一步也别偷懒,可以用FindVariableFeatures的默认vst方法,也可以根据数据特点调整selection.method。

提示:如果你的数据里包含不同物种或不同组织,HVG最好分别找再取交集,直接合并找HVG可能被某个占主导的样本带偏。

3.2 多样本合并的正确姿势:merge还是split

这一步是很多人出错的地方。Seurat里合并多个样本有两种方式:merge和split。merge是把多个对象合成一个大对象,split是在一个大对象里按样本分层。做Harmony整合,我推荐用merge,因为Harmony需要所有细胞的PCA坐标在同一个矩阵里,merge之后跑一次PCA就行。

合并的时候有个细节:样本信息一定要保留在metadata里。通常用add.cell.ids参数给每个样本的细胞加前缀,避免细胞条码重复。合并后检查一下table(obj$orig.ident),确认每个样本的细胞数对得上。

# 假设有四个样本对象 s1 s2 s3 s4 obj <- merge(s1, y = c(s2, s3, s4), add.cell.ids = c("S1", "S2", "S3", "S4"), project = "integrated_project") table(obj$orig.ident)

合并后重新做标准化、找HVG、scale、PCA。注意,PCA要在合并后的对象上做,不是在单个样本上做。因为Harmony需要所有细胞共享同一套主成分。

3.3 跑Harmony:参数怎么设、结果怎么看

Harmony的核心函数是RunHarmony,输入是PCA降维后的对象,指定批次变量。批次变量就是你的样本来源,通常是orig.ident。

library(harmony) obj <- RunHarmony(obj, group.by.vars = "orig.ident", reduction = "pca", dims.use = 1:30, assay.use = "RNA", max.iter.harmony = 20)

几个关键参数。dims.use选多少主成分,这个和PCA阶段保持一致,一般20到30。选太少信息不够,选太多噪声进来。max.iter.harmony是迭代次数,默认10,我一般设20,让它充分收敛,但也不是越大越好,太大可能过拟合。theta参数控制校正强度,默认2,批次差异大的时候可以调到3到4,但调太高会过度整合。

跑完之后,用Harmony的降维结果做UMAP和聚类。这时候看UMAP,如果样本混合得比较均匀、细胞类型能聚成合理的cluster,就说明整合有效。如果还是按样本分离,可能是dims.use太小或theta太低;如果所有细胞糊成一团、细胞类型分不开,那就是过度整合,要降theta或减dims。

obj <- RunUMAP(obj, reduction = "harmony", dims = 1:30) obj <- FindNeighbors(obj, reduction = "harmony", dims = 1:30) obj <- FindClusters(obj, resolution = 0.5) DimPlot(obj, reduction = "umap", group.by = "orig.ident") DimPlot(obj, reduction = "umap", label = TRUE)

3.4 整合效果的量化评估:别只看UMAP

UMAP好看不代表整合成功,这是我最想强调的一点。UMAP是高度压缩的二维投影,它可能掩盖很多问题。我一般会配合几个量化指标一起看。

第一个是批次混合熵(batch mixing entropy),衡量每个cluster里不同批次细胞的混合程度,越高越好。第二个是细胞类型一致性,用已知标记基因检查每个cluster的细胞类型是否在批次间一致。第三个是kBET或LISI这类专门的批次评估指标,LISI分iLISI(批次混合)和cLISI(细胞类型分离),理想情况是iLISI高、cLISI低。

实际操作里,如果不想装太多包,至少做两件事:一是看每个cluster的批次组成,用table(obj$seurat_clusters, obj$orig.ident),如果某个cluster几乎全来自一个批次,要警惕;二是用几个经典标记基因画feature plot,看表达是否在批次间连续。

4. 过度整合:比不整合更隐蔽的坑

4.1 过度整合的三种表现

过度整合是整合分析里最危险的问题,因为它看起来"很成功"——UMAP上细胞混得特别均匀,cluster边界清晰,一切都很美好。但实际上,真实的生物学差异被抹掉了。

表现一:本该分开的细胞类型被合并。比如初始T细胞和记忆T细胞,它们本来有明确的转录差异,过度整合后可能被强行拉到一起,变成一个cluster。

表现二:处理组和对照组的差异消失。你明明做了处理,整合后两组细胞完全混合,差异基因一个都找不出来。这时候不是处理没效果,是整合把效果消掉了。

表现三:标记基因表达被"平均化"。某个基因在A群细胞高表达、B群低表达,过度整合后所有细胞表达都差不多,feature plot上一片均匀。

这三种表现里,第二种最容易被误判。很多人看到处理组对照组混合,第一反应是"我的处理没效果",其实可能是整合参数太激进。

4.2 怎么判断是不是整合过头了

判断过度整合,我有一套自己的检查流程。首先,在整合前的PCA或UMAP上看一遍,记住哪些细胞类型是明显分开的。整合后再看,如果原本分开的现在合并了,就要怀疑。

其次,用已知的、可信的标记基因做验证。选几个你百分百确定应该差异表达的基因,看整合后它们的表达模式是否还保留。如果全被抹平,就是过度整合。

第三,对比不同参数下的结果。把theta从2调到1,或者dims从30降到20,重跑一遍,看细胞类型是否重新分开。如果参数一降就分开,说明原来的设置确实过头了。

第四,看iLISI和cLISI的平衡。如果iLISI很高但cLISI也很高(意味着细胞类型也被混了),就是过度整合。

4.3 回调参数的具体操作

确认过度整合后,怎么调回来?按影响程度从大到小,依次调这几个。

先降theta。这是校正强度,从默认2降到1甚至0.5,让校正力度减弱。这是最直接的手段。

再减dims.use。主成分少了,保留的生物学结构反而更"粗",不容易被过度校正。从30降到20试试。

然后可以调max.iter.harmony。迭代次数少了,校正不充分,反而保留了更多原始结构。但这个手段比较粗暴,一般不首选。

最后,如果怎么调都过度整合,可能要考虑换方法,比如改用RPCA,或者干脆不整合、用其他策略处理批次。

注意:调参不是越低越好。theta太低、dims太少,又会回到不整合的老问题。理想状态是在"批次混合"和"生物学保留"之间找平衡点,这个点因数据而异,没有万能值。

5. 整合后的下游分析注意事项

5.1 差异表达分析:用哪个assay很关键

整合完之后做差异表达,assay的选择直接影响结果可靠性。如果你用的是Harmony,它没有改变原始表达值,所以差异分析直接用RNA assay的count或data就行,不需要特殊处理。但如果你用的是Seurat的CCA或RPCA整合,整合结果存在integratedassay里,这个assay里的值是校正过的,不建议直接拿来做差异分析,因为校正过程可能引入假信号。

正确做法是:用整合结果做聚类和UMAP,但差异分析回到原始RNA assay。Seurat官方也推荐这个流程。具体操作是在FindMarkers里指定assay = "RNA",并且用slot = "data"(标准化后的值)。

markers <- FindMarkers(obj, ident.1 = "0", ident.2 = "1", assay = "RNA", slot = "data", only.pos = FALSE, min.pct = 0.25, logfc.threshold = 0.25)

5.2 细胞类型注释:整合后注释更稳还是更乱

整合的一个好处是细胞类型注释可以跨样本共享。因为整合后同一类细胞聚在一起,你只需要注释一次,所有样本都适用。这比每个样本单独注释再手动对齐要高效得多。

但整合也可能让注释变难。如果过度整合,某些细胞类型被合并,你可能会把一个cluster注释成单一类型,实际上它包含两种。所以注释阶段要结合多个标记基因,不要只看一个。我一般会准备一套marker panel,每个cluster至少用三到五个基因交叉验证,必要时做亚聚类。

另外,整合后的cluster里如果批次组成极不均匀(比如某个cluster 90%来自一个样本),要警惕这个cluster可能是批次特异的假cluster,而不是真实的细胞类型。

5.3 细胞比例分析:整合会不会扭曲比例

细胞比例分析是很多课题的重点,但整合对比例的影响经常被忽略。整合本身不改变细胞数量,所以理论上比例不变。但整合会改变聚类结果,如果整合把某些细胞归到了不同的cluster,比例就会变。

更隐蔽的问题是:如果不同批次对某类细胞的捕获效率不同,整合后这类细胞的比例反映的是"捕获到的比例",不是"真实比例"。这个问题在整合前后都存在,不是整合引入的,但整合容易让人忽略它。

做比例分析时,我建议同时报告整合前后的比例,并说明差异来源。如果差异很大,要谨慎解读。

6. 几个真实项目里的踩坑记录

6.1 批次与条件共线:一个救不回来的设计

前面提过这个坑,这里展开说。有个项目,六个样本分两批测,第一批三个全是对照,第二批三个全是处理。整合的时候不管用什么方法,处理效应都被大幅削弱。因为算法看到的是"批次间差异",它无法区分这是技术批次还是生物学处理。

最后的补救是:放弃整合,改成在每个批次内部做配对分析,再比较两批的结果。虽然统计效力下降,但至少结论方向是对的。这个教训是,实验设计阶段就要避免批次和条件共线,每个批次里都要有各种条件。

6.2 细胞数极度不平衡导致的"淹没"

另一个项目,一个样本有3万细胞,另一个只有2千。整合后,小样本的细胞几乎被大样本淹没,在UMAP上完全贴在大样本的cluster里,看不出自己的结构。这是因为Harmony的校正是在全局做的,细胞数少的批次权重低。

解决办法有两个:一是下采样大样本,让各样本细胞数接近;二是用group.by.vars时给不同批次加权(部分工具支持)。我一般选下采样,简单直接,虽然损失一些细胞,但整合结果更均衡。

6.3 整合后marker基因"消失"的排查过程

有次整合完,一个原本很明确的marker基因在feature plot上几乎看不到了。排查过程是这样的:先确认基因名没写错,再看不整合的版本里这个基因表达是否正常——正常。然后怀疑过度整合,把theta从2降到1重跑,基因表达恢复了。最后定位到是theta设太高。

这个排查链路的关键是保留一个不整合的版本作为对照。任何时候整合结果不对劲,先和不整合的版本比,能快速定位是整合的问题还是数据本身的问题。

6.4 内存爆掉的几种情况和应对

Harmony虽然省内存,但数据量特别大的时候还是会爆。我遇到过几次,总结下来几个原因:一是细胞数超过20万,PCA矩阵太大;二是dims.use设太高,比如设了50;三是同时开了多个R会话。

应对方法:细胞数大就分批整合或下采样;dims.use控制在30以内;跑之前清一下内存,gc()一下。如果还是不够,考虑用Harmony的Python版本或者换用更省内存的工具。

7. 写在最后的一点个人体会

整合这件事,工具和方法固然重要,但更关键的是你对自己数据的理解。你得知道哪些差异是真实的、哪些是技术造成的,才能判断整合结果对不对。我见过太多人把整合当成一个"跑完就行"的步骤,参数全用默认,结果出来也不验证,最后结论出问题都不知道错在哪。

我的习惯是,每次整合都至少跑两个参数版本,一个保守一个激进,对比着看。保守版本保留更多生物学差异,激进版本批次混合更好,然后根据研究目标选。如果两个版本结论一致,那结论就很稳;如果不一致,就要深挖原因。

另外,整合不是终点,是起点。整合完的object要拿去做注释、差异分析、轨迹分析等等,每一步都可能引入新问题。整合阶段埋下的雷,后面会一个个爆出来。所以这一步多花点时间,绝对值。

最后分享一个实用小技巧:把每次整合的关键参数和对应的UMAP图存下来,建一个自己的"参数-效果"对照表。跑的项目多了,你会慢慢摸出适合自己常用组织类型的参数范围,下次直接从这个范围起步,能省很多试错时间。这个表我现在攒了十几行,每次新项目先查表,效率高不少。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询