Pairwise colocalization with colocPipeline
pecotmr authors
2026-07-21
Source:vignettes/coloc-pipeline.Rmd
coloc-pipeline.RmdOverview
colocPipeline() runs pairwise QTL ↔︎ GWAS colocalization
using coloc::coloc.bf_bf on the SuSiE log Bayes-factor
(LBF) matrices carried by each fine-mapping entry. For multi-trait
colocalization across many QTL outcomes in one model, use colocboostPipeline
instead.
Inputs:
-
QTL input — a
QtlFineMappingResultproduced byfineMappingPipeline. -
GWAS input — either a
GwasSumStats(fine-mapping run internally) or aGwasFineMappingResult(used directly).
The output is a long-format data frame with one row per
(QTL tuple, GWAS tuple, credible-set pair) combination and
the standard coloc posterior columns PP.H0.abf …
PP.H4.abf.
Bundled inputs
data(qtl_dataset_example, gwas_sumstats_s4_example)
# Build a QtlFineMappingResult from the bundled QtlDataset.
qtlFmr <- fineMappingPipeline(qtl_dataset_example, methods = "susie",
cisWindow = 1e6)QTL FMR + GWAS sumstats (inline GWAS fine-mapping)
The recommend approach is to provide colocPipeline() a
QtlFineMappingResult and a GwasSumStats. The
pipeline runs fineMappingPipeline() internally on the GWAS
sumstats (with finemappingMethods) over the exact window
used in the QtlFineMappingResult, then runs
coloc.bf_bf per (QTL, GWAS) pair.
res <- colocPipeline(
qtlFineMappingResult = qtlFmr,
gwasInput = gwas_sumstats_s4_example,
finemappingMethods = "susie")
head(res)## study context trait method gwasStudy gwasMethod nsnps
## 1 study1 brain ENSG_example susie trait1 susie 198
## 2 study1 brain ENSG_example susie trait1 susie 198
## 3 study1 brain ENSG_example susie trait1 susie 198
## 4 study1 brain ENSG_example susie trait1 susie 198
## 5 study1 brain ENSG_example susie trait1 susie 198
## 6 study1 brain ENSG_example susie trait1 susie 198
## hit1 hit2 PP.H0.abf PP.H1.abf PP.H2.abf
## 1 chr22:15611133:C:G chr22:15698333:A:G 0 0 0.83948430
## 2 chr22:15611133:C:G chr22:15570730:C:T 0 0 0.07236177
## 3 chr22:15611133:C:G chr22:15567276:C:T 0 0 0.08044104
## 4 chr22:15611133:C:G chr22:15569194:A:G 0 0 0.07556434
## 5 chr22:15611133:C:G chr22:15567276:C:T 0 0 0.08044104
## 6 chr22:15611133:C:G chr22:15776459:C:T 0 0 0.82919861
## PP.H3.abf PP.H4.abf idx1 idx2 nSnps
## 1 0.14897480 0.01154090 1 1 NA
## 2 0.01101005 0.91662818 1 2 NA
## 3 0.01246308 0.90709588 1 3 NA
## 4 0.01158602 0.91284964 1 4 NA
## 5 0.01246308 0.90709588 1 5 NA
## 6 0.14712494 0.02367645 1 6 NA
Use returnGwasFineMapping = TRUE to get the inline GWAS
FMR back as an attribute on the result:
res2 <- colocPipeline(
qtlFineMappingResult = qtlFmr,
gwasInput = gwas_sumstats_s4_example,
returnGwasFineMapping = TRUE)
attr(res2, "gwasFineMapping")If the QTL FineMappingResult has an LD sketch because it
was run on summary statistics it must match the LD sketch for the
GWASSumStats.
QTL FMR + pre-computed GWAS FMR
If you already have a GwasFineMappingResult (typically
computed over LD blocks), you can use that fine-mapping result
directly:
gwasFmr <- fineMappingPipeline(gwas_sumstats_s4_example, methods = "susie")
colocPipeline(qtlFineMappingResult = qtlFmr,
gwasInput = gwasFmr)The disadvantage of this approach is that LD blocks will not align with cis-QTL windows. Ultimately this means that the variable selection in the QTL and GWAS fine-mapping will have been done over different variant sets, which may reduce the sensitivity for colocalizations, particuarly in areas with complex LD.
Filtering effects fed into coloc
coloc::coloc.bf_bf accepts one LBF matrix for the QTL
and one for hte GWAS. By default, every effect with non-trivial prior
variance (V > priorTol) gets included. Two opt-in
filters can adjust this:
| Filter | Description | Default |
|---|---|---|
filterLbfCs |
TRUE keeps only effects that produced a credible set
(trimmedFit$sets$cs_index). |
FALSE |
filterLbfCsSecondary |
Numeric coverage in (0,1). Runs a CS-concentration filter at that coverage. | NULL |
filterLbfCsConcentration |
Numeric in (0,1). Concentration factor: a CS at coverage X is kept
only if it spans fewer than nVariants * X * concentration
variants. |
0.5 |
priorTol |
Drop effects whose estimated prior variance is at or below this threshold. | 1e-9 |
colocPipeline(
qtlFineMappingResult = qtlFmr,
gwasInput = gwas_sumstats_s4_example,
filterLbfCsSecondary = 0.5, # 50% CS concentration filter
filterLbfCsConcentration = 0.5) # span < 25% of locus variantsEnrichment-aware coloc (enloc mode)
Pass a per-(gwasStudy, qtlContext) enrichment table (the
output of qtlEnrichmentPipeline()) to scale the
shared-signal prior:
p_{12}^{\text{used}} = \min\bigl(p_{12}\,(1 + \text{enrichment}),\, p_{12,\max}\bigr)
Pairs without a matching enrichment row fall back to the baseline
p12 with a warning. Two extra columns are added to the
output: enrichment (the lookup) and p12Used
(what was actually passed to coloc.bf_bf).
enrichmentTable <- data.frame(
gwasStudy = "trait1",
qtlContext = "brain",
enrichment = 2.5,
stringsAsFactors = FALSE)
colocPipeline(
qtlFineMappingResult = qtlFmr,
gwasInput = gwas_sumstats_s4_example,
enrichment = enrichmentTable,
p12Max = 1e-3)PIP renormalization on variant intersection
When the QTL and GWAS fine-mapping results were fit on different
variant sets (common when the user declines RAISS imputation, or when
the GWAS FMR carries variants the QTL FMR doesn’t),
adjustPips = TRUE (default) renormalizes the PIPs for each
objectl to the cross-FMR variant intersection before any per-pair
inference. Pass FALSE to use the FMRs as supplied.
colocPipeline(
qtlFineMappingResult = qtlFmr,
gwasInput = gwas_sumstats_s4_example,
adjustPips = TRUE) # defaultCommon parameters
colocPipeline(
qtlFineMappingResult = qtlFmr,
gwasInput = gwas_sumstats_s4_example,
filterLbfCs = FALSE,
filterLbfCsSecondary = NULL, # e.g. 0.5
filterLbfCsConcentration = 0.5,
priorTol = 1e-9,
p1 = 1e-4,
p2 = 1e-4,
p12 = 5e-6,
finemappingMethods = "susie", # inline GWAS FM when needed
returnGwasFineMapping = FALSE,
enrichment = NULL, # data.frame for enloc mode
p12Max = 1e-3,
adjustPips = TRUE)Reading the result
str(res, max.level = 1L)## 'data.frame': 20 obs. of 17 variables:
## $ study : chr "study1" "study1" "study1" "study1" ...
## $ context : chr "brain" "brain" "brain" "brain" ...
## $ trait : chr "ENSG_example" "ENSG_example" "ENSG_example" "ENSG_example" ...
## $ method : chr "susie" "susie" "susie" "susie" ...
## $ gwasStudy : chr "trait1" "trait1" "trait1" "trait1" ...
## $ gwasMethod: chr "susie" "susie" "susie" "susie" ...
## $ nsnps : int 198 198 198 198 198 198 198 198 198 198 ...
## $ hit1 : chr "chr22:15611133:C:G" "chr22:15611133:C:G" "chr22:15611133:C:G" "chr22:15611133:C:G" ...
## $ hit2 : chr "chr22:15698333:A:G" "chr22:15570730:C:T" "chr22:15567276:C:T" "chr22:15569194:A:G" ...
## $ PP.H0.abf : num 0 0 0 0 0 0 0 0 0 0 ...
## $ PP.H1.abf : num 0 0 0 0 0 0 0 0 0 0 ...
## $ PP.H2.abf : num 0.8395 0.0724 0.0804 0.0756 0.0804 ...
## $ PP.H3.abf : num 0.149 0.011 0.0125 0.0116 0.0125 ...
## $ PP.H4.abf : num 0.0115 0.9166 0.9071 0.9128 0.9071 ...
## $ idx1 : int 1 1 1 1 1 1 1 1 1 1 ...
## $ idx2 : int 1 2 3 4 5 6 7 8 9 10 ...
## $ nSnps : logi NA NA NA NA NA NA ...
## study context trait method gwasStudy gwasMethod nsnps
## 2 study1 brain ENSG_example susie trait1 susie 198
## 4 study1 brain ENSG_example susie trait1 susie 198
## 7 study1 brain ENSG_example susie trait1 susie 198
## 3 study1 brain ENSG_example susie trait1 susie 198
## 5 study1 brain ENSG_example susie trait1 susie 198
## 10 study1 brain ENSG_example susie trait1 susie 198
## hit1 hit2 PP.H0.abf PP.H1.abf PP.H2.abf
## 2 chr22:15611133:C:G chr22:15570730:C:T 0 0 0.07236177
## 4 chr22:15611133:C:G chr22:15569194:A:G 0 0 0.07556434
## 7 chr22:15611133:C:G chr22:15569194:A:G 0 0 0.07556434
## 3 chr22:15611133:C:G chr22:15567276:C:T 0 0 0.08044104
## 5 chr22:15611133:C:G chr22:15567276:C:T 0 0 0.08044104
## 10 chr22:15611133:C:G chr22:15567276:C:T 0 0 0.08044104
## PP.H3.abf PP.H4.abf idx1 idx2 nSnps
## 2 0.01101005 0.9166282 1 2 NA
## 4 0.01158602 0.9128496 1 4 NA
## 7 0.01158602 0.9128496 1 7 NA
## 3 0.01246308 0.9070959 1 3 NA
## 5 0.01246308 0.9070959 1 5 NA
## 10 0.01246308 0.9070959 1 10 NA
Each row is one CS-pair combination; in particular the
idx1 / idx2 columns identify the QTL / GWAS
effect indices within the respective LBF matrices, and
PP.H4.abf is the standard coloc shared-signal
posterior.