跳转至

616_孟德尔随机化分析

一句话概述: 孟德尔随机化(MR)利用遗传变异作为"天然随机分组"的工具变量,从观察性数据中推断暴露因素与结局之间的因果关系,相当于用基因做了一场"不花钱的随机对照试验"。

核心知识点速查表

概念白话解释
工具变量(IV)用遗传变异(SNP)作为代理来推断因果关系
暴露(Exposure)你怀疑的"原因",如BMI、肠道菌群
结局(Outcome)你关心的"结果",如2型糖尿病、心血管病
Two-sample MR暴露和结局的GWAS数据来自不同人群
IVW逆方差加权法,MR的主要分析方法
MR-Egger能检测和校正水平多效性的敏感性分析
Pleiotropy多效性——一个SNP影响多个性状
F-statistic工具变量强度指标,>10算强工具变量

一、MR三大核心假设

白话版: 1. 关联性:你选的SNP确实与暴露因素相关(比如这些SNP确实影响BMI) 2. 独立性:这些SNP不受混杂因素影响(基因在出生时随机分配,天然满足) 3. 排他性:这些SNP只通过暴露因素影响结局,不走"后门"(最难验证)

二、安装与配置

# === 安装TwoSampleMR包 ===
# 方法1:从r-universe安装(推荐)
install.packages(
    "TwoSampleMR",
    repos = c("https://mrcieu.r-universe.dev", 
              "https://cloud.r-project.org")
)

# 方法2:从GitHub安装
# install.packages("remotes")
remotes::install_github("MRCIEU/TwoSampleMR")

# 安装其他MR相关包
install.packages("MendelianRandomization")  # 另一个MR包
remotes::install_github("rondolab/MR-PRESSO")  # MR-PRESSO

# 加载包
library(TwoSampleMR)  # 加载TwoSampleMR

# === 2024年重要更新:OpenGWAS需要API认证 ===
# 访问 https://api.opengwas.io 获取API key
# 在R中设置:
Sys.setenv(OPENGWAS_JWT = "your_api_key_here")  # 设置API密钥

三、Two-Sample MR完整流程

3.1 获取暴露数据

# === 方法1:从OpenGWAS数据库获取 ===
# 搜索可用的GWAS数据集
ao <- available_outcomes()  # 查看所有可用GWAS
bmi_ids <- ao[grep("body mass index", ao$trait, ignore.case = TRUE), ]
head(bmi_ids[, c("id", "trait", "nsnp", "sample_size")])  # 查看BMI相关

# 提取暴露的工具变量SNP
exposure_dat <- extract_instruments(
    outcomes = "ieu-b-40",  # BMI的GWAS数据集ID
    p1 = 5e-8,              # 全基因组显著性阈值
    clump = TRUE,           # LD clumping去除冗余SNP
    r2 = 0.001,             # clumping的LD阈值
    kb = 10000              # clumping的距离窗口(10Mb)
)
cat("提取到", nrow(exposure_dat), "个工具变量SNP\n")

# === 方法2:从本地GWAS结果读取 ===
exposure_dat <- read_exposure_data(
    filename = "bmi_gwas_summary.txt",  # 本地文件
    sep = "\t",                          # 分隔符
    snp_col = "SNP",                     # SNP列
    beta_col = "BETA",                   # 效应值列
    se_col = "SE",                       # 标准误列
    effect_allele_col = "A1",            # 效应等位基因
    other_allele_col = "A2",             # 其他等位基因
    pval_col = "P",                      # p值列
    eaf_col = "EAF"                      # 效应等位基因频率
)

3.2 获取结局数据

# === 从OpenGWAS提取结局数据 ===
outcome_dat <- extract_outcome_data(
    snps = exposure_dat$SNP,  # 使用暴露的SNP
    outcomes = "ieu-b-7"      # 2型糖尿病的GWAS数据集ID
)

# === 从本地文件读取 ===
outcome_dat <- read_outcome_data(
    filename = "t2d_gwas_summary.txt",
    snps = exposure_dat$SNP,  # 只提取暴露的SNP
    sep = "\t",
    snp_col = "SNP",
    beta_col = "BETA",
    se_col = "SE",
    effect_allele_col = "A1",
    other_allele_col = "A2",
    pval_col = "P",
    eaf_col = "EAF"
)

3.3 数据协调(Harmonization)

# 确保暴露和结局的等位基因编码一致
dat <- harmonise_data(
    exposure_dat = exposure_dat,  # 暴露数据
    outcome_dat = outcome_dat,    # 结局数据
    action = 2                     # 自动协调(推荐)
)
# action=1: 假设所有等位基因都在正链
# action=2: 尝试推断正确的链方向(推荐)
# action=3: 严格模式,无法确定的SNP全部去除

cat("协调后保留", nrow(dat), "个SNP\n")

3.4 运行MR分析

# === 主要MR分析 ===
res <- mr(dat)  # 运行所有默认MR方法
print(res)  # 查看结果

# 输出包含5种方法的结果:
# MR Egger        — 能检测多效性
# Weighted median  — 允许50%的SNP无效
# IVW             — 主要分析方法(逆方差加权)
# Simple mode     — 简单模式
# Weighted mode   — 加权模式

# === 指定特定方法 ===
res_specific <- mr(
    dat,
    method_list = c(
        "mr_ivw",                    # IVW(主要方法)
        "mr_egger_regression",       # MR-Egger
        "mr_weighted_median",        # 加权中位数
        "mr_penalised_weighted_median"  # 惩罚加权中位数
    )
)

3.5 敏感性分析

# === 1. 异质性检验 ===
het <- mr_heterogeneity(dat)  # Cochran's Q检验
print(het)
# p < 0.05 说明SNP间存在异质性,需要关注

# === 2. 水平多效性检验(MR-Egger截距)===
pleio <- mr_pleiotropy_test(dat)  # 多效性检验
print(pleio)
# p < 0.05 说明存在水平多效性,IVW结果可能有偏

# === 3. 留一法分析(Leave-one-out)===
loo <- mr_leaveoneout(dat)  # 每次去掉一个SNP重新分析
# 如果去掉某个SNP后结果变化很大,说明该SNP可能有问题

# === 4. MR-PRESSO(检测和去除离群SNP)===
library(MRPRESSO)
presso_res <- mr_presso(
    BetaOutcome = "beta.outcome",
    BetaExposure = "beta.exposure",
    SdOutcome = "se.outcome",
    SdExposure = "se.exposure",
    OUTLIERtest = TRUE,     # 检测离群SNP
    DISTORTIONtest = TRUE,  # 检测校正前后差异
    data = dat,
    NbDistribution = 1000,  # 分布模拟次数
    SignifThreshold = 0.05  # 显著性阈值
)

3.6 可视化

# === 1. 散点图(Scatter plot)===
p1 <- mr_scatter_plot(res, dat)  # 暴露-结局效应的散点图
ggsave("mr_scatter.pdf", p1[[1]], width = 8, height = 6)

# === 2. 森林图(Forest plot)===
res_single <- mr_singlesnp(dat)  # 单SNP分析
p2 <- mr_forest_plot(res_single)  # 森林图
ggsave("mr_forest.pdf", p2[[1]], width = 8, height = 10)

# === 3. 留一法图(Leave-one-out plot)===
p3 <- mr_leaveoneout_plot(loo)  # 留一法图
ggsave("mr_leaveoneout.pdf", p3[[1]], width = 8, height = 10)

# === 4. 漏斗图(Funnel plot)===
p4 <- mr_funnel_plot(res_single)  # 漏斗图
ggsave("mr_funnel.pdf", p4[[1]], width = 8, height = 6)

四、工具变量质量评估

# === 计算F-statistic(工具变量强度)===
# F > 10 说明是强工具变量,可以信赖MR结果

dat$F_stat <- (dat$beta.exposure / dat$se.exposure)^2  # 计算F值
cat("F-statistic范围:", range(dat$F_stat), "\n")
cat("平均F-statistic:", mean(dat$F_stat), "\n")
cat("F < 10的弱工具变量数:", sum(dat$F_stat < 10), "\n")

# 如果有弱工具变量,考虑去除
dat_strong <- dat[dat$F_stat >= 10, ]  # 只保留强IV
cat("去除弱IV后剩余SNP数:", nrow(dat_strong), "\n")

# === 计算总R²(暴露的方差解释比例)===
r2 <- sum(2 * dat$eaf.exposure * (1 - dat$eaf.exposure) * 
          dat$beta.exposure^2)
cat("总R²:", r2, "\n")
# R²太小(<1%)说明工具变量解释暴露的能力弱

五、MR结果报告(STROBE-MR清单要点)

# === 整理最终结果 ===
cat("\n========== MR分析结果报告 ==========\n")
cat("暴露: BMI\n")
cat("结局: 2型糖尿病\n")
cat("工具变量SNP数:", nrow(dat), "\n")
cat("平均F-statistic:", round(mean(dat$F_stat), 1), "\n\n")

# 主要结果
cat("--- 主要分析 ---\n")
for(i in 1:nrow(res)) {
    or <- exp(res$b[i])  # 转为OR
    ci_low <- exp(res$b[i] - 1.96 * res$se[i])  # 95%CI下限
    ci_high <- exp(res$b[i] + 1.96 * res$se[i])  # 95%CI上限
    cat(sprintf("%s: OR=%.2f (95%%CI: %.2f-%.2f), p=%.2e\n",
        res$method[i], or, ci_low, ci_high, res$pval[i]))
}

# 敏感性分析
cat("\n--- 敏感性分析 ---\n")
cat("异质性检验 p:", het$Q_pval, "\n")
cat("MR-Egger截距 p:", pleio$pval, "\n")

六、常见报错与解决

报错信息原因解决方案
No API key found2024年起OpenGWAS需要认证设置OPENGWAS_JWT环境变量
No proxy SNPs foundSNP在结局数据中找不到降低LD阈值或用proxy SNP
Not enough SNPs for MR协调后SNP太少放宽暴露的p值阈值
F-statistic < 10弱工具变量去除弱IV或增加SNP数
MR-Egger intercept significant存在水平多效性IVW结果可能有偏,以MR-Egger为主
Heterogeneity detectedSNP间效应不一致使用随机效应IVW或MR-PRESSO

七、面试高频题

Q1:孟德尔随机化的基本原理是什么?

答: MR利用基因的"随机分配"特性(类似RCT中的随机分组)。遗传变异在受精时随机分配,不受出生后混杂因素影响。如果某些SNP影响BMI(暴露),而这些SNP携带者的糖尿病风险也更高(结局),那么BMI可能因果性地增加糖尿病风险。本质是用遗传变异作为工具变量进行因果推断。

Q2:MR的三大核心假设是什么?违反了怎么办?

答: (1) 关联性:SNP必须与暴露强关联(F-statistic > 10验证);(2) 独立性:SNP不受混杂因素影响(基因天然满足);(3) 排他性:SNP只通过暴露影响结局(最难验证)。违反排他性叫"水平多效性",用MR-Egger截距检验检测,MR-PRESSO去除离群SNP,加权中位数法容许50%的无效SNP。

Q3:Two-sample MR的优缺点?

答: 优点:(1) 不需要个体水平数据,用公开的GWAS汇总统计量即可;(2) 暴露和结局来自不同人群,避免赢者诅咒偏倚;(3) 样本量大。缺点:(1) 两个样本可能存在人群差异;(2) 无法检测非线性因果关系;(3) 受限于GWAS的检出能力。

Q4:如何判断MR结果是否可靠?

答: 看五个方面:(1) IVW、MR-Egger、加权中位数等多种方法的方向和显著性一致;(2) MR-Egger截距不显著(无水平多效性);(3) F-statistic均>10(强工具变量);(4) 留一法分析中结果不被单个SNP驱动;(5) MR-PRESSO无显著离群SNP。满足以上条件说明结果稳健。


参考资料:TwoSampleMR: Hemani et al., eLife 2018 | STROBE-MR: Skrivankova et al., BMJ 2021 | MR教程: Davies et al., BMJ 2018 | GWASTutorial MR章节