@@ -470,6 +470,35 @@ colocboost_analysis_pipeline <- function(region_data,
470470 sumstats <- LD_mat <- dict_sumstatLD <- NULL
471471 }
472472
473+ # Helper: validate a single GWAS study data.frame and its LD matrix
474+ is_valid_sumstat_entry <- function (df , ld_matrix ) {
475+ if (is.null(df ) || nrow(df ) == 0 ) return (FALSE )
476+ if (! all(c(" z" , " n" , " variant" ) %in% colnames(df ))) return (FALSE )
477+ n_vals <- suppressWarnings(as.numeric(unique(df $ n )))
478+ if (length(n_vals ) == 0 || is.na(n_vals [1 ]) || ! is.finite(n_vals [1 ]) || n_vals [1 ] < 3 ) return (FALSE )
479+ if (all(is.na(df $ z ))) return (FALSE )
480+ if (is.null(ld_matrix )) return (FALSE )
481+ if (! is.matrix(ld_matrix )) return (FALSE )
482+ if (any(! is.finite(ld_matrix ))) return (FALSE )
483+ # Ensure at least 1 overlapping variant with LD matrix dimnames
484+ ld_vars <- intersect(rownames(ld_matrix ), colnames(ld_matrix ))
485+ if (length(ld_vars ) == 0 ) return (FALSE )
486+ if (length(intersect(as.character(df $ variant ), as.character(ld_vars ))) == 0 ) return (FALSE )
487+ TRUE
488+ }
489+
490+ # Helper: filter joint structures (sumstats list and dict_sumstatLD) to only valid entries
491+ filter_valid_sumstats <- function (sumstats , LD_mat , dict_sumstatLD ) {
492+ if (is.null(sumstats ) || is.null(dict_sumstatLD ) || is.null(LD_mat )) return (list (sumstats = NULL , dict = NULL ))
493+ keep <- vector(" logical" , length(sumstats ))
494+ for (i in seq_along(sumstats )) {
495+ ld_idx <- dict_sumstatLD [i , 2 ]
496+ ld_matrix <- if (! is.na(ld_idx )) LD_mat [[ld_idx ]] else NULL
497+ keep [i ] <- is_valid_sumstat_entry(sumstats [[i ]], ld_matrix )
498+ }
499+ if (! any(keep )) return (list (sumstats = NULL , dict = NULL ))
500+ list (sumstats = sumstats [keep ], dict = matrix (dict_sumstatLD [keep , , drop = FALSE ], ncol = 2 ))
501+ }
473502
474503 # ###### ========= streamline three types of analyses ======== ########
475504 if (is.null(X ) & is.null(sumstats )) {
@@ -500,32 +529,55 @@ colocboost_analysis_pipeline <- function(region_data,
500529 if (joint_gwas & ! is.null(sumstats )) {
501530 message(paste(" ====== Performing non-focaled version GWAS-xQTL ColocBoost on" , length(Y ), " contexts and" , length(sumstats ), " GWAS. =====" ))
502531 t21 <- Sys.time()
503- traits <- c(names(Y ), names(sumstats ))
504- res_gwas <- colocboost(
505- X = X , Y = Y , sumstat = sumstats , LD = LD_mat ,
506- dict_YX = dict_YX , dict_sumstatLD = dict_sumstatLD ,
507- outcome_names = traits , focal_outcome_idx = NULL ,
508- output_level = 2 , ...
509- )
510- t22 <- Sys.time()
511- analysis_results $ joint_gwas <- res_gwas
512- analysis_results $ computing_time $ Analysis $ joint_gwas <- t22 - t21
532+ # Filter invalid GWAS before calling colocboost
533+ filtered <- filter_valid_sumstats(sumstats , LD_mat , dict_sumstatLD )
534+ if (is.null(filtered $ sumstats )) {
535+ message(" All GWAS studies failed validation; skipping joint GWAS analysis for this region." )
536+ } else {
537+ traits <- c(names(Y ), names(filtered $ sumstats ))
538+ res_gwas <- colocboost(
539+ X = X , Y = Y , sumstat = filtered $ sumstats , LD = LD_mat ,
540+ dict_YX = dict_YX , dict_sumstatLD = filtered $ dict ,
541+ outcome_names = traits , focal_outcome_idx = NULL ,
542+ output_level = 2 , ...
543+ )
544+ t22 <- Sys.time()
545+ analysis_results $ joint_gwas <- res_gwas
546+ analysis_results $ computing_time $ Analysis $ joint_gwas <- t22 - t21
547+ }
513548 }
514549 # - run focaled version of ColocBoost for each GWAS
515550 if (separate_gwas & ! is.null(sumstats )) {
516551 t31 <- Sys.time()
517552 res_gwas_separate <- analysis_results $ separate_gwas
518553 for (i_gwas in 1 : nrow(dict_sumstatLD )) {
519554 current_study <- names(sumstats )[i_gwas ]
520- message(paste(" ====== Performing focaled version GWAS-xQTL ColocBoost on" , length(Y ), " contexts and " , current_study , " GWAS. =====" ))
521555 dict <- dict_sumstatLD [i_gwas , ]
556+ # Validate this study before calling colocboost
557+ ld_idx <- dict [2 ]
558+ ld_matrix <- if (! is.na(ld_idx )) LD_mat [[ld_idx ]] else NULL
559+ valid <- is_valid_sumstat_entry(sumstats [[dict [1 ]]], ld_matrix )
560+ if (! isTRUE(valid )) {
561+ message(paste(" Skipping" , current_study , " due to invalid N/z/LD." ))
562+ next
563+ }
564+ message(paste(" ====== Performing focaled version GWAS-xQTL ColocBoost on" , length(Y ), " contexts and " , current_study , " GWAS. =====" ))
522565 traits <- c(names(Y ), current_study )
523- res_gwas_separate [[current_study ]] <- colocboost(
524- X = X , Y = Y , sumstat = sumstats [dict [1 ]],
525- LD = LD_mat [dict [2 ]], dict_YX = dict_YX ,
526- outcome_names = traits , focal_outcome_idx = length(traits ),
527- output_level = 2 , ...
528- )
566+
567+ # Try to run colocboost with error handling
568+ tryCatch({
569+ res_gwas_separate [[current_study ]] <- colocboost(
570+ X = X , Y = Y , sumstat = sumstats [dict [1 ]],
571+ LD = LD_mat [dict [2 ]], dict_YX = dict_YX ,
572+ outcome_names = traits , focal_outcome_idx = length(traits ),
573+ output_level = 2 , ...
574+ )
575+ }, error = function (e ) {
576+ message(paste(" Error in colocboost analysis for" , current_study , " :" ))
577+ message(paste(" Error message:" , e $ message ))
578+ message(paste(" Continuing with next GWAS..." ))
579+ res_gwas_separate [[current_study ]] <<- NULL
580+ })
529581 }
530582 t32 <- Sys.time()
531583 analysis_results $ separate_gwas <- res_gwas_separate
0 commit comments