前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于MR-Egger方法的注意事项(1)

关于MR-Egger方法的注意事项(1)

作者头像
生信与临床
发布2022-08-21 16:54:37
9820
发布2022-08-21 16:54:37
举报

知识回顾

在往期的内容中,我和大家简单介绍过MR研究中IVW和MR-Egger这两种方法的区别,具体参见孟德尔随机化之IVW和MR-Egger方法简介。

主要问题

前一阵子,有小伙伴提出来用“TwoSampleMR”包里的MR-Egger方法算出来的结果和直接在回归模型里添加截距项的结果不同。我看了一下,这里主要是因为暴露数据里的beta值存在负数,要想彻底理解这个问题,我们有必要看一下计算的源代码。

“TwoSampleMR”包里的MR-Egger计算代码如下(该代码可以在R语言中加载好TwoSampleMR包后直接输入mr_egger_regression并回车即可获取):

代码语言:javascript
复制
function (b_exp, b_out, se_exp, se_out,parameters)
{
   stopifnot(length(b_exp) == length(b_out)) 
   stopifnot(length(se_exp) == length(se_out))
   stopifnot(length(b_exp) == length(se_out))
   #上面三行stopifnot是排错步骤,针对的是数据不完整的情况
   nulllist <- list(b = NA, se = NA, pval = NA, nsnp = NA, b_i = NA,
       se_i = NA, pval_i = NA, Q = NA, Q_df = NA, Q_pval = NA,
       mod = NA, smod = NA, dat = NA)
    if(sum(!is.na(b_exp) & !is.na(b_out) & !is.na(se_exp) &
       !is.na(se_out)) < 3) { # MR-Egger的计算需要至少3个有效的IV,否则报错
        return(nulllist)
    }
   sign0 <- function(x) {
       x[x == 0] <- 1 # 区别于sign()函数的不同之处,把beta为0的变成1,基础函数中sign(0) = 0
       return(sign(x))
    }
   to_flip <- sign0(b_exp) == -1 # 确定exposure中beta<0的要翻转
   b_out = b_out * sign0(b_exp) # 对于要翻转的SNP,其outcome中的beta值要取相反数
   b_exp = abs(b_exp) # 暴露的beta值全变为正值
   dat<- data.frame(b_out = b_out, b_exp = b_exp, se_exp = se_exp,
       se_out = se_out, flipped = to_flip)
   mod<- lm(b_out ~ b_exp, weights = 1/se_out^2) # 回归分析,逆方差加权,保留截距项
   smod <- summary(mod)
    if(nrow(coefficients(smod)) > 1) {
       b <- coefficients(smod)[2, 1] # 获取beta值
       se <- coefficients(smod)[2, 2]/min(1, smod$sigma) # 获取se
       pval <- 2 * pt(abs(b/se), length(b_exp) - 2, lower.tail = FALSE)
       b_i <- coefficients(smod)[1, 1] # 获取截距项
       se_i <- coefficients(smod)[1, 2]/min(1, smod$sigma) # 获取截距项的se
       pval_i <- 2 * pt(abs(b_i/se_i), length(b_exp) - 2, lower.tail =FALSE) # 获取截距项的p值(采用的是T检验)
       Q <- smod$sigma^2 * (length(b_exp) - 2) # 计算MR结果的异质性
       Q_df <- length(b_exp) - 2 # 计算自由度
       Q_pval <- pchisq(Q, Q_df, lower.tail = FALSE) # 使用卡方检验获取异质性p值
    }
   else {
       warning("Collinearities in MR Egger, try LD pruning the exposurevariables.")
       return(nulllist)
    }
   return(list(b = b, se = se, pval = pval, nsnp = length(b_exp),
       b_i = b_i, se_i = se_i, pval_i = pval_i, Q = Q, Q_df = Q_df,
       Q_pval = Q_pval, mod = smod, dat = dat))
}

上面这个计算方法中,它借用了R里的sign()基础函数来重新定义了sign0()这个函数,其目的就是把beta.exposure为0的符号变为1(不过米老鼠觉得没有必要)。

接下来,我们看看这里最关键的部分“to_flip”,这一块就是借用之前新定义的sign0()函数来把beta.exposure为负值的调整为正值,相应的beta.outcome也会取一个相反数,这样就保证了每个SNP的effect allele对exposure的效应是一致的(也即都增加暴露的风险),同时不改变利用单个SNP进行Wald ratio估计的效果。

接下来我将以示例文件具体展示一下比较的过程(示例文件可以点击阅读原文下载demo1.csv即可):

代码语言:javascript
复制
# 利用MR-Egger方法计算(有flip的过程)
library(TwoSampleMR)
data = read.csv('demo1.csv',header=T)
mr_egger_regression(b_exp =data$beta.exposure, b_out = data$beta.outcome, se_exp = data$se.exposure,se_out = data$se.outcome)

其主要输出结果如下(注意mr_egger_regression是TwoSampleMR包里的函数):

代码语言:javascript
复制
# 直接回归(包含截距项,但没有flip的过程)
summary(lm(beta.outcome ~ 1 +beta.exposure, weights = 1/se.outcome^2, data = data))

其输出结果如下:

通过上述比较我们不难发现,两个结果是有差异的,其中第一个是MR-Egger方法计算出来的结果,第二个就是普通的线性回归。从数学上来看,MR-Egger在进行回归分析前把位于二、三象限的点通过中心(原点)对称的方式分别转化到四、一象限了(二象限对称到四象限,三象限对称到一象限),经过这么转换后SNP对exposure的效应方向也就一致了,也便于解释接下来的多效性问题。

因此,当你的暴露文件中beta值有负数的时候不要直接拟合,可以先翻转符号后再拟合,这样才是MR-Egger计算方法。希望大家注意!

当然,你也可以直接使用TwoSampleMR提供的MR-Egger方法,这是没有问题的。

PS: 之前有小伙伴提出无法从我的Gitee里下载MRinstruments包,米老鼠查看了一下,是我之前把这个MRInstruments库设成私密文件了,在这里向大家道个歉。现在我已经将其设置为公开了,大家可以自由下载(Gitee的下载速度比Github快很多!)。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-01-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 生信与临床 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档