Skip to content

自建 skill 使用指南:cis-pQTL 药靶 MR 四道关卡

这一页解决的问题:本课题 2026-07 → 2026-08 犯过五类错,其中最严重的一类 (T1D 等位频率整列反转)存活了 7 天并通过了当时全部审计。 原因是所有检查都在拿流水线和它自己比。这个 skill 把「和外部参照物比」固化成四道关卡。

相关:判定标准与 skill 合规打分谐化与定向过滤


一、它是什么,不是什么

:一层质控外壳。四道关卡,每道都拿分析之外的东西做参照——参考面板、教科书位点、已发表阈值、证据阶梯。

不是:分析流水线。它不跑 MR,也不跑共定位

为什么没有 03_04_ 脚本

这是故意的。第 3 步(MR 估计)和第 4 步(共定位)在父 skill bio-causal-genomics-proteome-mr-drug-targetexamples/cis_pqtl_mr.R 里已经实现了, 本 skill 只补父 skill 没有的东西。编号保留空档,是为了让这个缺口看得见而不是让人困惑。

不适用于:多效性/trans MR、非蛋白暴露、观察性蛋白组学。

核心命题

一条 cis-pQTL 流水线可以内部完全自洽,同时外部完全错误。

符号错误、表型标错、结论夸大,这三类问题都不会改变 p 值、置信区间或任何一张图。 所以任何"拿流水线和自己比"的检查——单元测试、回归测试、内部一致性审计——都测不出来。


二、四道关卡

关卡问的问题脚本不过怎么办
0 定题你需要什么级别的结论,这批数据够得着吗?00_scope_gate.R降目标,或换问题
0.5 角色每个分析被允许对候选做什么00b_analysis_roles.R先改角色,再开跑
1 可行性这批数据根本能不能回答问题——以及回答的是哪个问题?01_feasibility_gate.R换问题
2 输入 QC文件里装的是不是它声称的东西?02_input_qc.R停下,修数据
3 三角验证是这个蛋白吗?方向对吗?代价是什么?05_triangulate.R降级,别删
4 证据分层这个结果允许说到什么程度?06_score_evidence.R改措辞

子项(加粗为新增):

  • Gate 0:0.1 一句话问题 · 0.2 阴性也成立 · 0.3 新颖性 · 0.4 资产反推
  • Gate 0.5:0.5a 角色 · 0.5b 筛选顺序 · 0.5c 范畴错误 · 0.5d 不许删记录 · 0.5e 安全性不是筛选器 · 0.5f 规则出处 · 0.5g 留痕
  • Gate 1:1.1 panel · 1.2 功效 · 1.3 样本重叠 · 1.4 发生 vs 进展
  • Gate 2:2.1 列映射 · 2.2 EAF ★ · 2.3 p·beta·se · 2.4 哨兵位点 · 2.5 基因组版本
  • Gate 3:3.1 PAV · 3.2 邻居 · 3.3 跨平台 · 3.4 L2G · 3.5 反向因果 · 3.6 on-target pheWAS

二之一、决策流程图

关卡不是流程旁边的检查清单,而是流程里面的岔路口。 图上每一条往回走的箭头都是真实结局,不是异常分支。

全图只有两条箭头是真正要紧的

REACH → LOWERCMP -.→ WRITE。 两者在研究的一头一尾说的是同一件事结论的级别由数据决定, 你唯一能选的,是在第一周知道,还是在第三个月知道。

文献比对(Burgess 2023 §4 + STROBE-MR,逐条记录偏离)夹在 Gate 0 与 Gate 1 之间。

二之二、★ 最终思路:串联筛选 + 并联表征

先看文献怎么做的

Yao 等,Biomolecules 2024;14:355 (骨关节炎,SomaScan 4,907 蛋白)是我找到的写得最清楚的一份流程:

4,907 蛋白 → MR + FDR → 12 个
  → Steiger(紧跟 MR)→ Cochran Q / Egger 截距 → SMR(10/12 有 eQTL)
  → 共定位 PP.H4 ≥ 0.8 → phenotype scanning → PheWAS(只对 3 个核心靶点)

两句是决定性的:

原文级要点

  • 共定位 "not used to exclude candidates"(不用来排除候选)
  • PheWAS 明确是 "to investigate whether side effects existed"——用于描述,不用于排除
  • 12 个全部进入结果表,没有一个因安全性被剔除

结论:串联,但"筛选"改的是层级,不是删除记录。

★ 正文写漏斗,不写分级标签

一处已订正的错误

我最初说"分级(Tier)是本领域常规做法",那是错的。当时用 "tier 1" "tier 2" 当关键词搜, 必然只返回有分级的论文——拿它证明"分级普遍"是循环论证。

中性关键词重搜后,实际情况是绝大多数论文用漏斗,不用分级

研究报告方式
同济 C1R 共病(同 UKB-PPP 54,219,与我们同构1,954 → 224 → 40 → 5,重点讲 4 个蛋白;全文 tier 零命中
腹主动脉瘤34 个关联 → 共定位突出 2 个
NAFLD1,834 cis-pQTL → 4 过 FDR → 2 个共定位支持
冠心病(pQTL 臂)39 过 MR → 24 共定位

而且用分级的那几篇,每篇定义都不一样、且都明说是作者自定义、不引用既有标准

所以:正文按漏斗写(57 对/31 蛋白 → 15 对/12 蛋白 → 3 个),A/B/C/D 全表放补充材料。

这同时解决了两套分级打架的问题——正文不出现 A/B/C/D,就不会和 T0–T4 混淆。 T0–T4 管的是「这篇论文能声称到什么程度」,不是「哪个蛋白更好」,它是内部写作约束,不进正文。

「不删记录」不受影响

正文报漏斗 ≠ 分析过程中丢掉行。分析时一条都不能删—— 删了会毁掉分母,还会藏起方法分歧(ACRBP/LACTB2/NUDT5/PAM/SIGLEC5 通过 coloc.abf 却没过 HyPrColoc 这件事,只因两套结果都留着才看得见)。

★ MHC 什么时候要考虑——查高分文献后订正

我原先把 MHC 画成筛选链的第三道,那是错的;但把它降成"注释"也不够—— 它其实是方法失效边界

决定性依据:Nature Communications 2024

Dhalla 等,The influence of HLA genetic variation on plasma protein expression (UKB 45,330 欧洲人 × 2,940 蛋白)原文两句:

"standard fine-mapping and colocalization methods optimized for bi-allelic SNPs … are not suitable for analysis in the MHC region"

"further benchmarking and developments in statistical methodology are warranted to perform formal fine mapping, colocalization, and Mendelian randomization analyses with HLA genetic variants"

不是"结果要谨慎解读",是方法在这个区域本身就不适用,而且一次点了 fine-mapping、共定位、MR 三样。

五个必须考虑 MHC 的场合

场合怎么处理依据
trans 工具排除 chr6:25–34Mb质控原文:"for trans-pQTLs, variants in the extended MHC region"
蛋白编码在 MHC 内,用 cis 工具不能排除,但下游统计推断标注为不适用排除变异=这些蛋白直接没有工具;而标准共定位/MR 在此区不适用
结局是免疫相关疾病MHC 是 trans 多效性重灾区504 个蛋白受 HLA 变异影响,478/504(94.8%)是 trans;>80% 的 HLA-pQTL 落在肽结合槽,机制=抗原呈递
共定位 / fine-mappingMHC 区结果不作为证据方法不适用(同上);且 MHC 区 eQTL 跨度中位 2.1 Mb,远超 ±500 kb 标准 cis 窗
通路富集 / 跨疾病模式必须分组跑本课题实测(见下)

★ 坐标要写清楚:该文用 hg19 chr6:28–34Mb;trans 排除常用的扩展区是 25–34Mb

对我们的直接含义:一票否决是对的,但理由要换

  • 原来的理由「LD 混杂风险」太软,像个操作定义
  • 真正的理由是:标准共定位方法在 MHC 区不适用,所以「共定位支持」这个判据对 MHC 蛋白 根本给不出有效结果——它们进不了 A/B 是方法学后果,不是我们从严
  • ★实测印证:11 个 MHC 蛋白的 coloc_support 全部 FALSE,与"方法在此区失效"完全一致

而它作为分组轴的价值,是本课题最硬的发现之一

  • 全部 31 个蛋白一起跑富集 → 头号结果 immune response p=7.2e-07
  • 只跑非 MHC 的 20 个 → 免疫信号完全消失(最好才 p=0.047),变成脂蛋白颗粒
  • 把 31 撑成 57 对的那 8 个蛋白里,6 个在 MHC

「免疫机制驱动并发症」完全由 MHC 那块撑着。不分组跑就会写出由 LD 造成的假机制。

★ 与我们同构的 C1R 研究(同 UKB-PPP 54,219)全文 1,683 行完全不提 MHC (MHC/HLA/chromosome 6/chr6 零命中,本地 PDF 提取实测)。 这不是它的错——只是它没做这一层检查;我们做了,而且查出了东西。

三类角色——这是全部问题的根子

这些分析根本不是同一种东西,它们被允许做的事不同:

角色作用单位能改层级吗能删记录吗谁属于这一类
筛选 screen蛋白 × 疾病✅ 它决定层级MR 显著性、Steiger、共定位、疾病特异性、方向一致性
方法边界基因组区域❌ 但使某些判据失效MHC 区——标准 fine-mapping / 共定位 / MR 在此不适用;用作分组轴
表征 characterise单个存活候选✅ 只能降级跨平台、PAV、邻居基因、反向 MR、on-target PheWAS、单细胞定位
验收 acceptance性状 × 性状完全不能LDSC 遗传相关、通路富集
  • 筛选是有序串联:每一道看到的是上一道剩下的,所以每道必须写 stage
  • 表征是并联:它们彼此不依赖,谁先谁后无所谓
  • 验收既不筛也不表征:它验的是数据和研究本身

0.5c 范畴错误:LDSC 不在筛选链上

LDSC 算的是两个性状之间的遗传相关。它能回答"这两个性状共享遗传结构吗", 永远回答不了"这个蛋白该不该留下"

本课题里它的真实用途是验收:rg(T1D,T2D) 从 0.886 → 0.087, 证明换的新 T1D 数据源测的确实是 T1D。

把它塞进候选筛选链,是拿性状层的工具去筛蛋白层的对象——这是范畴错误,不是严格与否的选择

0.5d 不许删记录,只许降级

删记录会毁掉流程图的分母,还会藏起方法之间的分歧

实测案例:ACRBP / LACTB2 / NUDT5 / PAM / SIGLEC5 这 5 个蛋白 通过了 coloc.abf,却没通过 HyPrColoc——这件事之所以可见, 正是因为两套结果都留着。删了就永远看不见。

★ 单细胞要分成两种,它们角色不同

是什么角色
sc-TWAS / sc-eQTL MR细胞类型特异的 cis-eQTL 当工具做 MR + 共定位因果证据——可以当筛选器,也可以降级
scRNA-seq 表达定位图谱,看基因在哪类细胞高表达描述性——不许改层级

在疾病相关细胞里高表达是机制叙事,不是因果证据。配置里必须声明你指的是哪一种。

回到你的两个思路

思路 1 对,思路 2 不行。 但你写的思路 1 里有一处要改:LDSC 不属于筛选链

思路 2(全并联)有两个硬伤:① 1,954 个蛋白全做单细胞不现实; ② 下游给出矛盾结果时没有预设优先级就无法裁决——而矛盾是实际发生过的 (ERMAP 视网膜方向与血浆相反、IFNAR1 视网膜层全阴性、APOL1 的 mRNA 站 SomaScan 反 Olink)。 这正是"混乱"的来源。


三、安装

bash
cp -r F:/project/skills-dev/running-cis-pqtl-drug-target-mr ~/.claude/skills/

装完必须三个 skill 并存(本 skill 只做编排,不重复父 skill 的内容):

~/.claude/skills/running-cis-pqtl-drug-target-mr/
~/.claude/skills/bio-causal-genomics-mendelian-randomization/
~/.claude/skills/bio-causal-genomics-proteome-mr-drug-target/

依赖

需要用在哪缺了会怎样
R ≥ 4.2 + data.tableyaml全部脚本硬依赖,跑不了
PLINK 1.9 + 同祖先 LD 参考面板Gate 2.2 频率仲裁、Gate 3.2 LDGate 2.2 降级为警告
jsonlite + PATH 上的 curlGate 3.4(Open Targets)该项跳过,其余照跑
Graphviz dot渲染流程图仍会写出 .dot 文件

LD 面板不是可选项

Gate 2.2 是这个 skill 存在的唯一理由。没有 LD 面板它只会给个警告, skill 的大部分价值随之消失。


四、七步跑法

第 1 步:写出一句话,然后跑 Gate 0

在【某人群】中,遗传预测的【某蛋白】水平是否影响【某结局】,方向是什么?

四个要素缺一不可。少了任何一个,你手里的还是选题("我想做糖尿病并发症"), 不是研究问题——选题没法拿去和任何东西核对。

然后,在下载任何数据之前

bash
Rscript scripts/00_scope_gate.R study.yml

★ 核心思路:把证据阶梯倒过来读

证据阶梯平时是正着读的,在终点告诉你"这个结果允许说到什么程度"。 开题时倒过来读,它就是一张采购清单

想达到就必须已经
T0暴露 cis-pQTL 统计量;结局统计量
T1+ 结局的全区域统计量(共定位要的是区域,不是 lead SNP);祖先匹配 LD 面板
T2+ 该蛋白在第二个检测平台上的数据
T3+ 第二平台要达到显著(不是方向一致就行);VEP 注释;邻居基因 cis 信号;反向 MR 的工具pheWAS 资源
T4+ 独立队列且重新选过工具

脚本算出可达上限,低于目标时点名缺哪一样。然后只有两个诚实的选项: 去把它搞到手,或者现在就把 target_tier 降到上限,从一开始就按那个层级写。

拿本课题真实开局数据实测的结果

把当初真实的资产状况填进去跑,在下载任何文件之前输出:

[FAIL] 0.3 novelty checked        record the date you searched the literature (YYYY-MM-DD)
[FAIL] 0.4 assets for target tier reachable ceiling = T2, target = T3

Missing for T3:
  [T3] second_platform_significant  the second platform must reach significance,
                                    not merely agree in direction

这正是本课题花了约三个月才得出的结论。 而且它点的是病根不是症状: IFNAR1 的工具在两个 SomaScan 队列里根本不构成有效工具(deCODE p=0.619 / F=0.2;ARIC F=8.9), 所以第二平台永远不可能显著——这是那两个队列的属性,开题时就能知道

target_tier 改成 T2 并补上新颖性日期 → gate0: 0 failed它会鉴别,不是一律拒绝。

第 1.5 步:定角色

bash
Rscript scripts/00b_analysis_roles.R study.yml

analyses: 块,每个分析声明 role / stage / downgrade。四个失败分支实测:

注入的错误被哪一项抓到报什么
LDSC 给了 downgrade: yes0.5cacceptance analyses cannot downgrade a candidate: LDSC genetic correlation
pheWAS 声明成 role: screen0.5eis declared as a screen/remover
某筛选器 removes_records: yes0.5dthese delete candidates instead of downgrading
stage 从 4 改成 90.5bstages 1->2->3->5->9

★ 0.5f 分层规则出处——本课题最贵的一个错就是它防的

scope.tier_rule_source实现分层规则的代码文件:行号,脚本把那几行原样打印出来, 让你拿它和上面声明的 screen 逐条对。

为什么要有这一条:三份交付物(PPT / 中文 Word / 英文 Word)把第四道判据写成 「低多效 / low pleiotropy(PheWAS)」,共 8 处; 而代码 32_targets_table.R:76-81 里第四道是方向一致性PheWAS 是分层之后才打印的旁路警示列,从未进过规则

这个错存活了约 5 周,期间 361 项审计断言全部通过—— 因为没有任何一条断言覆盖分层规则

实跑输出(真的把代码打出来了):

[PASS] 0.5f tier rule source  .../32_targets_table.R:76-81

  The tier rule AS IMPLEMENTED - read it against the screens listed above:
      | tab[, tier := fifelse(!in_MHC & coloc_support &
      |                         grepl("并发症特异|并发症增强", dm_class_s) &
      |                         targeting_flag != "★方向相反",
      |                       "A-优先",
      |              fifelse(!in_MHC & coloc_support, "B-...",
      |              fifelse(in_MHC, "C-MHC(LD)", "D-仅MR")))]

这个比对是人工的,脚本做不了。脚本能做的是让它变得可能。

另外三项:全都对"沉默"判 FAIL

检查问什么为什么必须写下来
0.2 阴性也成立主结果为零时,这篇文章还站得住吗?站不住 → 你赌的是运气,先改框架再花钱买数据。本课题最终论文以方法学结论打头,正因为"多少比例是糖尿病驱动"这个问题,答案是 30% 还是 70% 都能发
0.3 新颖性查过没有?哪天查的新颖性是文献的属性,不是你结果的属性,它不会因为你在算而变好。本课题查晚了,MR 主体被 2024–25 文献覆盖
0.3b 放弃条件什么结果会让你放弃这个靶点?开题写下来是执行规则;事后再说是在沉没成本下跟自己讲价。 本课题两条真实规则:APOL1 被"两平台方向相反"这条淘汰,ERMAP 被"F<10"这条淘汰

这四项都不可能从数据里算出来,所以全部对沉默判 FAIL—— 因为"没想过"和"想过了但没写",三个月后长得一模一样。

第 2 步:填 study.yml

复制 scripts/study.yml 改。两个字段决定关卡能不能工作:

  • columns —— 列名要照抄文件表头。不许起别名,不许猜。打开文件看一眼。
  • eaf_orientation —— 默认 effect。Gate 2.2 会告诉你什么时候该改成 other不许为了让报错消失而手动改它

scripts/study.example-ifnar1.yml 是一份跑通过真实数据的填好的例子。

第 3 步:Gate 1

bash
Rscript scripts/01_feasibility_gate.R study.yml

报告每个结局在多重检验校正后的 alpha 下的最小可测 OR:

ORmin=exp(z2NeffRexposure2),z=z1α/2+zpower,Neff=41/ncase+1/ncontrol

判为 marginalUNDERPOWERED 的结局产生不了证据——要么剔除,要么预先声明。 不许把它的阴性结果当成有信息的阴性来报。

本课题实测标定:

结局例数最小可测 OR判定
黄斑病变3,5721.35adequate
T1D(外部)20,3551.13adequate
新生血管性青光眼1,1001.71marginal

这与实际结果吻合:那个 1,100 例的结局在真实研究里零发现。区别在于,Gate 1 是在跑 MR 之前 就得出这个结论的——而当初它以"看似有信息的阴性"身份在稿件流程里待了好几周。

★ 1.4:这个结局到底在估计什么

疾病风险的遗传预测因子,常常不是疾病进展的预测因子。选错不是"估计有偏", 而是你手里的 estimand 悄悄变成了另一个

每个结局必须声明两个字段,不声明就 FAIL

designcontrol_groupestimand
incidencepopulation / disease_free发生——常规情形
progressionpopulation复合:"患病 且 并发症"
progressiondiseased进展,但有 index event bias

这正是本课题的真实处境

糖尿病黄斑病变是"糖尿病人中的进展",而 FinnGen 的对照是一般人群。 所以 estimand 是"糖尿病 黄斑病变"的复合效应,不是对进展的效应。

实测输出:

[PASS] 1.4 design [Maculopathy]      progression vs population controls -> COMPOSITE estimand
[PASS] 1.4 design [T1D_external]     incidence vs population controls
[PASS] 1.4 design [NeovascGlaucoma]  progression vs population controls -> COMPOSITE estimand

把对照限定成糖尿病人不是修复,那是用 collider bias 换掉复合效应。两种都站得住, 但都不许默不作声——这个 estimand 属于摘要,不是只属于局限性段落。

这一关什么都算不出来,它只对沉默判 FAIL:因为"我们没想过这件事"和 "我们是有意选的人群对照"在输出上长得一模一样。

第 4 步:Gate 2 —— 这一步不许跳

bash
Rscript scripts/02_input_qc.R study.yml

每个文件解压一次,跨全文件抽样(不是读头部——汇总统计按位置排序,前 N 行只是一条染色体)。 几个 GB 的文件要跑几分钟,这是应该付的成本

非零退出就是停

触发这道关卡的那个缺陷——effect allele frequency 列报的是对侧等位的频率—— 会让 p 值、置信区间和所有图完全正常。硬往下走,下游没有任何东西会告诉你。

四个子检查:

#查什么抓什么
2.1列映射显式打印,人读一遍maf 被当成 eafpval/mlogp 靠别名顺序解析
2.2 ★非回文工具的 EAF 对外部面板整列频率反转
2.3p_recomputed = 2·pnorm(-|beta/se|) 对账绑错列、OR 没取对数、se 不是 se
2.4哨兵位点 + 阴性对照表型标错
2.5基因组版本:声明 + 用哨兵坐标实证GRCh37/38 混用

★ 2.5:基因组版本

和 2.2 是同一种形状——局部损坏、不报错。GRCh37 与 GRCh38 混用时, 所有走 rsID 的步骤照常工作(谐化、MR 本身),所有走坐标的步骤静默出错: cis 窗口、±500 kb 邻居扫描、Open Targets 的 chr_pos_ref_alt 查询。

两层,因为便宜的那层替代不了有用的那层:

  1. 声明层:每个数据集都要写 build:,且必须全部一致
  2. 实证层:哨兵 rsID 在两个版本下的坐标是已知的,所以只要文件有位置列, 它就自己说出了自己的版本,不管它声明的是什么

实测(真实 T1D 文件,哨兵坐标取自 Ensembl REST 2026-08-05):

声明判定详情
GRCh38(真实)PASSpositions say GRCH38(b37:0 b38:3 of 3)
GRCh37(故意谎报)FAILdeclared GRCH37, positions say GRCH38;同时声明层单独报 GRCH38, GRCH37 不一致

它会鉴别而不是一律拒绝:没有 columns.possentinel_trait 的数据集报 NOT VERIFIED,既不判过也不判错。

2.2 报错时,先判断哪种情况为真,再动手:

情况做法
文件确实报的是对侧等位频率eaf_orientation: "other",重跑,并写进 Methods
你的 columns 映射错了改映射
LD 面板与 GWAS 人群不同源换匹配面板——这不是数据缺陷

2.4 一定要给每个结局设 sentinel_trait 留空会静默跳过这项检查。 阴性对照是其中最有力的一环:一个标着 1 型糖尿病、却在 TCF7L2 上带全基因组显著信号的文件, 就是标错了,而流水线里没有任何自洽性检查会说出这件事。

第 5 步:MR 与共定位

不在本 skill 里。 用父 skill 的 examples/cis_pqtl_mr.R

按工具个数分岔——蛋白组面板上绝大多数蛋白只有 1 个工具:

本课题实例

UKB-PPP 的 99.9% 蛋白只有 1 个 cis 哨兵工具。当初配置好的 MR-PRESSO、Cochran's Q、 MR-Egger 截距、leave-one-out 在数学上一次都跑不起来——它们都需要 ≥ 3 个工具 (Egger 要 ≥ 10 才有功效)。一套为多工具设计的敏感性电池,装在单工具设计上, 就是一套永远不会启动的电池。

第 6 步:Gate 3

bash
Rscript scripts/05_triangulate.R study.yml

需要 target.instrument_snp;L2G 还需要 instrument_posrefalt。 要启用 PAV 检查,在 exposure 块加 columns.consequence

#查什么判据
3.1PAV 敏感性剔除 PAV 前后:方向一致、|effect| 差 < 2 倍、p 仍名义显著
3.2±500 kb 邻居基因r² 远低于 0.05 且邻居对结局为零 → 排除中介;高 LD 需共定位,PP.H4 < 0.5 才保留
3.3跨平台方向一致是强制的(Eldjarn 2023:约一半 cis-pQTL 信号不在 Olink 与 SomaScan 间共享)
3.4Open Targets L2G≥ 0.5(Mountjoy 2021)
3.5反向因果反向 MR 的工具不许落在靶蛋白自己的 cis 区
3.6on-target 不良反应必须有方向列;未做则 Gate 4 封顶 T2

★ 3.5:反向因果

能自动化的,正是最容易做错的那一步:反向 MR(疾病 → 蛋白)如果把靶蛋白自己 cis 区里的 变异当工具,就是循环论证——那些变异按构造就会和蛋白相关,反向分析每次都返回假阳性。 这一关断言没有任何反向工具落在靶点的 cis 窗口内。

方向检验本身不打分。 MR-Steiger 在存在多效性时会失效(COPDGene 的 chr15q25 上它推出 "FEV1 导致当前吸烟"),且两个性状越相关功效反而越低。所以:报告方向时连同其局限一起报, 不要当成"过了一关"。反向 MR 为零,说的是"未发现反向效应的证据",绝不是"不存在反向效应"。

实测(夹具):

场景结果
反向工具里混入 rs914142(正向工具本身,落在 IFNAR1 ±500 kb 内)FAIL — "1 of 3 reverse instruments fall inside IFNAR1 → circular"
剔掉 cis 区变异后的同一组PASS — 0 of 2

★ 3.6:on-target 不良反应

没有安全性扫描的靶点提名只是半个提名。 产生疗效的那个扰动,正是药物会在这个蛋白 起作用的所有其他地方产生的扰动,所以 on-target 不良反应可以用同一个工具预测—— 而且这是审稿人一定会问的。

方向列是必需的,不是可选的

一个没有符号的命中,无法被归入"不良"还是"获益",所以没有方向的 pheWAS 不是安全性分析columns.beta 没映射时这一关直接 FAIL——因为一个无符号的扫描看起来是完整的

实测:beta 未映射 → FAIL: an UNSIGNED scan is not a safety analysis

结果含义
clear没有表型通过 0.05 / n_tests
flagged有命中——不是取消资格;每条都要连方向一起报
untested没做。Gate 4 封顶 T2

与疗效同向 ⇒ 预测的不良反应;反向 ⇒ 预测的次要获益。

工具模拟的是终生调节。短疗程药物可能不同,且受体脱敏会让长期效应反转(如 GIPR)。

「未评估」要和「未通过」一样认真读

lead 变异没有 rsID 的邻居 → 未评估,不是无风险。 变异不在任何 GWAS 可信集里 → L2G 不可评估,不是判据未通过。 两者都是证据缺失,不是证据反对

3.3 有一个极易混淆的区分:

设计证明了什么没有证明什么
同一变异,暴露效应换第二个平台测两种检测化学在方向上一致——反驳表位伪影不是独立复制。单工具 Wald ratio 下 MR 的 p 值恒等于结局的 p 值,三个估计共用同一个检验
在第二个队列里重新选工具真正的独立复制

第 7 步:Gate 4

bash
Rscript scripts/06_score_evidence.R study.yml \
    p=3.42e-5 n_tests=1587 pph4=0.940 \
    xplat=direction pav=clear neighbour=clear l2g=NA cohort=partial \
    reverse=clear safety=clear

打印证据层级和允许使用的措辞那个措辞就是稿件的天花板。

reversesafety 来自 Gate 3.5/3.6,默认 untested,把层级封顶在 T2。 这个默认是刻意的:一句"我们提名 X 为候选药物靶点"同时断言了方向安全性, 而一个没去看的分析两样都没有。实测三种情形:

输入层级
证据够 T3,但 safety 不传T2 + 提示"提名前先跑 Gate 3.6"
同上 + safety=clear reverse=clearT3
同上 + reverse=protein_affectedT2

附:图 1 流程图

bash
Rscript scripts/07_flow_diagram.R study.yml \
    "Proteins assayed=1954" "cis instruments=1587" "Harmonised=1587" \
    "FDR<0.05=142" "Complication-specific=21" "Colocalised=19" "Tier A=3"

标记每一个损失 ≥ 30% 输入的步骤。一个滤掉三分之一数据的过滤器,应该是明写的设计选择, 而不是让审稿人去发现的东西。


五、证据阶梯:允许说什么

七条判据

#判据阈值出处
1cis-MR 显著性P < 0.05 / N_proteins[有出处] 标准 Bonferroni
2共定位PP.H4 ≥ 0.7 提示性 · ≥ 0.8 可发表 · ≥ 0.95 工业级[有出处] Mountjoy 2021;Wallace 2020
3跨平台两种化学都显著且方向一致[有出处] Eldjarn 2023
4跨队列第二队列同向理想,非必需
5剔除 PAV 后一致一致,或本无 PAV[有出处] Sun 2023 补充材料
6邻居清白无非靶基因共享因果变异(PP.H4 < 0.5)[操作定义]
7Open Targets L2G≥ 0.5[有出处] Mountjoy 2021

两个提名前提(不是判据,是闸门)

前提来源缺了会怎样
反向因果不占主导Gate 3.5 reverse != protein_affected正向估计变成方向不明 → 封顶 T2
on-target 安全性已扫描Gate 3.6 safety != untested封顶 T2

再高的共定位也替代不了"去看一眼"

五层

需要可以不可以
T0 探索性仅 1(可用 FDR)"与……相关"、"一个候选"任何因果语言
T1 与共享因果一致1 + 2(≥ 0.7)"与共享因果变异一致""因果"、"靶点"
T2 跨化学一致+ 3 方向"在不同检测化学间一致""已复制"、"已验证"
T3 可发表的提名+ 3 显著 + 5 + 6,且两个前提都满足"我们提名 X 为候选药物靶点""我们确认 X 是因果的"
T4 临床药理级全部 7 项 + 两个前提,PP.H4 ≥ 0.95"遗传学证据支持 X 作为药物靶点"关于具体剂量或试验结果的断言

缺任何一条腿,都降级为"与……一致",绝不是"……的证据"。

措辞硬规则

情况不许写
FDR 过、Bonferroni 不过"FDR 校正后显著(探索性)"不加限定的"显著"
单个工具"Wald ratio;单工具下多效性稳健方法未定义"沉默,或一张填满 NA 的敏感性表
某队列中工具 F < 10"在该队列中无法检验(F = x)""未能复制"
宽区域内 PP.H3 占优"无法判定""无共定位"
同一变异换第二个平台测"方向在不同化学间一致""在独立数据集中复制"
跨平台单位不同的效应量"跨检测单位的效应量不可比"把倍数差当成不一致来报
反向 MR 什么也没查出来"未发现反向效应的证据""该蛋白不受疾病影响"
用 MR-Steiger 判定的方向"在其假设下与 Steiger 一致;存在多效性时可能反转""我们确定了因果方向"
并发症结局 + 一般人群对照"estimand 是疾病与并发症的复合"把它说成对进展的效应
pheWAS 没有 on-target 命中"在 α = 0.05/N 下未检出 on-target 不良表型""该靶点是安全的"

F < 10 和 PP.H3 这两行是最常见的证据倒置

两者都把缺失的证据说成了反对的证据,而后者是强得多的主张。

投稿前自检(每答一个"否",降一层)

  1. 如果某个输入文件被静默损坏了,这套分析会停下来吗?(Gate 2 跑了吗?)
  2. Methods 里每个阈值都标了「有出处」还是「操作定义」吗?
  3. 有没有哪句话说得比打印出来的层级更满?
  4. 有没有把"无法检验"写成了"未能复制"?
  5. 有没有把同一个检验当成多份独立证据数了?
  6. 流程图有没有交代清楚每一个进来了但没活下来的输入?
  7. 那些什么都没产出的结局,报了吗?带功效一起报了吗?
  8. 摘要里写的 estimand,和对照定义实际产生的那个是同一个吗?
  9. 如果提名了靶点,它的 on-target 不良反应谱扫过没有?带方向扫的吗?

Methods 里必须交代的一件事

如果 Gate 2 在某个公开数据集里发现并纠正了缺陷,明确写出来——哪个数据集、哪个字段、 怎么发现的、做了什么处理。这对之后每一个下载同一份文件的人都有用, 而且这是"方向性结果可信"的最强证据。


六、危险信号:立刻停

  • 没跑 Gate 2 对外部参照就报结果
  • 拿"谐化代码是对的"当作"方向是对的"的证据
  • 工具数 < 3 还跑 Egger 截距 / Cochran Q / MR-PRESSO
  • 对 F < 10 的队列说"未能复制"
  • 把同一个变异在不同平台上算成多次独立复制
  • 06_score_evidence.R 打印出层级之前,写下任何因果措辞
  • 并发症结局配一般人群对照,却说成"对进展的效应"
  • 反向 MR 的工具里混着靶蛋白自己 cis 区的变异
  • 提名靶点却没做 on-target 扫描,或者做了个没有方向的
  • 一个分析里混用两个基因组版本的坐标

借口与现实

借口现实
"流水线测试很充分"测试是拿流水线和它自己比。Gate 2 是拿它和世界比。
"效应等位在表头里标着呢"表头声明的是意图,Gate 2 验证的是内容。已发表的文件会违反它自己声明的标准。
"p 值和置信区间看着挺正常"符号翻转不改变其中任何一个。这正是它能存活的原因。
"三个平台都一致"同一变异 + 同一结局 = 一个检验。独立复制需要独立选出的工具。
"复制队列里不显著"先看 F。F < 10 是无法检验,不是被推翻
"共定位很强,所以这个基因是因果的"共定位分不开靶基因和邻居。那是 Gate 3 的事。
"明天就截稿了"Gate 4 打印的层级就是你能做的主张。截稿日不改变它。
"结局是并发症,所以这是进展研究"决定 estimand 的是对照组,不是结局的名字。一般人群对照给的是复合效应。
"反向 MR 是阴性,方向定了"先看它的工具。只要有一个落在靶点 cis 区,那个分析就是循环的。
"pheWAS 什么都没查出来,所以靶点安全"它是在那个 alpha、那批表型里没查出来。而且无符号的命中根本谈不上不良还是获益。
"两个文件都是新的,版本肯定一样"GWAS Catalog 统一转 GRCh38,而不少现役联盟发布仍是 GRCh37。
"先跑跑看能出什么"已经知道自己需要哪个层级。Gate 0 今天就能告诉你够不够得着,分析要三个月才告诉你。
"等有结果了再查新颖性"新颖性是文献的属性,不是你结果的属性。你在算的时候它不会变好。
"这个靶点留着,以后再决定要不要放弃"那时你是在沉没成本下跟自己讲价。开题就把放弃条件写死。

七、已知弱点(如实记录,不要以为它全包了)

TESTING.md 里有完整版。当前四个最弱的点:

#弱点性质怎么补
1单工具分岔只是指导,无脚本强制功能缺口03_check_iv_count.R:读谐化产物,IV=1 时若发现 Egger/Q/PRESSO 结果就报错
2「未能检验 vs 不复制」是措辞规则原理性限制脚本查不了散文,只能靠投稿前自检;或做关键词扫描器扫 Word/PPT
3Gate 3.2 没在高 LD 邻居上测过未验证分支找一个 r² ≥ 0.05 的真实案例跑一遍共定位回退分支
4Gate 1.1 没用真实 panel manifest 跑过未验证从 Sun 2023 Table S1 导出蛋白名单填进 panel_manifest 跑一次

另外四处要留意:

  • Gate 3.3 跨平台在脚本里是提示不是检查05_triangulate.R 打印 "manual - record (a) or (b) in Methods"fatal = FALSE——它提醒你区分两种设计,但不替你算。
  • Gate 3.5 / 3.6 只在夹具上验证过,没跑过本课题真实的反向 MR 与 pheWAS 产物。 循环污染分支和无符号扫描分支都测到了,真实文件没测。
  • Gate 2.5 只在同时配了位置列和哨兵性状时才做实证。在示例配置里,四个数据集只有一个满足。
  • Gate 0 的 assets 是你自己填的。填错一个 yes 会一路静默传下去,没有任何脚本能核对—— 和 Gate 1.3(样本重叠)是同一类局限。
  • 哨兵位点表目前只有 T1D / T2D。AMD 的候选位点是 CFH rs1061170、ARMS2 rs10490924, 但方向没有在两个独立数据集里核实过,所以故意没放进去。 未列入的 trait 会静默跳过 Gate 2.4——请显式写 sentinel_trait: "",让被跳过的检查在报告里可见。

明确不做的一件事

条件效应 vs 边际效应完全没有覆盖。 cisMR-cML(Nat Commun 2024)指出:cis 区里 若存在与结局相关、但没被纳入分析的 SNP,它与所选工具的相关会打开一条不经过暴露的旁路, 使所有工具失效;建议改用 GCTA-COJO 的条件效应。

暂不做的理由:修它要引入 GCTA 依赖,而本课题 99.9% 蛋白只有 1 个工具, 边际/条件之分在 n=1 时不适用,收益不清楚。这是一个有意识的取舍,不是遗漏。

加哨兵位点的规矩

  1. 断言方向和下界,绝不断言精确效应量。 队列之间效应大小的差异是合理的,招牌位点的符号不会差。
  2. 两个招牌位点 + 一个阴性对照。 阴性对照取自相关但遗传学上不同的性状,它才是抓表型标错的那一环。
  3. 加进去之前,在两个独立数据集里确认方向。 文献回忆不够—— 表里的 INS 行最初就填错了风险等位,是靠两个源文件都和它对不上才发现的。
  4. min_or 设得远低于已发表估计——查的是方向和数量级,不是复现点估计。

八、这个 skill 是从哪些真实失败里长出来的

不是虚构场景。以下五类失败全部发生在本课题真实数据上 (1,954 个 UKB-PPP 蛋白 × 7 个糖尿病并发症结局,FinnGen R9 + Mahajan T2D + GCST90824163 T1D):

场景发生了什么对应关卡
0 ★最贵的一次立项目标是提名药物靶点,但这件事在下载数据之前就已经不可能——工具在两个 SomaScan 队列里都不是有效工具,第二平台永远达不到显著。约三个月后才发现。新颖性同样查晚了Gate 0
A1,100 例的结局跑完全程,零发现——是设计决定的零,不是生物学决定的零Gate 1
B ★新 T1D 文件 EAF 列 93.7% 反转,导致 220 个回文工具(12.8%)beta 符号翻转,存活 7 天并通过全部审计Gate 2
C为多工具配好的敏感性电池,装在 99.9% 只有单工具的设计上,一次都跑不起来第 5 步分岔
D三次夸大:并列写"三个 A 级候选"、对视网膜 eQTL 写"强共定位"、把同一个检验当三平台复制Gate 4
EERMAP 被写成"跨平台复制失败",实际是两个队列 F=0.2 / 8.9 根本不构成有效工具Gate 3 + 4

共同形状

分析内部自洽,外部错误。

任何"把流水线和它自己比"的检查都会通过。只有对照外部参照物——参考面板、教科书位点、 已发表阈值、证据阶梯——才抓得住。四道关卡全部是外部检查。

场景 B 当时的原话

「谐化做得对」

这句话是真的,而且不相关。代码是对的,喂给它的数据不是。 这两件事互相独立,前者正确推不出后者正确。

而且这个缺陷不是被任何流程发现的——是一个人追问了两次"暴露和结局的效应等位一致吗"才发现的。

跑起来才抓到的三个 bug(写代码时看不出来)

bug后果
功效计算用了未经多重检验校正的 alpha把 1,100 例的结局判成 adequate(OR_min 1.35)
配置的暴露列在文件里不存在时,静默取默认 R²无声地用错参数
fread(select = )具名向量会静默改列名之后 setnames() 找不到原名,整个文件被报成不可读——这曾让所有结局文件的检查都失效
★ 2026-08-05:06_score_evidence.RA[[k]] 读命令行参数具名字符向量上 [[ 遇到不存在的名字会抛 subscript out of bounds 而不是返回 NULL,`%
★ 2026-08-06:Gate 0 的 0.1 只查了句子长度 ≥ 30模板里那句占位符 In [population], does genetically predicted [protein]... 有 96 个字符——一个完全没填的配置,通过了那个专门用来抓"没填"的检查。已改为按名字点出未替换的 [...] 占位符。

参考

  • Yao et al. Biomolecules 2024;14:355 —— 骨关节炎蛋白组 MR,本页「串联筛选 + 并联表征」的流程依据:共定位「not used to exclude candidates」、PheWAS「to investigate whether side effects existed」
  • Sun et al. medRxiv 2026.07.14.26358022(同济 C1R 共病,同 UKB-PPP 54,219)—— 漏斗式报告 1,954 → 224 → 40 → 5;全文 tier / MHC / HLA / chr6 均零命中(本地 PDF 提取实测 1,683 行)
  • Chen et al. PMC10827252 —— MHC 排除的原文限定:「for trans-pQTLs, variants in the extended MHC region (Chr6:25–34Mb)」
  • Dhalla et al. Nat Commun 2024;15:6318 —— The influence of HLA genetic variation on plasma protein expression(UKB 45,330×2,940 蛋白):504 蛋白受 HLA 影响、94.8% 为 trans、机制=抗原呈递;并明言标准 fine-mapping/共定位**「are not suitable for analysis in the MHC region」**,MR 亦待方法学发展
  • Gill et al. BMC Med 2024;22:473 —— 药靶 MR 常见陷阱与规避(本轮 1.4 / 3.6 的依据:发生 vs 进展、生存偏倚、工具的生物学验证、on-target 效应)
  • Lutz et al., reverseDirection —— MR-Steiger 在多效性下会给出错误方向;建议对自己的数据做情景模拟
  • cisMR-cML, Nat Commun 2024 —— 条件效应 vs 边际效应;只用暴露相关 SNP 会使工具失效(本轮有意未采纳,理由见上)
  • Burgess et al. Wellcome Open Res 2019;4:186 v3 §4 Variant harmonization —— 「等位基因和链的信息可以通过比较等位基因频率信息来交叉核对」;原文并载明等位对齐问题「已导致孟德尔随机化分析出现错误结果,以及稿件的撤回与更正」
  • Sun et al. Nature 2023;622:329 —— UKB-PPP,补充表 S1 为蛋白清单
  • Eldjarn et al. Nature 2023;622:348 —— Olink 与 SomaScan 的 cis-pQTL 共享率
  • Mountjoy et al. Nat Genet 2021;53:1527 —— Open Targets L2G
  • Wallace PLoS Genet 2020;16:e1008720 —— 共定位
  • Skrivankova et al. JAMA 2021;326:1614 —— STROBE-MR
  • Burgess et al. Genet Epidemiol 2016;40:597;Mounier & Kutalik Genet Epidemiol 2023;47:314 —— 样本重叠与赢者诅咒

个人科研与运维文档 · 内容持续修订