@@ -26,10 +26,10 @@ mr <- function(
2626 # Convert to data.table for efficient grouped operations
2727
2828 dat_dt <- data.table :: as.data.table(dat )
29-
29+
3030 # Get unique combinations of id.exposure and id.outcome
3131 combos <- unique(dat_dt [, .(id.exposure , id.outcome )])
32-
32+
3333 # Pre-compute method names once, outside the loop
3434 methl <- mr_method_list()
3535 method_names <- methl $ name [match(method_list , methl $ obj )]
@@ -40,7 +40,7 @@ mr <- function(
4040 out_id <- combos $ id.outcome [i ]
4141 x1 <- dat_dt [id.exposure == exp_id & id.outcome == out_id ]
4242 x <- x1 [mr_keep == TRUE ]
43-
43+
4444 if (nrow(x ) == 0 ) {
4545 message(
4646 " No SNPs available for MR analysis of '" ,
@@ -71,7 +71,7 @@ mr <- function(
7171 mr_tab <- mr_tab [! (is.na(mr_tab $ b ) & is.na(mr_tab $ se ) & is.na(mr_tab $ pval )), ]
7272 return (mr_tab )
7373 })
74-
74+
7575 mr_tab <- data.table :: rbindlist(results , fill = TRUE , use.names = TRUE )
7676 data.table :: setDF(mr_tab )
7777
@@ -662,12 +662,16 @@ mr_egger_regression_bootstrap <- function(b_exp, b_out, se_exp, se_out, paramete
662662
663663 # Vectorized bootstrap: generate all random values at once
664664 # Matrix dimensions: nboot rows x nsnp columns
665- xs_mat <- matrix (stats :: rnorm(nboot * nsnp , mean = rep(b_exp , each = nboot ),
666- sd = rep(se_exp , each = nboot )),
667- nrow = nboot , ncol = nsnp )
668- ys_mat <- matrix (stats :: rnorm(nboot * nsnp , mean = rep(b_out , each = nboot ),
669- sd = rep(se_out , each = nboot )),
670- nrow = nboot , ncol = nsnp )
665+ xs_mat <- matrix (
666+ stats :: rnorm(nboot * nsnp , mean = rep(b_exp , each = nboot ), sd = rep(se_exp , each = nboot )),
667+ nrow = nboot ,
668+ ncol = nsnp
669+ )
670+ ys_mat <- matrix (
671+ stats :: rnorm(nboot * nsnp , mean = rep(b_out , each = nboot ), sd = rep(se_out , each = nboot )),
672+ nrow = nboot ,
673+ ncol = nsnp
674+ )
671675
672676 # Apply sign correction for Egger regression (vectorized)
673677 ys_mat <- ys_mat * sign(xs_mat )
@@ -676,15 +680,19 @@ mr_egger_regression_bootstrap <- function(b_exp, b_out, se_exp, se_out, paramete
676680 # Vectorized weighted linear regression for all bootstrap iterations
677681 # For each bootstrap iteration, compute weighted regression coefficients
678682 # Using the formula: bhat = cov(x*w, y*w) / var(x*w), ahat = mean(y) - mean(x)*bhat
679- res <- t(vapply(seq_len(nboot ), function (i ) {
680- xs <- xs_mat [i , ]
681- ys <- ys_mat [i , ]
682- xw <- xs * weights
683- yw <- ys * weights
684- bhat <- stats :: cov(xw , yw , use = " pair" ) / stats :: var(xw , na.rm = TRUE )
685- ahat <- mean(ys , na.rm = TRUE ) - mean(xs , na.rm = TRUE ) * bhat
686- c(ahat , bhat )
687- }, numeric (2 )))
683+ res <- t(vapply(
684+ seq_len(nboot ),
685+ function (i ) {
686+ xs <- xs_mat [i , ]
687+ ys <- ys_mat [i , ]
688+ xw <- xs * weights
689+ yw <- ys * weights
690+ bhat <- stats :: cov(xw , yw , use = " pair" ) / stats :: var(xw , na.rm = TRUE )
691+ ahat <- mean(ys , na.rm = TRUE ) - mean(xs , na.rm = TRUE ) * bhat
692+ c(ahat , bhat )
693+ },
694+ numeric (2 )
695+ ))
688696
689697 return (list (
690698 b = mean(res [, 2 ], na.rm = TRUE ),
@@ -808,20 +816,28 @@ weighted_median_bootstrap <- function(b_exp, b_out, se_exp, se_out, weights, nbo
808816
809817 # Vectorized bootstrap: generate all random values at once
810818 # Matrix dimensions: nboot rows x nsnp columns
811- b_exp_mat <- matrix (stats :: rnorm(nboot * nsnp , mean = rep(b_exp , each = nboot ),
812- sd = rep(se_exp , each = nboot )),
813- nrow = nboot , ncol = nsnp )
814- b_out_mat <- matrix (stats :: rnorm(nboot * nsnp , mean = rep(b_out , each = nboot ),
815- sd = rep(se_out , each = nboot )),
816- nrow = nboot , ncol = nsnp )
819+ b_exp_mat <- matrix (
820+ stats :: rnorm(nboot * nsnp , mean = rep(b_exp , each = nboot ), sd = rep(se_exp , each = nboot )),
821+ nrow = nboot ,
822+ ncol = nsnp
823+ )
824+ b_out_mat <- matrix (
825+ stats :: rnorm(nboot * nsnp , mean = rep(b_out , each = nboot ), sd = rep(se_out , each = nboot )),
826+ nrow = nboot ,
827+ ncol = nsnp
828+ )
817829
818830 # Compute Wald ratios for all bootstrap samples (element-wise division)
819831 betaIV_mat <- b_out_mat / b_exp_mat
820832
821833 # Apply weighted_median to each bootstrap iteration
822- med <- vapply(seq_len(nboot ), function (i ) {
823- weighted_median(betaIV_mat [i , ], weights )
824- }, numeric (1 ))
834+ med <- vapply(
835+ seq_len(nboot ),
836+ function (i ) {
837+ weighted_median(betaIV_mat [i , ], weights )
838+ },
839+ numeric (1 )
840+ )
825841
826842 return (stats :: sd(med ))
827843}
@@ -1118,7 +1134,11 @@ mr_raps <- function(b_exp, b_out, se_exp, se_out, parameters = default_parameter
11181134 }
11191135
11201136 if (utils :: packageVersion(' mr.raps' ) < ' 0.4.3' ) {
1121- message(paste(" The version of mr.raps is" , utils :: packageVersion(' mr.raps' ), " please consider updating to version 0.4.3 or higher, e.g., install.packages('mr.raps', repos = c('https://mrcieu.r-universe.dev', 'https://cloud.r-project.org')) " ))
1137+ message(paste(
1138+ " The version of mr.raps is" ,
1139+ utils :: packageVersion(' mr.raps' ),
1140+ " please consider updating to version 0.4.3 or higher, e.g., install.packages('mr.raps', repos = c('https://mrcieu.r-universe.dev', 'https://cloud.r-project.org')) "
1141+ ))
11221142 }
11231143
11241144 data <- data.frame (
0 commit comments