主题
流水线架构总览
本页讲清楚
mr-pipeline的整体设计:模块怎么编排、数据怎么流动、配置怎么驱动、以及支撑一切的工程约定(错误隔离、断点续跑、内存安全)。想看具体某一步用了什么统计方法,见 方法引擎 各章。
一句话设计哲学
方法引擎与课题解耦:R/ 下的方法代码写死一次、经过验证后不再动;换暴露、换结局、换 FinnGen 版本,只改一个 config.yaml。这样既保证方法学的一致性与可复现,又让新课题的边际成本降到"改几行配置"。
目录与职责
mr-pipeline/
├── config.yaml 配置(唯一需要改的文件)
├── run_all.R 一键入口(编排三阶段)
└── R/
├── utils.R 日志 / IO / 断点续跑 / 错误隔离(无副作用,可单独 source)
├── 00_setup.R 环境与随机种子
├── 01_config.R 读取+校验配置、解析 cis 窗口、rsID 校验
├── 02_standardize.R 原始输入 → 内部标准 schema
├── adapters/ 读取适配层(按格式分发)
│ ├── read_dispatch.R 统一入口 read_gwas() + 列名自动探测
│ ├── read_tsv.R 扁平表(含流式预过滤,内存安全)
│ ├── read_instrument_table.R 预算工具表(UKB-PPP 式)
│ └── read_vcf.R GWAS-VCF(M3 stub)
├── 04_iv_select.R 工具变量选择
├── 05_harmonise.R 谐化 + 回文 + Steiger
├── 06_mr_core.R 自适应 MR 主分析
├── 07_sensitivity.R 敏感性与稳健性
├── 08_coloc_abf.R 两两共定位 coloc.abf
├── 09_hyprcoloc.R 多性状共定位 hyprcoloc
├── 10_multiple_testing.R FDR + 证据整合
├── 11_report.R 出图 + STROBE-MR HTML 报告
└── 12_bidirectional.R 反向 MR数据流:从原始文件到报告
run_all.R 把整个分析组织成三个阶段(源码 R/run_all.R):
Phase 1 · 逐暴露选工具,收集工具 SNP 并集
对每个暴露:read_gwas() 读入并标准化 → validate_rsid() 校验 → select_instruments() 选出工具变量(IV)。把所有暴露的工具 SNP 求并集 snp_union,供下一阶段预过滤结局。
Phase 2 · 结局按工具流式预过滤读取(内存安全)
结局 GWAS 动辄上千万行。这里不整读,而是:
rsid模式:按snp_union用grep -Fw只捞出工具 SNP 所在行;position模式:按chr:pos集合用awk过滤。
峰值内存只有几百 MB,3.6G 内存的机器也能跑全基因组文件。
Phase 3 · 逐暴露 hyprcoloc + 逐(暴露×结局)对做 MR
对每个暴露先跑一次多性状 hyprcoloc;再对每个结局:谐化 → MR 主分析 → 敏感性 → 两两 coloc.abf → (可选)双向 MR,把逐对结果写成标准化的 pair_summary。最后汇总所有对做 FDR 校正 与 MR×coloc 证据整合,并渲染 STROBE-MR HTML 报告。
config.yaml
│ load_config + 校验(01)
▼
[Phase1] 暴露 ──read_gwas(02+adapters)──▶ 标准 schema ──select_instruments(04)──▶ IV ──┐
│ 工具SNP并集
[Phase2] 结局 ──read_gwas(按并集流式预过滤)──▶ 标准 schema ◀───────────────────────────┘
│
[Phase3] 每对: build_harmonised(05) → run_mr(06) → run_sensitivity(07)
│ → coloc.abf(08) / hyprcoloc(09) → pair_summary
▼
汇总 → apply_fdr(10) → integrate_evidence(10) → render_report(11)
▼
results/mr_all_pairs_primary.csv + results/report/MR_report.html三条工程约定(贯穿所有模块)
这三点是流水线"跑得稳"的关键,都在 utils.R 里实现:
1. 错误隔离 —— safely()
每个易失败的外部调用(clumping、MR-PRESSO、coloc、出图…)都包在 safely() 里:出错时记日志、返回兜底值,不中断整条流水线。一个暴露-结局对失败,不会连累其余几十对。
2. 断点续跑 —— cached()
每一步的中间结果都以 .rds(+ .csv)落盘。config 里 project.resume: true 时,已算好的步骤直接读缓存;改一处重跑不会全部从头来。想强制重算就删掉对应中间目录,或设 resume: false。
3. 快速失败 + SNP 流水账 —— assert_that() / log_snp_flow()
配置或数据在系统边界就校验(build 一致、rsID 占比、必需列齐全),不满足立刻报错并说清缺什么。每一步过滤后剩多少 SNP 都记进日志(raw → significant → cis-window → clumped → F≥10),正好对应 STROBE-MR 要求的工具筛选流程图(item 10a)。
内部标准 schema
所有格式的输入,读进来后都归一到同一套列(read_dispatch.R: STD_COLS),对齐 GWAS-SSF 与 TwoSampleMR 习惯:
SNP, chr, pos, effect_allele, other_allele, eaf, beta, se, pval, samplesize, ncase, ncontrol下游所有方法只认这套 schema,不管原始文件是 FinnGen、UKB-PPP 还是 GWAS Catalog。这正是"适配层 + 标准 schema"解耦的地方 —— 详见 数据读取与标准化。
怎么用
见 使用教程(改 config、跑 run_all.R、读结果)。要理解引擎内部每一步的方法学,从 方法引擎总览 往下看。