一个触底的 P 值:同一份肝硬化数据,两种都说得通的算法,给出互不相容的结论
我们重新分析 Ramachandran 等人的人肝脏单细胞数据时,第一轮组成学结果给出了一个漂亮的数字:CD45 阳性层里,NK 细胞份额在肝硬化组下降,ΔCLR −1.820,精确置换 P = 0.007937,正好落在这个设计能达到的最小值上。
这个数字后来没有出现在任何结论里。它算得没错,问题在于它可以被一个与生物学无关的因素完整解释。本文写的就是这个排查过程。原计划是一篇纤维化生态位复现,换成现在这个题目之后,结论可以复用到任何用分选文库做组成分析的项目。
一个 P 值触底意味着什么,值得先说清。0.007937 是 5 对 5 平衡设计在双侧精确置换检验下能给出的最小值,它出现时说明观测到的分组是全部 252 种重排里最极端的那一个(连同它的镜像)。这是一个关于排序的陈述,不是一个关于效应大小的陈述,更不是”这个结论有 99.2% 的概率为真”。同一个 0.007937 既可以来自一个真实的生物学差异,也可以来自任何一个恰好与分组完美对齐的技术变量——而在这份数据里,恰好有一个技术变量与分组几乎完美对齐。
论文和数据来源
| 项目 | 信息 |
|---|---|
| 论文 | Ramachandran et al., “Resolving the fibrotic niche of human liver cirrhosis at single-cell level” |
| 期刊与年份 | Nature, 2019 |
| DOI | 10.1038/s41586-019-1631-3 |
| PubMed | PMID 31597160 |
| GEO | GSE136103 |
| 矩阵层 | 公开 CellRanger 输出矩阵(20 个人肝文库) |
| 标签层 | 本次分析自行完成的 marker 打分标注 |
原论文使用了更广的分析链,包括流式验证、组织学染色与配体—受体分析;本文只讨论公开矩阵能直接支撑的再分析层。
这不是一个队列,是两条分选文库
有一件事必须先说清:这份数据的单位是文库,不是”若干供者的肝组织”。同一批供者经过 CD45 磁珠分选,得到两套文库,20 个文库分成两层:

- A 层 CD45 阳性:5 位健康供者 vs 5 位肝硬化供者,10 个文库一一对应,共 37,306 个细胞进入标注。
- B 层 CD45 阴性:4 位健康 vs 3 位肝硬化,10 个文库(其中 healthy1、healthy3、cirrhotic1 各拆成 A/B 两个技术分区),共 24,904 个细胞。
两层不能合并成一个 12 供者队列,因为分选把细胞群体本身切开了:阳性层里的内皮细胞和阴性层里的内皮细胞,是同一组织被两种富集策略采到的两个不同子集,它们的份额分母完全不同。我们的处理是把两层作为两个独立的检验族分别走完全流程,从不跨层做比较。
这条禁令不是谨慎,是算术。同一个部分在两层里的份额差到什么程度,一眼就能看出来:内皮细胞在阳性层占 3.65%,在阴性层占 24.48%;肝细胞 2.57% 对 13.95%;反过来,T 细胞 37.80% 对 11.94%,NK 30.88% 对 17.53%。这些不是两组供者的差异,是同一批供者被两种富集策略采样后的差异。把两层的同名部分放进一张表做比较,得到的会是磁珠的效果,不是肝脏的状态。
还有一层更细的问题:两层的供者集合本身不一样。阳性层是 5 对 5,阴性层是 4 对 3,缺的是 healthy5、cirrhotic4 和 cirrhotic5。所以即使抛开分母问题,两层的”组”也不是同一组人。
统计重复因此是供者,不是细胞。A 层 5 对 5 是平衡设计,双侧精确置换检验的最小可达 P 是 2/C(10,5) = 2/252 = 0.007937。B 层 4 对 3 是不平衡设计,最小可达 P 是 1/C(7,4) = 1/35 = 0.028571——分子是 1 而不是 2,因为把 4 位健康换成 3 位肝硬化得到的补集是一个大小不同的划分,它并不出现在同一个枚举里。这个区别在两层里都会影响后面每一个 q 值,所以它写在共享模块里由三篇文章共用,而不是在每个脚本里各推一遍。
分选纯度审计:一张表让头条结果失效

CD45 阳性文库理论上只含免疫细胞。我们没有假设它成立,而是逐供者测量了非免疫谱系细胞的占比:
- 5 位健康供者:1.06%、0.26%、1.43%、1.87%、1.36%——分选干净。
- 5 位肝硬化供者:23.81%、30.50%、54.24%、1.74%、1.92%。
cirrhotic3 的阳性文库里有超过一半的细胞不是免疫细胞。两组非免疫占比差异的均值是 21.24 个百分点,精确置换 P = 0.015873。也就是说,分选纯度本身在两组之间就是差异的,而且这个差异在这份数据里几乎是能测到的最强信号之一。
这件事的后果不是”有点噪音”。CLR 变换的几何中心是所有进入分析的部分的对数丰度均值。当肝硬化组混入大量肝细胞、内皮、胆管细胞时,几何中心被抬高,于是每一个免疫部分的 CLR 都被压低——不管它的绝对丰度有没有变。NK 细胞在阳性层占 30.9% 的细胞,是最大的免疫部分之一,它承受的压低也最明显。
关键在于:这个混杂不会被零膨胀门禁拦住。杂质细胞数量很大,每个样本都远高于任何合理的最小细胞数阈值,所以它们看起来是完全合格的、可估计的部分。门禁是为稀疏部分设计的,对”太多”的部分没有意见。
为什么纯度不能用 CD45 转录本来测
一个自然的想法是:既然分选依据是 CD45 蛋白,那就直接数 PTPRC 转录本被检出的细胞比例。我们把这个量也算了出来,结果说明它不能用作纯度指标。
阳性层逐供者的 PTPRC 检出比例是:健康 0.753、0.471、0.871、0.847、0.656;肝硬化 0.573、0.644、0.282、0.805、0.826。healthy2 的非免疫占比只有 0.26%,按谱系证据它是全队列最干净的一个文库,但它的 PTPRC 检出率只有 0.471——不到一半的细胞测到了这个基因。这是 droplet 数据的常规 dropout,与分选质量无关。
反方向也不成立:被判为非免疫的细胞里仍有 2.6%–28.4% 检出 PTPRC。单个基因的检出既会漏掉真阳性,也会在环境 RNA 和多重比对下给出假阳性,所以用它划线会同时高估和低估纯度,且偏差量在不同文库之间不一样。
因此纯度必须用与分选标记不同的证据来测:我们用的是多基因谱系归属(肝细胞、内皮、胆管、间质的 marker 组),也就是上一节那组数字。这一步看着琐碎,但它决定了后面整篇文章的判断是否站得住——如果用 PTPRC 检出率去审计,healthy2 会被误判成最脏的文库之一,结论会完全反过来。
可以顺着数字看一遍这个机制。健康组的阳性文库几乎全是免疫细胞,几何中心由 5 个免疫部分的对数丰度决定;肝硬化组里 cirrhotic1、cirrhotic2、cirrhotic3 分别混入 23.8%、30.5%、54.2% 的非免疫细胞,这些细胞被标注成肝细胞、内皮和胆管细胞,全部作为合格部分参与了中心的计算。中心被抬高多少,所有免疫部分就被压低多少。因此在算法一里,5 个免疫部分的 ΔCLR 全部为负(NK −1.820、Myeloid −1.048、T −0.998、B −0.309、Plasma −0.032),而 3 个非免疫部分全部为正(内皮 +1.998、间质 +1.273、肝细胞 +0.935)——符号完全按”是不是杂质”分成两组,这种整齐是混杂的特征,不是生物学的特征。
还有一个方向上的自相矛盾可以当作独立线检查:如果 NK 的下降是真实的,那么在只含免疫细胞的参照下它应该更清楚,因为噪音部分被移走了。实际相反,P 从 0.0079 涨到 0.0794。移走杂质会削弱一个信号,这个信号就很难说是被杂质掩盖的。
两种算法,都说得通,结论互不相容

面对分选杂质,有两种处理方式,两种都能写进方法学部分而不被认为是错的:
- 算法一(全部部分):CD45 阳性层里观察到的所有 8 个可估计部分都进入几何中心。理由是 CLR 要求参照集合覆盖被观察到的整个组成,人为删掉一部分就是在改变参照。
- 算法二(仅免疫区室):只把 B、Myeloid、NK、Plasma、T 这 5 个免疫部分放进几何中心。理由是这个文库的设计意图是免疫细胞,非免疫细胞是分选失败的产物,不属于被抽样的组成。
两种算法在同一份计数矩阵上给出的结果如下(阳性层,5 个两种算法都存在的部分):
| 部分 | 全部部分 ΔCLR | P | 仅免疫 ΔCLR | P |
|---|---|---|---|---|
| NK | −1.820 | 0.0079 | −0.979 | 0.0794 |
| T | −0.998 | 0.0556 | −0.156 | 0.3571 |
| Myeloid | −1.048 | 0.0952 | −0.206 | 0.6270 |
| B | −0.309 | 0.6111 | +0.533 | 0.1746 |
| Plasma | −0.032 | 0.9524 | +0.809 | 0.0238 |
5 个部分里有 2 个符号翻转(B 与 Plasma),2 个跨过 0.05 这条线(NK 从 0.0079 到 0.0794,Plasma 从 0.9524 到 0.0238)。三个非免疫部分(内皮、肝细胞、间质)在算法二里根本不存在,其中内皮在算法一里是 P = 0.0238。
换句话说:**这份数据在阳性层里”NK 是否减少”这个问题上没有唯一答案,答案取决于一个参照集合选择,而那个选择又取决于你怎么看待分选杂质。**这不是可以靠增加分析步骤解决的分歧,因为两种参照都是自洽的。
所以本文不写”肝硬化中 NK 细胞减少”。能写的只有一句:在这份分选数据上,NK 的表观变化取决于是否把非免疫杂质放进几何中心。
多重校正之后:0/8 与 0/9
即使先不管参照问题,把算法一的结果按预先定义的族边界做 Benjamini–Hochberg 校正,阳性层 8 个部分里通过 q < 0.05 的有 0 个。NK 的 q = 0.0635,是最小的一个,但它没过。阴性层 9 个部分的 q 全部等于 0.9143,也是 0/9。
这里有一个容易被误用的细节。阳性层单个部分即使 P 触底到 0.007937,在 8 个检验的 BH 框架下 q 也只能到 0.0635——一个部分单独触底在数学上无法通过校正,至少需要 2 个部分同时触底。实际触底的只有 1 个。所以”零发现”在这一层的部分原因是离散 P 值的分辨率天花板,而不能等同于”确认没有变化”。这一点我们在表里用 zero_discoveries_is_resolution_limited 显式标出,不留给读者自己推。
阴性层的最小可达 P 是 0.028571,9 个检验之下,单个部分触底给出的 q 是 0.2571,需要 6 个部分同时触底才能有任何一个通过——这个设计对组成学差异基本没有分辨力,我们据此不在阴性层报告任何组成结论。
两层的逐部分实况

把阳性层 8 个部分摊开看(算法一,ΔCLR / 精确 P / BH q):NK −1.820 / 0.0079 / 0.0635,内皮 +1.998 / 0.0238 / 0.0952,间质 +1.273 / 0.0635 / 0.1270,髓系 −1.048 / 0.0952 / 0.1524,T −0.998 / 0.0556 / 0.1270,肝细胞 +0.935 / 0.2540 / 0.3386,B −0.309 / 0.6111 / 0.6984,浆细胞 −0.032 / 0.9524 / 0.9524。
方向本身就是在讲那个混杂的故事:三个非免疫部分(内皮、间质、肝细胞)全部为正,四个免疫部分(NK、髓系、T、B)全部为负。把它读成三种独立的生物学变化加上四种独立的免疫耗竭是行不通的。一个共同原因就能解释全部七个符号:肝硬化组的分选纯度更差,非免疫细胞进来了,几何中心被抬高,所有免疫部分被同步压低。八个部分的符号排成这样整齐的两组,本身就是混杂的指纹。

阴性层 9 个部分的效应量绝对值都在 0.02–0.93 之间,最大的是胆管细胞 +0.924(P = 0.2857)和 B 细胞 +0.758(P = 0.4571),没有一个精确 P 低于 0.2571,q 一律 0.9143。这一层的 4 对 3 设计只有 35 种分配方式,观测到的排序离两端都很远。
阴性层的纯度审计给出了不同的结论:非免疫占比的组间差异是 9.17 个百分点,精确 P = 0.6571,purity_confounds_the_grouping 为假。CD45 阴性分选在这份数据里没有表现出与分组共变的纯度问题。所以阳性层的麻烦是这一层的具体事实,不能推广成”分选都不可靠”。纯度必须逐层逐样本实测,按一个总体印象处理会同时错判两层。
百分点和 CLR 回答的不是同一个问题
阳性层 NK 的原始份额变化是 −20.21 个百分点,同一部分的 ΔCLR 是 −1.820;内皮是 +9.90 个百分点对 +1.998。这两组数字方向一致,但它们的含义不同:百分点回答”占回收细胞的比例变了多少”,CLR 回答”相对于组成参照的对数比值变了多少”。
在算法二里这个差别更刺眼。B 细胞的原始份额变化是 +2.92 个百分点,ΔCLR 是 +0.533;而在算法一里同一个 B 细胞的原始份额变化是 +2.11 个百分点,ΔCLR 却是 −0.309。原始份额只换了分母(8 部分总数变 5 部分总数),符号没变;CLR 换的是参照中心,符号翻了。
所以谈组成变化时必须把参照写出来。“B 细胞增加”这句话在这份数据里既可以是真的也可以是假的,取决于跟什么比。我们在所有表里同时保留 mean_percentage_point_change 和 mean_clr_cirrhotic_minus_healthy 两列,就是为了让这个差别没法被悄悄忽略。
可估计集合在看结果之前冻结

参照集合的选择既然如此关键,就不能在看到 P 值之后再定。我们的门禁规则是硬零:一个部分必须在每一个在范围内的样本中至少出现 1 个细胞,才能进入 CLR 推断。
阳性层因此排除了胆管细胞——它在 10 个样本中有 2 个完全为零,占总细胞的 1.13%。如果强行放进去,这两个样本的对数比值会由伪计数(0.5)而不是观测丰度决定,并且因为几何中心是所有部分共享的,这个由伪计数虚构出来的数值会同时移动其余 8 个部分。阴性层 9 个部分全部通过,最紧的是 B 细胞,在 healthy1 里只有 1 个细胞。
排除决定的依据是每个样本的观测细胞数,与两组之间的差异无关,也在计算任何效应量之前完成。满足这两条它才配叫门禁;否则它只是一次筛选。
门槛阶梯与留一供者

硬零门禁的阈值 1 是我们选的,所以要检查它值不值这个信任。我们把阈值排成 1、5、20 三档,每一档重新决定可估计集合、重算效应、重算精确 P 和 q。
结果是三档给出的可估计集合完全相同(n_distinct_estimable_sets = 1),三档共享同一组结论。这说明结论不由阈值位置决定——但也说明这份数据的稀疏结构离阈值很远,阶梯在这里没有起到区分作用,不能反过来当成”我们检验过了很多情形”的证据。
留一供者审计给出 0 条地板事件:删掉任何一位供者,都不会让某个已进入分析的部分掉到门槛以下。
留一还给出另一层信息:效应的方向是否由某一位供者撑着。阳性层 8 个部分里有 6 个在删掉任意一位供者后方向不变(内皮 1.646 到 2.316、肝细胞 0.570 到 1.432、间质 0.756 到 1.593、髓系 −1.394 到 −0.766、NK −2.012 到 −1.505、T −1.235 到 −0.769),B 细胞和 Plasma 这两个则会翻转——它们本来就是效应最小的两个,而且恰好是仅免疫算法下符号翻转的同两个部分。阴性层反过来,9 个部分里 5 个方向不稳定,只有 B、胆管、间质、Plasma 这 4 个稳定。
要注意区间宽度本身不是好消息。阳性层内皮的 ΔCLR 从 1.646 摆到 2.316,等于删掉一位供者能让效应量变动 0.67,这是一个 5 对 5 设计的正常杠杆水平,也正说明为什么效应量的点估计在这里不值得写进结论句。方向稳定是最低要求,不是充分条件。
伪计数不是一个中性的小数
硬零门禁背后的算术值得摊开写,因为”加个伪计数就行了”是这一步最常见的误解。我们用的伪计数是 0.5,CLR 的每一项是 log(n + 0.5)。当 n 足够大时这个偏移可以忽略:阳性层 cirrhotic1 的 B 细胞有 60 个,log(60.5) = 4.1026,与 log(60) = 4.0943 相差 0.008,对 ΔCLR 的量级(本文里普遍在 0.2 到 2.0 之间)毫无影响。
但同一个 0.5 在小计数处完全不是这个性质。阴性层 healthy1 的 B 细胞只有 1 个,log(1.5) − log(1) = 0.4055——伪计数本身贡献的位移就有 0.41,已经和我们报告的多数效应量同一量级。而当 n = 0 时,log(0.5) − log(0) 是无穷大:这时数值已经与观测无关,完全由伪计数虚构出来。我们在可估计性表里把这个量直接算出来(pseudocount_log_shift_at_worst),胆管细胞在阳性层的这一列是 inf,它被排除的机器可读依据就在这一格。
所以门禁的作用不是”避免 log(0) 报错”——加伪计数就不会报错了。门禁的作用是拦住那些数值虽然算得出来、但信息量为零的部分,并且拦在它们污染共享的几何中心之前。
精确置换检验做到了哪一步
本文所有的组间 P 值都是完全枚举,不是抽样近似。阳性层 5 对 5 枚举 C(10,5) = 252 种分配,阴性层 4 对 3 枚举 C(7,4) = 35 种,两者都小到可以穷尽,所以 P 值没有蒙特卡洛误差,重复运行给出逐位相同的结果。
需要留意的是最小可达 P 的分子。平衡设计取 2:把两组标签整体互换得到的分配也在枚举里,观测到的极端情形因此出现两次。不平衡设计取 1:4 对 3 的互补是 3 对 4,那是一个大小不同的划分,不在同一个枚举中,极端情形只出现一次。这两个数一旦搞错,阴性层的最小可达 P 会从 0.0286 被误算成 0.0571,进而把一个本来能达到 0.05 的设计误判成达不到——这正是我们在自查中发现并修掉的一处缺陷,它当时还被一条断言了错误答案的测试保护着。
配对设计走的是另一条路:n 对样本的符号翻转有 2^n 种,最小可达 P 是 2/2^n,因为整体取负总是合法的。三种情形写在同一个共享模块里,由本批三篇文章共用一份实现,避免每个脚本各推一遍。
平衡设计为什么救不了它
在设计冻结时我们讨论过一个替代方案:只保留两层都有的供者,做一个 7 供者的平衡设计。它被否决了,但否决的理由曾经是错的。
最初写的理由是”这个设计达不到 0.05”。这个说法不成立:一个平衡的 7 供者设计如果分成不同大小,最小可达 P 完全可以低于 0.05(例如 4 对 3 是 0.0286)。我们在复核时改掉了这条理由。
站得住的理由是两条与样本量无关的东西:一是两层的分选覆盖并不对齐,合并后仍然要处理两个不同的组成分母;二是分选纯度与分组共变,非免疫占比的组间差异精确 P = 0.0159。换多少位供者进来都不会改变第二条——混杂不是精度问题,加样本只会让被混杂的估计更精确地偏离。
标签自洽不等于标签被验证

细胞标注用的是 marker 打分,因此标注与后续任何以同一批 marker 定义的”程序”之间必然相关,这种相关不能算验证。我们的做法是把每个程序的打分基因和留出基因分开,并检查留出基因与打分基因、与标注 marker 的重叠都是 0。
四个程序在各自母区室内部的 Spearman ρ:瘢痕相关髓系 0.295(阳性层)/ 0.420(阴性层),纤维化间质 0.459 / 0.506,组织单核 0.315 / 0.237,瘢痕相关内皮 0.052 / −0.060。全细胞值普遍高于区室内值(例如内皮程序全细胞 0.392、区室内 0.052),差额来自谱系身份本身,是一个典型的循环相关陷阱。
即使区室内的值也只是描述性的:它们是细胞层面的相关,不是供者层面的结果,不能用来支持任何组间差异。瘢痕相关内皮程序在两层里都接近 0,这本身就说明这条线索在本次分析里没有得到支持。
另外,标注的模糊率我们如实报告:阳性层 1,544/37,306 = 4.14% 的细胞未能获得唯一标签,阴性层 1,578/24,904 = 6.34%。组成学的分母是已分配细胞,模糊细胞在那里被排除。
技术分区不是生物学重复
阴性层里有 3 位供者的文库被拆成了 A/B 两份。把它们当成 6 个独立样本会直接虚增自由度。我们把这三对做了区室份额的一致性检查:cirrhotic1 ρ = 0.600(P = 0.067)、healthy1 ρ = 0.358(P = 0.310)、healthy3 ρ = 0.188(P = 0.603)。
一致性并不高,也没有一对达到显著。这既说明它们不该被当成独立重复,也说明单个文库内部的份额估计本身带着相当的技术变异。分析中它们被合并到供者层面。
这份数据能写什么、不能写什么
可以写的:这是一份来自分选文库的数据,两层的分选纯度不同且与分组共变;组成学结论对参照集合的选择敏感;在预先定义的族边界下两层各自 0/8 和 0/9 通过 BH;零发现部分受离散 P 值分辨率限制。
不能写的:任何以 NK 或内皮的数值为基础的生物学陈述;任何跨两层的比较;任何把细胞份额当成组织内绝对细胞数量的表述——主语只能是”分选、消化、捕获、QC 和标签之后回收到的份额”。
还有三层本次完全没有做,必须一并披露,否则读者会高估这份分析的完成度:一是本项目没有做常规 QC 过滤,线粒体比例、双细胞、低质量细胞都未处理;二是没有做 ambient RNA 校正,也没有给出其影响的定量估计;三是细胞标注虽然在程序验证层用了不相交的留出基因,但标注本身仍来自 marker 打分,没有用外部参考数据集独立重做。这三层不补齐,这份工作只能作为方法学案例,不能作为一次完成的复现。
一半以上的产物是审计表,这是有意的
这次分析最终登记了 55 个产物文件,每个都带 SHA256,逐一记录在产物清单里;8 张图另有一份图—表对应清单,写明每张图由哪些表、哪个版本的表画出,这样”图和文字不一致”这类问题可以被机械地查出来,而不是靠人眼比对。唯一被显式排除在清单之外的是运行时长和峰值内存这类无法逐字节复现的度量,它们单独存放并注明了排除理由。
按类型数一下,55 个产物里超过一半是审计和披露表:纯度审计、可估计性、门槛阶梯、留一供者地板事件、标签模糊率、文库一致性、两种参照算法的逐部分对照、程序留出验证。承载”结果”的表只有少数几张。
这个比例值得说明,否则容易被理解成工作量的堆砌。它说明的是这份分析的产出主体:**每一条可能的结论都被查过,这些表就是查的过程和结果。**在一个头条结果被证明是分选杂质伪影的项目里,它们构成文章本身,不能降级成附录。
也正因如此,两个空表在这里是有信息量的:阳性层和阴性层的留一供者地板事件都是 0 行。空文件被登记进清单,和有内容的文件一样带哈希——“这项检查做了并且没有发现问题”与”这项检查没做”必须是两种可区分的状态。
要把它变成一次完整的复现,还差什么
如果要让这份数据支持生物学结论而不只是方法学结论,需要补的是三层前置工作,加更多统计没有用:
**一是常规 QC。**本项目对线粒体比例、双细胞和低质量细胞完全没有过滤。在一个已知混有分选杂质的数据集里,这一层缺失会直接影响标注:低质量细胞的 marker 打分本身就不可靠,它们被分到哪个部分带有随机性,而部分的份额正是我们要检验的量。
**二是 ambient RNA 的定量披露。**上面 PTPRC 在非免疫细胞里 2.6%–28.4% 的检出率已经提示了游离转录本的量级,但我们没有做校正,也没有给出”若校正会改变多少”的估计。没有这一层,任何以单个基因为依据的部分归属都留有疑问。
**三是用一份来源独立的参考重做标注。**当前标注来自 marker 打分,程序验证层用了与打分基因不相交的留出基因,这解决了循环相关,但没有解决标注本身的来源单一。用一份外部参考数据集独立标注一遍,再看两种标注下的组成结论是否一致,才是对”部分”这个定义的检验。
这三层里的任何一层都可能改变可估计集合,从而改变几何中心,从而改变每一个 ΔCLR。所以顺序不能颠倒:先补前置,再谈结论。在补齐之前把本文写成一次成功的复现,就是本文自己在批评的那种做法。
复现边界
这次复现能支持的,是两条分选文库的逐供者纯度实测、纯度与分组共变的检验结果、两种参照集合算法的逐部分对照,以及在各自族边界下阳性层 0/8、阴性层 0/9 通过 BH 这一事实。不能支持的是任何以 NK、内皮或其他部分数值为基础的生物学陈述,也不包括跨两层的比较。结论的主语只能是分选、消化、捕获与标签之后回收到的份额,不是组织内的绝对细胞数量。
三层未做的工作同属边界:没有常规 QC 过滤,没有 ambient RNA 校正及其定量估计,标注没有用外部参考数据集独立重做。阳性层的零发现有一部分来自离散 P 值的分辨率天花板,不能读成确认无变化。在这些边界之内,这份数据支持的是一个方法学判断,不是一条纤维化生态位的结论。
可复用的检查清单
如果你手上有分选或富集文库,下面五条值得直接抄走:
- 逐样本测量分选纯度,不要相信实验设计的标称。用与分选标记不同的谱系证据去测。
- 检验纯度是否与分组共变。如果共变,任何丰度随纯度走的部分都会显得差异,与生物学无关。
- 零膨胀门禁拦不住这种混杂。杂质是”太多”而不是”太少”,所有细胞数阈值都会放它过去。
- 把参照集合选择当成一个显式的敏感性维度,同时报告两种算法的结果,而不是选一个写进正文。
- 先算出这个设计的最小可达 P 和 BH 天花板,再决定要不要做这个比较。一个部分单独触底就无法通过 8 检验的 BH 校正——这是设计阶段就能知道的事。
这次复现留下的不是一条纤维化生态位的结论,是一个可以立刻用在别的项目上的判断:当参照集合的选择能让结论翻转时,先修参照,别先写结论。