---
title: "Case study: colocalization analysis in prostate cancer"
date: "2022-06-08"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Colocalization_analysis_with_xQTLbiolinks}
  %\VignetteEncoding{UTF-8}
  %\VignetteEngine{knitr::rmarkdown}
link-citations: true
lang: en-US
bibliography: references.bib
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  echo=TRUE,
  progress =FALSE,
  comment = "#>"
)
```

## Before we start.

All we need to prepare include three parts:

1.  GWAS summary statistics dataset.
2.  Name of tissue of interest.
3.  Following three installed packages.

```{r, results = 'hide', echo=TRUE, message=FALSE, warning=FALSE, eval=TRUE}
library(data.table)
library(xQTLbiolinks)
library(stringr)
```

Prostate cancer is one of the most common cancers in men. Prostate cancer pathogenesis involves both heritable and environmental factors. The molecular events involved in the development or progression of prostate cancer are still unclear. In this example, we aim to figure out the causal variants and genes assocaited with prostate cancer, and to uncover potential molecular mechanisms of regulation.

For data preparation, we download summary statistics dataset of a GWAS study ([GCST006085](http://ftp.ebi.ac.uk/pub/databases/gwas/summary_statistics/GCST006001-GCST007000/GCST006085/harmonised/29892016-GCST006085-EFO_0001663-build37.f.tsv.gz)) of prostate cancer from GWAS category and load the dataset in R with `data.table` package. Correspondingly, we chose tissue `Prostate` for study. We retain the variants with dbSNP id (start with `rs`), and a data.table object named `gwasDF` of 13,498,990 (rows) x 7 (cols) is loaded.

```{r, results = 'hide', echo=TRUE, message=FALSE, warning=FALSE, eval=FALSE}
gwasDF <- fread("29892016-GCST006085-EFO_0001663-build37.f.tsv.gz")
# extract columns.
gwasDF<- gwasDF[str_detect(variant_id, "^rs"),.(rsid=variant_id, chrom=chromosome, position= base_pair_location, pValue=p_value, AF=effect_allele_frequency, beta, se= standard_error)]
# tissue:
tissueSiteDetail="Prostate"
```

```{r, message=FALSE, warning=FALSE, include=FALSE}
gwasDF <- example_Coloc_gwasDF
```

```{r, eval=TRUE}
head(gwasDF)
```

## Step 1: Filter sentinel snps.

Sentinel SNP is the most prominent signal within a given genome range, and is usually in high LD with causal variants. By default, xQTLbiolinks detect sentinel snps that with the p-value \< 5e-8 and SNP-to-SNP distance \> 10e6 bp. **Note**: For in this example, due to the inconsistent genome version between the GWAS dataset (GRCh37) and eQTL associations (GRCh38) from eQTL category, conversion of genome version is required, and can be conducted using `xQTLanalyze_getSentinelSnp` with `genomeVersion="grch37"` and `grch37To38=TRUE` (package `rtracklayer`is required):

```{r, results = 'hide', echo=TRUE, message=FALSE, warning=FALSE, eval=FALSE}
sentinelSnpDF <- xQTLanalyze_getSentinelSnp(gwasDF, centerRange=1e6,
                                            genomeVersion="grch37", grch37To38=TRUE)
```

```{r, message=FALSE, warning=FALSE, include=FALSE}
sentinelSnpDF <- example_Coloc_sentinelSNP
```

A total of 94 sentinel SNPs are detected.

```{r, eval=TRUE}
head(sentinelSnpDF)
```

## Step 2: Identify trait genes for each sentinel SNPs.

Trait genes are genes that located in the range of 1Mb (default, can be changed with parameter `detectRange`) of sentinel SNPs. In order to reduce the number of trait genes and thus reduce the running time, we take the overlap of eGenes and trait genes as the final output of the function `xQTLanalyze_getTraits`:

```{r, results = 'hide', echo=TRUE, message=FALSE, warning=FALSE, eval=FALSE}
traitsAll <- xQTLanalyze_getTraits(sentinelSnpDF, detectRange=1e6, tissueSiteDetail=tissueSiteDetail)
```

Totally, 898 associations between 835 traits genes and 92 sentinel SNPs are detected

```{r, message=FALSE, warning=FALSE, include=FALSE}
tissueSiteDetail="Prostate"
traitsAll <- example_Coloc_traitsAll
```

```{r, eval=TRUE}
head(example_Coloc_traitsAll)
```

## Step 3: Conduct colocalization analysis.

Following three steps of colocalization analysis are encapsulated in one function xQTLanalyze_coloc:

1.  Retrieved all associations from EBI eQTL catalogue for a specified gene.
2.  Merge the data.frame of GWAS and eQTL by rsid.
3.  Perform colocalization analysis using `coloc` and `hyprcoloc` methods.

For above 835 trait genes, a for loop can be used to get these genes' outputs of colocalization analysis (this may take several hours):

```{r, results = 'hide', echo=TRUE, message=FALSE, warning=FALSE, eval=FALSE}
genesAll<- unique(traitsAll$gencodeId)
colocResultAll <- data.table()
# 162 575 error
for(i in 1:length(genesAll)){
  colocResult <- xQTLanalyze_coloc(gwasDF, 
                                   genomeVersion = "grch37", method="Both",
                                   genesAll[i], tissueSiteDetail=tissueSiteDetail)
  if(!is.null(colocResult)){ colocResultAll <- rbind(colocResultAll, colocResult$colocOut)}
  message(format(Sys.time(), "== %Y-%b-%d %H:%M:%S ")," == Id:",i,"/",length(genesAll)," == Gene:",genesAll[i])
}
```

```{r, message=FALSE, warning=FALSE, include=FALSE}
colocResultAll <- example_Coloc_colocResultAll
```


In this case, we invoke two methods to conduct colocalization analysis, (1). `coloc` that estimates the posterior support of variants for each hypothesis: H0,H1,H2,H3,H4:

-   H0 : neither trait has a genetic association in the region
-   H1: only trait 1 has a genetic association in the region
-   H2: only trait 2 has a genetic association in the region
-   H3: both traits are associated, but with different causal variants
-   H4: both traits are associated and share a single causal variant

and (2). `hyprcoloc` that calculates the posterior probability that all traits share a causal variant.

Output is a data.table object that combined all results of `colocOut` of all genes. 

```{r, eval=TRUE}
head(colocResultAll)
```

We can see that the two methodologies' outcomes are quite consistent. With a threshold of 0.75 for `coloc` and 0.5 for `hyprcoloc`, a total of 24 colocalized genes are shared.

```{r, results = 'hide', echo=TRUE, message=FALSE, warning=FALSE, eval=FALSE}
library(VennDiagram)
T <- venn.diagram( list(colocOut = colocResultAll[PP.H4.abf>=0.75]$traitGene, 
                   hyprcolocOut = colocResultAll[hypr_posterior>=0.5]$traitGene),
                   filename = NULL,lwd=1,lty=1, width = 8000, height = 10000,
                   fill=c('#ff7a45','#597ef7'), col=c('red','blue'), cat.col=c('red','blue'),
                   main.cex = 0.45, sub.cex= 0.1,
                   disable.logging = TRUE)
grid.draw(T)
```

```{r, venn_coloc_hyprcoloc, fig.align = 'center', out.width = "30%", echo=FALSE}
# knitr::include_graphics("images/prostate/venn_coloc_hyprcoloc.png", error = FALSE)
```


To save time and go through this case as soon as possible, you can get the above result directly with:

```{r, results = 'hide', echo=TRUE, message=FALSE, warning=FALSE, eval=FALSE}
colocResultAll <- fread("https://raw.githubusercontent.com/dingruofan/exampleData/master/colocResultAll.txt")
```

## Step 4: Visualization of the results.

We considered colocalization tests with a posterior probability of hypothesis 4 (PPH4.ABF) > 0.75 & hypr_posterior > 0.5 as having strong or moderate evidence for colocalization.

```{r, message=FALSE, warning=FALSE, include=FALSE}
colocResultsig <- example_Coloc_colocResultsig
```

```{r, results = 'hide', echo=TRUE, message=FALSE, warning=FALSE, eval=FALSE}
colocResultsig <- colocResultAll[PP.H4.abf>0.75 & hypr_posterior>0.5][order(-PP.H4.abf)]
```

There are 24 trait genes that are associated and share a single causal variant:

```{r, eval=TRUE}
head(colocResultsig)
```

All these genes' details can be fetched with `xQTLquery_gene`:

```{r eval=TRUE, message=FALSE}
outGenes <- xQTLquery_gene(colocResultsig$traitGene)
```

Add the value of PPH4 for each gene, and remove non-protein-coding genes:

```{r, eval=TRUE}
outGenes <- merge(colocResultsig[,.(gencodeId= traitGene, PP.H4.abf, candidate_snp, SNP.PP.H4, hypr_posterior)], 
                  outGenes[,.(geneSymbol, gencodeId, entrezGeneId, geneType)], by="gencodeId", sort=FALSE)
outGenes <- outGenes[geneType =="protein coding"]
```

```{r, eval=TRUE}
outGenes
```

Ridgeline plot can be used to compare the expressions among these genes:

```{r, results = 'hide', echo=TRUE, message=FALSE, warning=FALSE, eval=FALSE}
xQTLvisual_genesExp(outGenes$geneSymbol, tissueSiteDetail=tissueSiteDetail)
```


```{r, prostate_geneExpInOneTissue.png, fig.align = 'center', out.width = "50%", echo=FALSE}
# knitr::include_graphics("images/prostate/prostate_geneExpInOneTissue.png", error = FALSE)
```



Trait gene **`MMP7`** that with the highest `PPH4.ABF=0.9978` & `hypr_posterior=0.9993` encodes a member of the peptidase M10 family of matrix metalloproteinases, which is involved in the breakdown of extracellular matrix in normal physiological processes, such as embryonic development, reproduction, and tissue remodeling, as well as in disease processes, such as arthritis and metastasis [@RefSeq]. Prostate cancer can be promoted via MMP7-induced epithelial-to-mesenchymal transition by Interleukin-17 [@zhang2017]. Resent literature has shown that serum MMP7 levels could guide metastatic therapy for prostate cancer [@tregunna2020].

Expression of MMP7 in multiple tissues can be plotted with `xQTLvisual_geneExpTissues`:

```{r, results = 'hide', echo=TRUE, message=FALSE, warning=FALSE, eval=FALSE}
geneExpTissues <- xQTLvisual_geneExpTissues("MMP7", log10y = TRUE)
```

```{r, prostate_exp_multissues.png, fig.align = 'center', out.width = "90%", echo=FALSE}
# knitr::include_graphics("images/prostate/prostate_exp_multissues.png")
```

The number and significance of eQTLs in distinguished tissues are capable of showing a tissue-specific effect or a ubiquitous effect. The function `xQTLvisual_eqtl` can be used to indicate whether the gene is widely regulation in various tissues.

```{r, results = 'hide', echo=TRUE, message=FALSE, warning=FALSE, eval=FALSE}
xQTLvisual_eqtl("MMP7")
```

```{r, prostate_eqtlTissues.png, fig.align = 'center', out.width = "90%", echo=FALSE}
# knitr::include_graphics("images/prostate/prostate_eqtlTissues.png")
```

Besides, we provide functions `xQTLvisual_locusCompare` and `xQTLvisual_locusZoom` to visualize the colocalization between the GWAS and the eQTL dataset for a specified gene, we take the gene `MMP7` as an example:

```{r, message=FALSE, warning=FALSE, include=FALSE}
t1 <- tempfile()
utils::download.file("https://raw.githubusercontent.com/dingruofan/exampleData/master/gwasEqtldata.txt", t1)
gwasEqtldata <- data.table::fread(t1)
close(file(t1))
rm(t1)
```

```{r, results = 'hide', echo=TRUE, message=FALSE, warning=FALSE, eval=FALSE}
# Download all eQTL associations of gene  MMP7 in prostate:
eqtlAsso <- xQTLdownload_eqtlAllAsso(gene="MMP7",tissueLabel = tissueSiteDetail)
# Merge the variants of GWAS and eQTL dataset by rsid:
gwasEqtldata <- merge(gwasDF[,-c("AF")], eqtlAsso[,.(rsid=snpId, pValue)],
                      by=c("rsid"), suffixes = c(".gwas",".eqtl"))
```

Five retained fields are required:

```{r, eval=TRUE}
gwasEqtldata
```

Visualization of p-value distribution and comparison of the signals of GWAS and eQTL:

```{r, results = 'hide', echo=TRUE, message=FALSE, warning=FALSE, eval=FALSE}
xQTLvisual_locusCompare(gwasEqtldata[,.(rsid, pValue.eqtl)], 
                        gwasEqtldata[,.(rsid, pValue.gwas)], legend_position = "bottomright")
```

```{r, prostate_locuscompare.png, fig.align = 'center', out.width = "50%", echo=FALSE}
# knitr::include_graphics("images/prostate/prostate_locuscompare.png")
```

Locuszoom plot of GWAS signals:

```{r, results = 'hide', echo=TRUE, message=FALSE, warning=FALSE, eval=FALSE}
xQTLvisual_locusZoom(gwasEqtldata[,.(rsid, chrom, position, pValue.gwas)], legend=FALSE)
```

```{r, prostate_locuszoom_gwas.png, fig.align = 'center', out.width = "50%", echo=FALSE}
# knitr::include_graphics("images/prostate/prostate_locuszoom_gwas.png")
```

Locuszoom plot of eQTL signals:

```{r, results = 'hide', echo=TRUE, message=FALSE, warning=FALSE, eval=FALSE}
xQTLvisual_locusZoom(gwasEqtldata[,.(rsid, chrom, position, pValue.eqtl)], legend=FALSE)
```

```{r, prostate_locuszoom_eqtl.png, fig.align = 'center', out.width = "50%", echo=FALSE}
# knitr::include_graphics("images/prostate/prostate_locuszoom_eqtl.png")
```

We can also combine locuscompare and locuszoom plot using function `xQTLvisual_locusCombine`:

```{r, results = 'hide', echo=TRUE, message=FALSE, warning=FALSE, eval=FALSE}
xQTLvisual_locusCombine(gwasEqtldata[,c("rsid","chrom", "position", "pValue.gwas", "pValue.eqtl")])
```

```{r, prostate_combined.png, fig.align = 'center', out.width = "90%", echo=FALSE}
# knitr::include_graphics("images/prostate/prostate_combined.png")
```

From the above figures, we can see that the SNP `rs11568818` is potential causal variant, and we can use a violin plot to show the normalized effect size of it:

```{r, results = 'hide', echo=TRUE, message=FALSE, warning=FALSE, eval=FALSE}
xQTLvisual_eqtlExp("rs11568818", "MMP7", tissueSiteDetail = tissueSiteDetail)
```

```{r, prostate_eQTL_exp.png, fig.align = 'center', out.width = "40%", echo=FALSE}
# knitr::include_graphics("images/prostate/prostate_eQTL_exp.png")
```

## Extension: Integrative analysis with external packages or tools

To gain insight into the function of trait genes with higher PPH4, and explore the potential regulatory mechanism of the prostate cancer, we can conduct exploratory analysis, like co-expression analysis, and gene ontology enrichment analyses.

First we download expression profiles of the genes with higher value of PPH4 (>0.75) & hypr_posterior (>0.5) in prostate.

```{r, results = 'hide', echo=TRUE, message=FALSE, warning=FALSE, eval=FALSE}
expMat <- xQTLdownload_exp(outGenes$gencodeId, tissueSiteDetail=tissueSiteDetail, toSummarizedExperiment =FALSE)
```

Pearson coefficient can be calculated with the expression matrix for each gene:

```{r, results = 'hide', echo=TRUE, message=FALSE, warning=FALSE, eval=FALSE}
corDT <- cor(t(expMat[,-1:-7]))
colnames(corDT) <- outGenes$geneSymbol
rownames(corDT) <- outGenes$geneSymbol
```

R package `corrplot` is used to display this correlation matrix:

```{r, results = 'hide', echo=TRUE, message=FALSE, warning=FALSE, eval=FALSE}
library(corrplot) 
corrplot(corDT, method="color",  
         type="upper",    
         order = "hclust",
         addCoef.col = "#ff0099", 
         number.cex = 0.7) 
```

```{r, prostate_cor.png, fig.align = 'center', out.width = "90%", echo=FALSE}
# knitr::include_graphics("images/prostate/prostate_cor.png")
```

R package `clusterProfiler` is used for gene functional annotation:

```{r, results = 'hide', echo=TRUE, message=FALSE, warning=FALSE, eval=FALSE}
library(clusterProfiler)
library(org.Hs.eg.db)
ego <- enrichGO(gene = as.character(outGenes$entrezGeneId),
                OrgDb = org.Hs.eg.db,
                ont= "BP",
                pAdjustMethod ="none",
                readable = TRUE)
dotplot(ego, showCategory=15)
```

```{r, prostate_Go.png, fig.align = 'center', out.width = "80%", echo=FALSE}
# knitr::include_graphics("images/prostate/prostate_Go.png")
```

Viral-related GO terms are enriched in above analysis, including `"viral life cycle"`, `"positive regulation of viral life cycle"` and `"positive regulation of viral process"`. Previous studies have highlighted the role of viral infections in initiation or progression of prostate cancer. The presence of viruses such as human papillomavirus (HPV), herpesviruses including cytomegalovirus (CMV), human herpes simplex virus type 2 (HSV2), human herpesvirus type 8 (HHV8) and Epstein-Barr virus (EBV) can infect the prostate [@abidi2018]. However, the causal variants' genetic effects on the phenotype and whether the trait genes has a direct association with prostate carcinogenesis has not yet been established.

## References
