@@ -822,7 +822,8 @@ quantile_twas_weight_pipeline <- function(X, Y, Z = NULL, maf = NULL, region_id
822822 xi_tau_range = seq(0.1 , 0.9 , by = 0.05 ),
823823 keep_variants = NULL ,
824824 marginal_beta_calculate = TRUE ,
825- twas_weight_calculate = TRUE ) {
825+ twas_weight_calculate = TRUE ,
826+ qrank_screen_calculate = TRUE ) {
826827 # Step 1: vQTL
827828 # Step 1-1: Calculate vQTL rank scores
828829 message(" Step 0: Calculating vQTL rank scores for region " , region_id )
@@ -846,81 +847,105 @@ quantile_twas_weight_pipeline <- function(X, Y, Z = NULL, maf = NULL, region_id
846847 )
847848 message(" vQTL analysis completed. Proceeding to QR screen." )
848849
849- # Step 2: QR screen
850- message(" Starting QR screen for region " , region_id )
851- p.screen <- qr_screen(X = X , Y = Y , Z = Z , tau.list = quantile_qtl_tau_list , screen_threshold = screen_threshold , screen_method = " qvalue" , top_count = 10 , top_percent = 15 )
852- message(paste0(" Number of SNPs after QR screening: " , length(p.screen $ sig_SNP_threshold )))
853- message(" QR screen completed. Screening significant SNPs" )
854850 # Initialize results list
855851 results <- list (
856- qr_screen_pvalue_df = p.screen $ df_result ,
857- vqtl_results = vqtl_results # Include vQTL results
852+ vqtl_results = vqtl_results
858853 )
859- if (screen_significant && length(p.screen $ sig_SNP_threshold ) == 0 ) {
860- results $ message <- paste0(" No significant SNPs detected in region " , region_id )
861- return (results )
862- }
863854
864- if (screen_significant ) {
865- X_filtered <- X [, p.screen $ sig_SNP_threshold , drop = FALSE ]
866- } else {
867- X_filtered <- X
868- }
855+ if (qrank_screen_calculate ) {
856+ # Step 2: QR screen
857+ message(" Starting QR screen for region " , region_id )
858+ p.screen <- qr_screen(X = X , Y = Y , Z = Z , tau.list = quantile_qtl_tau_list , screen_threshold = screen_threshold , screen_method = " qvalue" , top_count = 10 , top_percent = 15 )
859+ message(paste0(" Number of SNPs after QR screening: " , length(p.screen $ sig_SNP_threshold )))
860+ message(" QR screen completed. Screening significant SNPs" )
861+ results $ qr_screen_pvalue_df <- p.screen $ df_result
862+
863+ if (screen_significant && length(p.screen $ sig_SNP_threshold ) == 0 ) {
864+ results $ message <- paste0(" No significant SNPs detected in region " , region_id )
865+ return (results )
866+ }
867+
868+ if (screen_significant ) {
869+ X_filtered <- X [, p.screen $ sig_SNP_threshold , drop = FALSE ]
870+ } else {
871+ X_filtered <- X
872+ }
873+
874+ # # Step 3: Optional LD clumping and pruning from results of QR_screen (using original QR screen results)
875+ if (ld_clumping ) {
876+ message(" Performing LD clumping and pruning from QR screen results..." )
877+ LD_SNPs <- multicontext_ld_clumping(X = X [, p.screen $ sig_SNP_threshold , drop = FALSE ], qr_results = p.screen , maf_list = NULL )
878+ selected_snps <- if (ld_pruning ) LD_SNPs $ final_SNPs else LD_SNPs $ clumped_SNPs
879+ x_clumped <- X [, p.screen $ sig_SNP_threshold , drop = FALSE ][, selected_snps , drop = FALSE ]
880+ } else {
881+ message(" Skipping LD clumping." )
882+ }
869883
870- # # Step 3: Optional LD clumping and pruning from results of QR_screen (using original QR screen results)
871- if (ld_clumping ) {
872- message(" Performing LD clumping and pruning from QR screen results..." )
873- LD_SNPs <- multicontext_ld_clumping(X = X [, p.screen $ sig_SNP_threshold , drop = FALSE ], qr_results = p.screen , maf_list = NULL )
874- selected_snps <- if (ld_pruning ) LD_SNPs $ final_SNPs else LD_SNPs $ clumped_SNPs
875- x_clumped <- X [, p.screen $ sig_SNP_threshold , drop = FALSE ][, selected_snps , drop = FALSE ]
876884 } else {
877- message(" Skipping LD clumping ." )
885+ message(" Skipping QR screen ." )
878886 }
879887
880888 # Determine whether to skip marginal beta calculation:
881889 # - skip if marginal_beta_calculate = FALSE
882890 # - skip if keep_variants is provided but empty (length 0)
891+ # - skip if qrank_screen_calculate = FALSE and keep_variants is NULL (no variants to select)
883892 skip_marginal_beta <- ! marginal_beta_calculate ||
884- (! is.null(keep_variants ) && length(keep_variants ) == 0 )
893+ (! is.null(keep_variants ) && length(keep_variants ) == 0 ) ||
894+ (! qrank_screen_calculate && is.null(keep_variants ))
885895
886896 if (! skip_marginal_beta ) {
887- # Step 4: Fit marginal QR to get beta with SNPs for quantile_qtl_tau_list values
888- message(" Fitting marginal QR for selected SNPs..." )
889- X_for_qr <- if (ld_clumping ) x_clumped else X_filtered
890- if (! is.null(keep_variants )) {
891- variants_to_keep <- intersect(keep_variants , colnames(X_for_qr ))
892- if (length(variants_to_keep ) > 0 ) {
893- X_for_qr <- X_for_qr [, variants_to_keep , drop = FALSE ]
894- message(" Filtered to " , ncol(X_for_qr ), " variants from keep_variants list for QR analysis" )
897+ # Step 4: Fit marginal QR to get beta with SNPs for quantile_qtl_tau_list values
898+ message(" Fitting marginal QR for selected SNPs..." )
899+ if (qrank_screen_calculate ) {
900+ X_for_qr <- if (ld_clumping ) x_clumped else X_filtered
901+ if (! is.null(keep_variants )) {
902+ variants_to_keep <- intersect(keep_variants , colnames(X_for_qr ))
903+ if (length(variants_to_keep ) > 0 ) {
904+ X_for_qr <- X_for_qr [, variants_to_keep , drop = FALSE ]
905+ message(" Filtered to " , ncol(X_for_qr ), " variants from keep_variants list for QR analysis" )
906+ } else {
907+ message(" Warning: No variants from keep_variants found in selected SNPs, using all selected SNPs" )
908+ }
909+ }
895910 } else {
896- message(" Warning: No variants from keep_variants found in selected SNPs, using all selected SNPs" )
911+ # qrank_screen_calculate = FALSE but keep_variants provided
912+ variants_to_keep <- intersect(keep_variants , colnames(X ))
913+ if (length(variants_to_keep ) > 0 ) {
914+ X_for_qr <- X [, variants_to_keep , drop = FALSE ]
915+ message(" Using " , ncol(X_for_qr ), " variants from keep_variants list for QR analysis (QR screen skipped)" )
916+ } else {
917+ message(" Warning: No variants from keep_variants found in X, skipping marginal beta calculation" )
918+ skip_marginal_beta <- TRUE
919+ }
897920 }
898921 }
899- rq_coef_result <- perform_qr_analysis(X = X_for_qr , Y = Y , Z = Z , tau_values = quantile_qtl_tau_list )
900922
901- # Step 5: Heterogeneity calculation
902- # Step 5-1: beta_heterogeneity index in marginal model
903- message(" Marginal QR for selected SNPs completed. Calculating beta heterogeneity..." )
904- beta_heterogeneity <- calculate_coef_heterogeneity(rq_coef_result )
905- message(" Beta heterogeneity calculation completed." )
923+ if (! skip_marginal_beta ) {
924+ rq_coef_result <- perform_qr_analysis(X = X_for_qr , Y = Y , Z = Z , tau_values = quantile_qtl_tau_list )
925+
926+ # Step 5: Heterogeneity calculation
927+ # Step 5-1: beta_heterogeneity index in marginal model
928+ message(" Marginal QR for selected SNPs completed. Calculating beta heterogeneity..." )
929+ beta_heterogeneity <- calculate_coef_heterogeneity(rq_coef_result )
930+ message(" Beta heterogeneity calculation completed." )
906931
907- # Step 5-2: Calculate xi correlation (Chatterjee correlation test)
908- message(" Calculating xi correlation for QR coefficients..." )
909- xi_correlation <- calculate_xi_correlation(rq_coef_result , tau_range = xi_tau_range , min_valid = 10 )
910- message(" Xi correlation calculation completed." )
932+ # Step 5-2: Calculate xi correlation (Chatterjee correlation test)
933+ message(" Calculating xi correlation for QR coefficients..." )
934+ xi_correlation <- calculate_xi_correlation(rq_coef_result , tau_range = xi_tau_range , min_valid = 10 )
935+ message(" Xi correlation calculation completed." )
911936
912- # Merge xi and xi_pval into rq_coef_result (using left_join to preserve row order)
913- rq_coef_result <- rq_coef_result %> %
914- dplyr :: left_join(xi_correlation , by = " variant_id" )
937+ # Merge xi and xi_pval into rq_coef_result (using left_join to preserve row order)
938+ rq_coef_result <- rq_coef_result %> %
939+ dplyr :: left_join(xi_correlation , by = " variant_id" )
915940
916- results $ rq_coef_df <- rq_coef_result
917- results $ beta_heterogeneity <- beta_heterogeneity
941+ results $ rq_coef_df <- rq_coef_result
942+ results $ beta_heterogeneity <- beta_heterogeneity
918943 results $ xi_correlation <- xi_correlation
919944 } else {
920945 message(" Skipping marginal beta calculation and heterogeneity analysis." )
921946 }
922947
923- if (twas_weight_calculate ) {
948+ if (twas_weight_calculate && qrank_screen_calculate ) {
924949 # Step 6: Optional LD panel filtering and MAF filtering from results of QR_screen
925950 if (! is.null(ld_reference_meta_file )) {
926951 message(" Starting LD panel filtering..." )
0 commit comments