---
title: "Functional Analysis"
author: "`r getOption('author')`"
date: "`r Sys.Date()`"
bibliography: bibliography.bib
params:
    bcbFile: "data/bcb.rda"
    resFile: "data/res.rda"
    organism: "Mm"
    gspecies: "mmu"
    species: "mouse"
    lfc: 0
    goOnt: "BP"
    outputDir: "."
---

```{r setup, cache=FALSE, message=FALSE}
# Last modified 2017-12-14

# Organism params:
# Mouse (default)
#     organism: "Mm"
#     gspecies: "mmu"
#     species: "mouse"
# Human
#     organism: "Hs"
#     gspecies: "hsa"
#     species: "human"

# Organism database package
# help("enrichGO", "clusterProfiler")
orgDB <- paste("org", params$organism, "eg", "db", sep = ".")

# Load the required libraries
packages <- c(
    orgDB,
    "lpantano/DEGreport",
    "hbc/bcbioRNASeq",
    "tidyverse",
    "DT",
    "clusterProfiler",
    "DOSE",
    "pathview"
)
if (!all(basename(packages) %in% rownames(installed.packages()))) {
    source("https://bioconductor.org/biocLite.R")
    notInstalled <- setdiff(basename(packages), rownames(installed.packages()))
    biocLite(pkgs = notInstalled)
}
invisible(lapply(basename(packages), library, character.only = TRUE))
    
# Shared R Markdown settings
prepareRNASeqTemplate()
if (file.exists("setup.R")) {
    source("setup.R")
}

# Load bcbioRNASeq object
bcbName <- load(params$bcbFile)
bcb <- get(bcbName, inherits = FALSE)

resName <- load(params$resFile)
res <- get(resName, inherits = FALSE) %>%
    .[!is.na(.$padj), , drop = FALSE]
alpha <- metadata(res)$alpha

# Directory paths
dataDir <- file.path(params$outputDir, "data", Sys.Date())
faDir <- file.path(params$outputDir, "results", Sys.Date(), "functional_analysis")
invisible(mapply(
    list(faDir, dataDir),
    FUN = dir.create,
    MoreArgs = list(recursive = TRUE, showWarnings = FALSE)
))
```

```{r header, child="_header.Rmd", eval=file.exists("_header.Rmd")}
```



```{r identifiers, message=FALSE, warning=FALSE}
allGenes <- rownames(res) %>%
    as.character()
sigGenes <- significants(
    res,
    fc = params$lfc,
    padj = alpha)
# Convert Ensembl gene identifiers to Entrez
ensembl2entrez <- bitr(
    allGenes,
    fromType = "ENSEMBL",
    toType = "ENTREZID",
    OrgDb = orgDB) %>%
    camel()
allEntrez <- unique(ensembl2entrez$entrezid)
sigEntrez <- bitr(
    sigGenes,
    fromType = "ENSEMBL",
    toType = "ENTREZID",
    OrgDb = orgDB) %>%
    camel() %>%
    .$entrezid %>%
    unique()
```

```{r sig_tables}
sigResults <- as.data.frame(res)[sigGenes, ]

foldChanges <- sigResults$log2FoldChange
names(foldChanges) <- rownames(sigResults)

fdrOrdered <- res %>%
    as.data.frame() %>%
    .[order(.$padj), ]
```



# GO enrichment analysis

Gene Ontology (GO) term enrichment is a technique for interpreting sets of genes making use of the Gene Ontology system of classification, in which genes are assigned to a set of predefined bins depending on their functional characteristics.

```{r enrich_go}
# Run GO enrichment analysis
ego <- enrichGO(
    sigGenes,
    "ENSEMBL",
    universe = allGenes,
    OrgDb = orgDB,
    ont = params$goOnt,
    pAdjustMethod = "BH",
    qvalueCutoff = 0.05,
    readable = TRUE)
saveData(ego, dir = dataDir)

# Show summary data.frame
egoSummary <- slot(ego, "result") %>%
    as_tibble() %>%
    camel()
write_csv(
    egoSummary,
    path = file.path(
        faDir,
        paste0(
            paste("go",
                  tolower(params$goOnt),
                  "clusterprofiler",
                  "padj",
                  alpha,
                  "lfc",
                  params$lfc,
                  sep = "_"),
            ".csv.gz")))
egoSummary %>% datatable()
```



# DOTplot

```{r dotplot, fig.width=8}
# Dotplot of top 25
dotplot(ego, showCategory = 25)
```



# GO terms map

```{r enrich_map, fig.width=8, fig.height=8}
# Enrichment plot of top 25
enrichMap(ego, n = 25, vertex.label.cex = 0.5)
```



# Gene map

In order to consider the potentially biological complexities in which a gene may belong to multiple annotation categories and provide information of numeric changes if available

```{r cnetplot, fig.width=8, fig.height=8}
# Cnet plot with genes colored by fold changes for top 5 most significant GO
# processes
cnetplot(
    ego,
    categorySize = "pvalue",
    showCategory = 5,
    foldChange = foldChanges,
    vertex.label.cex = 0.5)
```



# KEGG analysis

```{r enrich_kegg}
kegg <- enrichKEGG(
    gene = sigEntrez,
    universe = allEntrez,
    organism = params$species)
saveData(kegg, dir = dataDir)

# Show KEGG summary data.frame
keggSummary <- slot(kegg, "result") %>%
    as_tibble() %>%
    camel()
write_csv(
    keggSummary,
    path = file.path(
        faDir,
        paste0(
            paste(
                "kegg",
                "clusterprofiler",
                "padj",
                alpha,
                "lfc",
                params$lfc,
                sep = "_"),
            ".csv.gz")))
keggSummary %>% datatable()
```



# GO GSEA analysis

A common approach in analyzing gene expression profiles was identifying differential expressed genes that are deemed interesting. The enrichment analysis we demonstrated previously were based on these differentially expressed genes. This approach will find genes where the difference is large, but it will not detect a situation where the difference is small, but evidenced in coordinated way in a set of related genes. Gene Set Enrichment Analysis (GSEA) directly addresses this limitation. All genes can be used in GSEA; GSEA aggregates the per gene statistics across genes within a gene set, therefore making it possible to detect situations where all genes in a predefined set change in a small but coordinated way. Since it is likely that many relevant phenotypic differences are manifested by small but consistent changes in a set of genes.

```{r gse_go}
# Prepare the gene list
geneList <- 1 - fdrOrdered$padj
names(geneList) <- row.names(fdrOrdered)
geneList <- geneList[!is.na(geneList)]

# Now run GSEA
gse <- gseGO(
    geneList = geneList,
    OrgDb = orgDB,
    ont = params$goOnt,
    keyType = "ENSEMBL",
    nPerm = 1000,
    minGSSize = 100,
    maxGSSize = 500,
    pvalueCutoff = 0.05,
    verbose = FALSE)
saveData(gse, dir = dataDir)

# Write out summary data.frame
gseSummary <- slot(gse, "result") %>%
    as_tibble() %>%
    camel()
write_csv(
    gseSummary,
    path = file.path(
        faDir,
        paste0(
            paste(
                "gsea",
                "clusterprofiler",
                "padj",
                alpha,
                "lfc",
                params$lfc,
                sep = "_"),
            ".csv.gz")))
gseSummary %>% datatable()
```



# KEGG GSEA analysis

We can also perform GSEA analysis with clusterProfiler using KEGG gene sets and using the log2 fold changes as input. By using the log2 fold changes as the input, we are identifying pathways with genes that exhibit coordinated fold changes that are larger than might be expected by chance. The significant pathways can be visualized using the log2 fold changes with the Pathview tool.

```{r kegg_gsea}
resTblEntrez <- res %>%
    as.data.frame() %>%
    rownames_to_column("ensembl") %>%
    as_tibble() %>%
    # Use the full join option here to include all Entrez identifiers
    full_join(ensembl2entrez, by = "ensembl") %>%
    dplyr::select(entrezid, ensembl, everything()) %>%
    # Remove rows with duplicate Entrez identifiers
    filter(!duplicated(entrezid))

# Extract the fold changes
foldChanges <- resTblEntrez$log2FoldChange
names(foldChanges) <- resTblEntrez$entrezid
foldChanges <- sort(foldChanges, decreasing = TRUE)

# GSEA using gene sets from KEGG pathways
gseaKEGG <- gseKEGG(
    geneList = foldChanges,
    organism = tolower(params$gspecies),
    nPerm = 1000,
    minGSSize = 120,
    pvalueCutoff = 0.05,
    verbose = FALSE)
saveData(gseKEGG, dir = dataDir)

# Extract the GSEA results
gseaKEGGSummary <- slot(gseaKEGG, "result") %>% as_tibble()
write_csv(
    gseaKEGGSummary,
    path = file.path(faDir, "gsea_kegg_clusterprofiler.csv.gz"))
gseaKEGGSummary %>% datatable()
```

```{r kegg_plots, message=FALSE, results='asis'}
# dplyr must be unloaded at this step for pathview to work
suppressWarnings(detach("package:dplyr", unload = TRUE))

# If there is an error at this step, there may be a pathway that is not found by
# pathview package. In this case, you may need to run the pathview command above
# by specifying the index of the pathways you would like to print out in place
# of `x`.
pathways <- gseaKEGGSummary$ID

keggPlotsDir <- file.path(faDir, "kegg_plots")
dir.create(keggPlotsDir, recursive = TRUE, showWarnings = FALSE)

# There is currently no way to set the output path of the pathview PNG files.
# We're using tryCatch here to return to the user pathways that didn't output
# graphics correctly.
current <- getwd() %>% normalizePath()
setwd(keggPlotsDir)
lapply(seq_along(pathways), function(a) {
    pathway <- pathways[[a]]
    tryCatch(
        pathview(
            gene.data = foldChanges,
            pathway.id = pathway,
            species = tolower(params$gspecies), 
            limit = list(gene = 2, cpd = 1)),
        error = function(e) {
            warning(paste(pathway, "failed to plot"), call. = FALSE)
        }
    )
}) %>%
    invisible()
setwd(current)

figures <- list.files(keggPlotsDir, pattern = "pathview", full.names = TRUE)
invisible(lapply(seq_along(figures), function(a) {
    figure <- figures[[a]]
    cat(paste0("<img src=\"", figure, "\">\n"))
}))
```



```{r footer, child="_footer.Rmd", eval=file.exists("_footer.Rmd")}
```
