第4章 · 4.2

4.2 scp 包与 QFeatures:可复现流程的骨架

The scp Package and QFeatures: A Backbone for Reproducible Analysis
摘要 一次单细胞蛋白组学分析产生一串有亲缘关系的中间层:肽段-谱图匹配、肽段、蛋白,层层过滤、聚合、归一化。本节剖析支撑这条链的软件设计——QFeatures 用一个容器同时容纳全部定量层与两类注释,并在层与层之间保留血缘;scp 包在其上把处理组织成函数式流水线;同一副骨架也贯穿 Galaxy 图形界面与 DIA 专用软件。复现由此从态度要求变成结构保证。

4.2.1 一串中间层:电子表格式的分析为何失败

4.1 节给出了定量矩阵的解剖——行是分子、列是细胞通道、层级自 PSM 而上。本节转向另一个问题:这串层级在分析过程中由谁管理。一次完整的处理远不止三张表:PSM 层先做质量过滤,聚合(aggregation)为肽段层;肽段层再做过滤、归一化与缺失值填补(imputation),聚合为蛋白层;蛋白层最后做批次校正(batch correction)与统计。PSM 层还要先按 run 拆分、再合并。一个"最终矩阵"的背后,是十几次中间变换——每一次都动了行、列或数值。

常见的做法是让每层单独成表:过滤脚本输出 pep.csv,电子表格里手工核对、删几行,另存为 pep_改.csv,再交给聚合脚本。这条路走得通,却有三个结构性的失败模式。其一,中间层丢失:每一步覆盖上一步的产物,分析结束时只剩最终矩阵;想核对某个蛋白在肽段层的证据,旧文件已经不在了。其二,参数不可追溯:阈值写在脚本注释里、表格的筛选条件里,甚至只存在于操作者当天的记忆里;论文所写的"1% FDR"究竟是哪一步、作用在哪一层,无从对证。其三,不可复现(reproducibility)——同一批数据与同一段代码,换个人、换台机器理应得到同一结果,如今却做不到;审稿人要求补一张图,只能从头再做一遍,而"再做一遍"又会产生一套新的中间文件。

单细胞数据把这套隐患进一步放大。一次分析动辄数十个 run、成百上千个细胞通道,缺失值占比高,批次结构与多重标记交织在一起;表格行数以万计,"手工核对"从两小时变成两周,出错的机会随之上升。规模本身就否定了文件接力的做法——不是做得更仔细一些就能救回来。

这三个失败模式与细心与否无关。把有亲缘关系的数据拆散在一堆文件与脚本变量里,数据之间的关系本身就没有任何载体;关系没有载体,丢失与错位只是时间问题。要消除它们,靠的不是更强的自律,而是换一种组织方式——这正是 QFeatures 与 scp 包要解决的问题。

警示

手工处理不可复现。电子表格里的排序、删行、复制粘贴不留任何痕迹;单细胞数据矩阵大、缺失值多,手工操作最容易在"行列对齐"上出错——行列一旦错位并不报错,只会让结论悄悄变形。凡是没写进代码的操作,都等于没有发生过。

电子表格式分析与对象流水线的对比:三个失败模式与对应的结构保障 电子表格与脚本接力:三个失败模式 定量表 evidences.txt 肽段表 pep.csv 手工修改版 pep_改.csv 蛋白表 prot.csv 再改一版 prot_v2.csv 脚本 A 过滤 Excel 手工删行 脚本 B 聚合 改名另存 版本增殖 ① 中间层丢失:想核对某蛋白的肽段证据,旧文件已被覆盖 ② 参数不可追溯:阈值散落在脚本、表格批注与操作者的记忆里 ③ 不可复现:换人重跑数字对不上,补一张图须从头再来 对象与函数链:同一副骨架的结构化组织 定量表 evidences 通道注释表 readSCP QFeatures 对象 PSM 层 ×4(每 run 一层) 肽段层 peptides 蛋白层 proteins colData:64 个细胞通道 处理函数:接受对象 → 返回对象 filterFeatures(过滤) aggregateFeatures(聚合) logTransform / impute ComBat(批次校正) 参数即代码;新层追加,旧层保留 ① 全部中间层共存于一个对象,任何一层随时可查 ② 处理历史即代码:参数改一处,整链重跑即重现 ③ 任何一行可沿血缘回溯到上一层的来源行
图 4.2-1 电子表格式分析与对象流水线的组织方式对比。上:文件接力——每步覆盖上一步的产物、参数散落各处、手工步骤不留记录,三个失败模式彼此助长。下:QFeatures 容器把全部层与注释收进同一对象,处理函数接受对象、返回对象,参数留在代码里、血缘留在对象中,与上方三个失败模式逐一对应(流程环节据 Grégoire et al., 2024;Gomoryova and Hecht, 2025;作者整理)。

4.2.2 QFeatures 的数据模型:一个容器装下全部层

QFeatures 是 Bioconductor 上为"多层定量"设计的容器,出自 UCLouvain 的 Gatto 与 Vanderaa 之手,也是 scp 包的基础设施。核心想法一句话:与其让每一层单独成表,不如让全部层住进同一个对象。对象里装三类成分。

第一类是(assay):每层是一张定量矩阵,行是分子、列是细胞通道。PSM 可按 run 各占一层,肽段与蛋白各一层。关键在于:派生新层时旧层不删除——过滤前的 PSM 层与过滤后的并存,聚合前的肽段层与聚合后的并存。对象越处理越"厚",任何一步都拿得出来。

第二类是行注释(rowData):每层自带一张行注释表,描述该层的每一行——PSM 层放谱图得分、电荷、样品/载体信号比;肽段层放序列与蛋白归属;蛋白层放特有肽段数。注释随层演化:聚合造出新行,就要配出配套的新注释行。第三类是列注释(colData):全对象共享一张列注释表,每个细胞通道一行——所属 run、通道号、SampleType(载体、空白还是单细胞)、细胞类型、批次。列是所有层公共的坐标,注释自然也只有一份。

把层与层连接起来的,是层间血缘(assay links)。从某层派生新层时,容器记下"新层第 i 行由父层哪些行而来"。于是任何一个蛋白都可以顺藤摸瓜:蛋白层的这一行,来自肽段层的那三行,再往上追溯到 PSM 层的十来行及其谱图得分。定量数字不再悬空,而是带着完整的来历。4.4 讨论缺失值、4.6 讨论批次效应时,反复用到的正是这种回溯能力——"这个值是怎么来的"可以一路查到证据层。

定义

层与血缘(assay and assay links):层是容器中的一张定量矩阵及其配套行注释,一个对象可容纳多层,新层由处理函数派生、旧层保留;血缘是派生时记录的"子层每一行 ↔ 父层来源行"映射。两者合起来,把"分析是一串变换"这一事实写进了数据结构本身。

QFeatures 容器:多层 assays、每层 rowData、共享 colData 与层间血缘 QFeatures 容器 示意数据:4 run × 16 通道 = 64 列 层 1–4 PSM(每个 run 一层) run1 400×16 run2 500×16 run3 300×16 run4 200×16 rowData(行注释) 得分·电荷·SCR aggregateFeatures:PSM → 肽段 层 5 肽段 peptides 定量矩阵 200 行 × 64 列 rowData(行注释) 序列·蛋白归属 aggregateFeatures:肽段 → 蛋白 层 6 蛋白 proteins 定量矩阵 50 行 × 64 列 rowData(行注释) 肽段计数等 血缘(assay links):子层每一行 ↔ 其父层来源行 colData(列注释) 全对象共享 Raw.file(run) Channel 通道 SampleType 细胞类型 批次 batch 列对齐 64 行 = 4 run × 16 通道 所有层共享同一组列 每层各带一份行注释 PSM 层的行 得分、电荷、SCR… 肽段层的行 序列、修饰、蛋白归属 蛋白层的行 特有肽段数、分组 定量层(assay) 注释表(rowData / colData) 函数派生新层 血缘(assay links) 行数与列数为示意整数;列(细胞通道)在所有层之间对齐。
图 4.2-2 QFeatures 容器的结构。左:全对象共享的列注释(colData),每个细胞通道一行,所有层沿同一组列对齐;中:各定量层(assay)——PSM 按 run 分层,肽段与蛋白由聚合派生,新层追加而旧层保留,每层自带行注释(rowData);层间箭头是处理函数,底部虚线框记录血缘(assay links),子层每一行都可回溯到父层的来源行。行数与列数为示意(据 Vanderaa and Gatto,scp 包文档;Grégoire et al., 2024;作者整理)。

这套"容器+血缘"的设计是全书数据处理的心智模型。此后每一节介绍的处理步骤,都可以用同一组问题去读:作用在哪一层?删了行、换了值,还是造了新层?行注释与列注释如何随之更新?血缘是否保持完整?4.3 的标准化流程将逐条回答这些问题;本节先把骨架立起来。

列注释只此一份,还有一层用意:按细胞做任何筛选——剔除中位数 CV 过高的细胞、删除空白通道——都在对象层面一次完成、全层同步。列是所有层的公共坐标,动列必须全层一起动;这正对应习题 4.2-2 中"按细胞过滤"那一步的机理。

习题 4.2-1

某示意数据集含 4 个 run,readSCP 为每个 run 建一个 PSM 层,行数依次为 400、500、300、200,每层 16 列(通道)。(a)写出对象初始状态:层数、各层形状、colData 行数。(b)质量过滤保留一半行后,各层形状如何变化?层数呢?(c)各 run 的 PSM 聚合为肽段层(依次得 100、125、75、50 行)后,对象共有几层?(d)把四个肽段层合并为一个名为 peptides 的层,若并集共 200 行,该层形状与对象总层数各是多少?这一层为何天然带有缺失值?(e)再聚合出 50 行的蛋白层后,蛋白层形状与对象总层数各是多少?

参考解答

(a)4 层,形状依次为 400×16、500×16、300×16、200×16;colData 共 64 行(4 run × 16 通道)。(b)过滤删行不动列:200×16、250×16、150×16、100×16,仍为 4 层。(c)旧层保留,新增 4 个肽段层,共 8 层。(d)合并层的行数取四层肽段的并集,列取全部通道的并集,故 peptides 层为 200×64;对象共 9 层。某肽段若只在 run1 检出,合并后它在其余 48 列均为缺失——合并把"该层没有这一行"翻译成"这一行在某些列没有值"。(e)蛋白层 50×64,对象共 10 层。层数随处理递增,正是"新层追加、旧层保留"的直接后果。

4.2.3 scp:把处理写成函数链

QFeatures 管数据,scp 包管步骤。scp 由 UCLouvain 团队开发,在 QFeatures 之上补齐单细胞专用环节,并把整套处理组织成标准化流程(Grégoire et al., 2024)。入口是一个函数:readSCP 读入两张表——定量表(如 MaxQuant 输出的 evidences.txt)与通道注释表——按 run 拆层,一步得到装好注释的对象。Galaxy 教程所用的 SCoPE2 子集即由 1,362 行 × 150 列的定量表与 65 行 × 7 列的注释表起步,readSCP 之后直接进入处理链(Gomoryova and Hecht, 2025)。

处理函数遵守同一约定:接受对象、返回对象。过滤按行注释删行;聚合把一层归并为新层;归一化与填补在层内换值;批次校正整层重写。无论哪种操作,进出都是同一个容器,行注释、列注释与血缘自动随行。于是整条处理可以写成一条函数式流水线(functional pipeline)

scp1 <- readSCP(assayData = evidences,      # 定量表(PSM × 通道)
               colData = sampleAnnotation, # 通道注释(细胞、批次)
               runCol = "Raw.file")        # 按 run 拆分建层
scp1 <- filterFeatures(scp1, ~ Reverse != "+")     # PSM 层:删行
scp1 <- aggregateFeatures(scp1, i = 1:4, fcol = "peptide",
                          name = "peptides",       # PSM → 肽段(新层)
                          fun = matrixStats::colMedians)
scp1 <- logTransform(scp1, i = "peptides", base = 2)  # 派生 log2 层

上例中,readSCP 按 run 建层;filterFeatures 在 PSM 层按行注释设门槛(此处以剔除反向序列命中为例);aggregateFeatures 把各 run 的 PSM 按肽段归并,生成名为 peptides 的新层,四个旧层原样保留;logTransform 再派生出对数层,与父层一一对应。代码为示意,各步参数、过滤指标与完整流程见 4.3。

链条上每挂一个函数,都应顺手核对两件事:对象的层数与各层形状是否符合预期,行注释与列注释是否随操作同步。把这两项检查写进脚本,异常会在当场暴露,而不是在结论里潜伏。

注记

函数链即分析档案。链条自上而下就是处理历史;参数改一处、整链重跑,新旧结果可逐层对照——旧层都在,对照不需要重建任何中间文件。Galaxy 把同一逻辑搬进图形界面:每步一个工具、参数自动存档,"历史"就是这份档案的界面化版本(Gomoryova and Hecht, 2025)。

习题 4.2-2

4.3 节将按 Galaxy 教程的数据走完如下处理链(Gomoryova and Hecht, 2025):(1)PSM 层质量过滤(PIF ≥ 0.8、每 run 至少 150 个 PSM、平均 SCR ≤ 0.1、FDR 1%);(2)PSM 聚合为肽段;(3)按每细胞中位数变异系数(CV ≤ 0.65)过滤细胞;(4)肽段层双重归一化(列中位数、行均值);(5)log2 变换;(6)剔除缺失比例过高的肽段;(7)kNN(k = 3)填补;(8)ComBat 批次校正。对每一步回答:作用在哪一层?属于"删行、删列、换值、造新层"中的哪一类?血缘是否需要更新?

参考解答

(1)PSM 层,删行;血缘随行收缩,无需重建。(2)造新层(aggregateFeatures),并为每条肽段行建立指向若干 PSM 行的新血缘。(3)特殊一步:按细胞过滤是删列。CV 在肽段层算出、写入列注释,再据其删去整列,所有层同时失去该列。(4)肽段层换值,行列不变,常派生归一化新层,血缘与父层一一对应。(5)造新层(logTransform),一一对应。(6)删行(如 filterNA)。(7)换值或造新层(impute):缺失位置填入估计值,行列不变。(8)蛋白层换值:按列注释中的批次字段整层重写。八步只含四种动作——删行、删列、换值、造新层;删行删列不动血缘结构,造新层必须建立血缘。这组问题也就是阅读任何处理软件时应提的问题。

4.2.4 复现的载体:SCP.replication 与 scplainer

软件骨架的价值要用硬标准检验:能否用同一套代码,把一篇已发表论文的全部结论原样重演。SCP.replication 项目(UCLouvain 团队)为此而设:以 scp 重写已发表的单细胞蛋白组学分析并公开全部代码,SCoPE2(Specht et al., 2021)即其中之一。重演暴露出两个高频难点——批次校正与缺失值处理:原论文对这两步的描述往往不足以恢复数字,重演者只能做有依据的选择,并把每处选择写明(Vanderaa and Gatto, 2021)。

案例

SCP.replication 重演 SCoPE2。SCoPE2 原始分析以 10 天机时定量 1,490 个单核/巨噬细胞的 3,042 种蛋白(Specht et al., 2021)。重演不是抄结果,而是把论文的每一步在代码里落实;落实不了的地方,恰好是方法报告不完整的地方。这次复盘连同后续工作,推动了社区报告规范(Gatto et al., 2023)与 scp 标准化流程的成形(Grégoire et al., 2024)——复现的障碍最终变成了写作规范与软件功能的改进清单。

"论文结论附代码与数据"由此改变领域风气(呼应 2.3):结果不再是黑箱数字,后人可以在同一数据上换参数、换方法重新计算,方法之间的比较第一次有了共同地基——比较发生在同一数据、同一副骨架上,而非各说各话。下游建模也被纳入同一套对象:scplainer 以线性模型对处理完成的蛋白层做差异丰度(differential abundance)分析,细胞类型、批次与载体效应作为协变量放进同一个模型(Vanderaa and Gatto, 2025)。本节点到为止,建模细节见其原文。

代码之外还要有数据。配套的 scpdata 包把 SCoPE2 等已发表数据集整理成统一格式,可直接读入对象,"论文、代码、数据"三件套在同一个入口汇合(Vanderaa and Gatto,scp 包文档)。重演的门槛由此从"向作者逐一索要文件"降为"下载并运行"。

4.2.5 三个入口,一副骨架

同一副骨架有三个常见入口。其一是 R/Bioconductor:代码入口,控制最完全,门槛也最高,需要 R 基础与对每步机理的理解。其二是 Galaxy:图形界面入口,把同一套 scp 流程封装成网页工具,每步是一个表单,无需编程即可走完标准化流程;参数与数据自动存入"历史",复现要求同样满足(Gomoryova and Hecht, 2025)。其三是 DIA 侧的专用软件:DIA-NN 等把检索与定量一体完成,输出可直接进入下游统计,plexDIA 流程即由其承担(Derks et al., 2023)。

表 4.2-1三类分析入口的对比:形态与门槛不同,"层—血缘—流程"的骨架一致
入口形态上手门槛复现载体适合情形
R / Bioconductor(scp)代码(函数链)高:需 R 基础脚本与对象,参数全在代码方法学开发、需要完全控制
Galaxy(scp 工具集)网页图形界面低:无需编程历史自动存档每步参数标准流程的常规分析
DIA-NN 等专用软件命令行 / 图形软件配置文件与输出报告DIA 数据的检索与定量

工具不同,骨架相同。Galaxy 的"工具"对应函数,"历史"对应代码档案;DIA-NN 的输出报告对应行注释;层与血缘的读法在三个入口下都能对上。读一个新工具时先问它作用在哪一层、动了行列还是换了数值,比记住按钮的位置有用得多。信息学流程组合的比较也依此组织——基准评测评的是流程,不是单个软件(Wang et al., 2025)。

入口的选择因此是务实问题而非立场问题:常规分析走 Galaxy,最快得到可复现的结果;方法学比较回到 R,链条的每个环节都可改写;DIA 数据先经专用软件完成检索与定量,再接续同一套下游骨架。三个入口产出的矩阵,读法完全一致。

4.2.6 何时偏离标准流程

什么时候该自己写代码?默认答案:不该。标准流程经过多数据集的复用与检验,参数有出处、行为有文档(Grégoire et al., 2024);自己写下的每一步,都是一处需要自行验证、自行报告、自行维护的孤岛。偏离的正当理由大致三类:数据形态是标准流程不支持的(新型标记或采集方式);工作本身就是方法学研究(比较与基准评测);文献已明确某一步在此情形不适用。如果只是想换个阈值——那不是写代码的理由,是改参数。

这也是社区白皮书的立场:完整报告每一步的方法与参数,性能声明要有基准支撑(Gatto et al., 2023)。复现由结构保证——参数留在代码里、层留在容器里、血缘留在对象里;写作时如实交代偏离及其理由,读者才能判断结论的稳健程度。判断力不在于会写多少代码,而在于能说清每一步为什么这样走。

反过来,标准流程也不是护身符。参数照抄而不问数据是否满足其假设——填补之前缺失是否过于集中、批次结构是否可辨识——同样会得到"可复现的错误结果"。骨架保证的是过程可查,不是结论必然成立;结论仍要靠 4.3 至 4.6 的机理判断逐节支撑。

习题 4.2-3

同事想在归一化与填补之间插一步自定义过滤:把肽段层导出为 data.frame,手工删去若干行,再写回对象。指出至少两处风险,并给出不破坏骨架的替代做法。

参考解答

其一,对齐风险:导出—写回绕过了容器,若行序有变,定量矩阵与行注释、血缘即刻错位;错位不会报错,只会让结论悄悄变形。其二,档案断裂:这一步不留任何参数记录,函数链到此中断,整条分析不再可复现。替代做法:把过滤条件写成"接受对象、返回对象"的函数(或直接用 filterFeatures 表达),在容器内删行——行注释与血缘同步收缩,参数留在代码里,链条保持完整。


本节立起了贯穿第 4 章的软件骨架:

  • 一次分析 = 一个容器 + 一串函数:层(assay)、行注释(rowData)、列注释(colData)、层间血缘(assay links)四件套装进同一个对象;
  • 复现由结构保证:参数在代码里、层在容器里、血缘在对象里,重跑即重现,回溯有据可查;
  • 入口不同、骨架相同:R/Bioconductor、Galaxy、DIA 专用软件可按同一张地图阅读;
  • 偏离标准流程的三类正当理由:数据形态不支持、方法学研究、文献依据。
  • 默认走标准流程;偏离须说出理由,并把理由写进报告。

4.3 节将沿着这副骨架,走完从 PSM 过滤到批次校正的完整标准化流程。

关键术语

(assay)
QFeatures 容器中的一张定量矩阵及其行注释,一个对象可容纳多层。
行注释 (rowData)
描述某一层各行的表格(得分、序列、蛋白归属等),随层演化。
列注释 (colData)
全对象共享的列注释表,每个细胞通道一行(run、通道、类型、批次)。
层间血缘 (assay links)
派生层记录的"子行来自哪些父行"的映射,支撑逐步回溯。
复现 (reproducibility)
同一数据与代码在任何环境重跑都得到同一结果。
函数式流水线 (functional pipeline)
处理函数接受对象、返回对象串成的链,链条即分析档案。
聚合 (aggregation)
把 PSM 归并为肽段、肽段归并为蛋白并生成新层的操作。
差异丰度 (differential abundance)
蛋白层面比较丰度高低的统计任务,scplainer 以线性模型实现。

参考文献与延伸阅读

  1. Vanderaa C, Gatto L. 2021. Replication of single-cell proteomics data reveals important computational challenges. Expert Review of Proteomics 18(10): 835–843.
  2. Grégoire S, Vanderaa C, Gatto L. 2024. Standardized workflow for mass-spectrometry-based single-cell proteomics data processing and analysis using the scp package. Methods in Molecular Biology 2817: 177–.(arXiv:2310.13598)
  3. Vanderaa C, Gatto L. scp 包文档(Bioconductor,UCLouvain). uclouvain-cbio.github.io/scp/.
  4. Vanderaa C, Gatto L. 2025. scplainer: using linear models to understand mass spectrometry-based single-cell proteomics data. Genome Biology 26: 237.
  5. Gomoryova K, Hecht H. 2025. Single cell proteomics data analysis with bioconductor-scp. Galaxy Training, training.galaxyproject.org.
  6. Specht H, Emmott E, Petelski AA, Huffman RG, Perlman DH, Koller A, Slavov N. 2021. Single-cell proteomic and transcriptomic analysis of macrophage heterogeneity using SCoPE2. Genome Biology 22: 50.
  7. Gatto L, Aebersold R, Slavov N, et al. 2023. Initial recommendations for performing, benchmarking and reporting single-cell proteomics experiments. Nature Methods 20: 375–386.
  8. Derks J, Derks J, Leduc A, Masselon C, et al. 2023. Increasing the throughput of sensitive proteomics by plexDIA. Nature Biotechnology.
  9. Wang J, Huang Y, Fang Q. 2025. Benchmarking informatics workflows for data-independent acquisition single-cell proteomics. Nature Communications 16.