diff --git a/configuration.yaml b/configuration.yaml
index 6678915..4344e2a 100644
--- a/configuration.yaml
+++ b/configuration.yaml
@@ -16,6 +16,10 @@ module_files:
- "modules/cytokinenetwork.R"
- "modules/cellimagemodule.R"
- "modules/cnvmodule.R"
+ - "modules/germlinemodule.R"
+ - "modules/germlineheritability.R"
+ - "modules/germlinegwas.R"
+ - "modules/germlinerarevariants.R"
- "modules/ioresponseoverviewmodule.R"
- "modules/ioresponsesurvivalmodule.R"
- "modules/ioresponse_distribution_module.R"
@@ -38,6 +42,7 @@ function_files:
- "functions/mosaicplot.R"
- "functions/barplot.R"
- "functions/forestplot.R"
+ - "functions/manhattanplot.R"
- "functions/subtype_classifier.R"
- "functions/tablef_fun.R"
- "functions/imageplot.R"
@@ -45,6 +50,7 @@ function_files:
- "functions/extracellnet_utils.R"
- "functions/cellimage_utils.R"
- "functions/iomodules_utils.R"
+ - "functions/germline_utils.R"
page_files:
- "pages/aboutpage.R"
diff --git a/data/MethodsText/germline-colocalization.md b/data/MethodsText/germline-colocalization.md
new file mode 100644
index 0000000..b019294
--- /dev/null
+++ b/data/MethodsText/germline-colocalization.md
@@ -0,0 +1,22 @@
+**Title:** Germline Colocalization
+
+**Descriptions:** *Gene expression and splice quantitative trait locus analysis, and Colocalization:* We performed eQTL and sQTL analyses in TCGA and used summary statistics from the GTEx datasets to search for potential candidate genes. We excluded the HLA and IL17RA loci since SNPs at these loci are known eQTLs for genes that are part of the immune trait. For the significant and suggestive SNPs, we tested all genes within +/- 1MB for eQTL and all transcipts within +/- 500KB for sQTL. We used a shorter range for sQTLs with the assumption that SNPs affecting splicing are likely to act at a shorter distance.
+
+
+*TCGA dataset:* RNA-seq gene expression and splicing data were downloaded from the NIH Genomics Data Commons (https://gdc.cancer.gov/about-data/publications/pancanatlas and https://gdc.cancer.gov/about-data/publications/PanCanAtlas-Splicing-2018 (Kahles et al., 2018). For the sQTL analysis, we considered the following splicing categories: 3’, 5’, exome skipping, intron retention, and mutually exclusive exon events quantified by the Percent Spliced In (PSI) (Kahles et al., 2018). Only splicing events with more than 800 non-missing observations (~10% of the total data) were considered. Association analyses between either gene expression or PSI and the imputed SNPs were performed using linear regression using age, sex, PC1-7, and cancer type as covariates. We calculated FDR for each SNP separately, under the assumption that the SNP was already either significant or suggestive, and thus we had to correct for each of the genes at the locus but not all of the other SNPs (Table S5). We then selected the SNP-gene expression (eQTL) or SNP-gene splicing (sQTL) pairs with FDR p < 0.1 for further colocalization analysis.
+
+
+*GTEx dataset:* We downloaded all summary statistics for expression quantitative loci (eQTL - GTEx_Analysis_v8_eQTL_all_associations), and splicing quantitative loci (sQTL - GTEx_Analysis_v8_sQTL_all_associations) from GTEx project (https://console.cloud.google.com/storage/browser/gtex-resources) using the results from the latest version of the GTEx database (Version 8). For each SNP that had a genome-wide significant or suggestive association with one of the 33 immune traits by GWAS, we extracted all of the association statistics from the summary statistics for eQTL within +/- 1MB and for sQTLs within +/- 500 KB from all tissues in the GTEx summary statistics dataset. We then calculated FDR for each SNP, correcting for all of the genes at the locus across all tissues as we did for TCGA. For eQTL and/or sQTLs that had FDR p < 0.1, we pursued colocalization as below. TCGA GWAS summary statistics are annotated in Build 37, GTEx QTL summary stats are annotated in Build 38, when appropriate, liftover from Build 38 to 37 are provided using R/Bionconductor packages AnnotationHub (v2.12.1) (AH14150 chain file) and rtracklayer (v1.40.6). In the GTEx summary file (Tale S5) we annotated both Build 37 and Build 38 positions.
+
+
+*Colocalization analysis:* We performed colocalization posterior probability (CLPP) analysis using eCAVIAR (Hormozdiari et al., 2016) on both TCGA and GTEx results. eCAVIAR computes a posterior probability of causality based on association data and LD structure for the eQTL/sQTL and the trait GWAS and then calculates the joint probability of both of these being causal. It requires both summary statistics from GWAS and from the eQTL/sQTL analysis and the LD matrix of SNPs used in both analyses. For TCGA, we began with all SNPs that had FDR p < 0.1 with at least one gene and/or transcript and computed the eQTL and sQTL associations for the surrounding SNPs from the index SNP for that same gene/transcript using the same approach as outlined above. For GTEx, we began with SNP-gene expression or SNP-gene splicing pairs that met our FDR p < 0.1 criteria and extracted the eQTL and sQTL results for the surrounding SNPs from the summary results. For the GWAS and TCGA analyses, we calculated the genotype correlation (r) at each locus from the genotype data. For the GTEx analysis, we downloaded the individual genotype data from dbGAP for GTEx participants (https://www.ncbi.nlm.nih.gov/projects/gap/cgi-bin/study.cgi?study_id=phs000424.v8.p2) and calculated genotypic correlation between SNPs in R. We then ran eCAVIAR separately for each FDR p < 0.1 eQTL and sQTL association from TCGA and GTEx, considering models at each locus that assume one or two causal variants. For each SNP-gene expression or SNP-gene splicing category pair, 200 SNPs (+/- 100 SNPs) around the index SNP were included in colocalization analysis. The CLPP of each SNP being causal was calculated, and also a regional CLPP by summing all 201 SNP CLPPs. We used a posterior probability of > 0.01 to consider plausible colocalization, including both the 1 and 2 locus model and considering the sum of the posterior probability SNPs in the colocalization results.
+
+
+*Expanded region criteria for colocalization:* Since eCAVIAR identified multiple genes at the same locus for many loci that have plausible colocalization within a +/- 100 SNP boundary, we sought stronger evidence for colocalization at the loci where eCAVIAR found colocalization by examining an expanded region. We reasoned that a gene or transcript that is causal for the immune trait should not be more strongly associated with another SNP in the region that has little or no evidence of association with the immune trait. Therefore, for each gene or splice variant that had plausible colocalization by eCAVIAR, we performed an expanded region search (+/- 1MB for eQTLs and +/- 500KB for sQTLs) to see if we can identify one or more SNPs that had a stronger effect in the eQTL/sQTL analysis in the same tissue/dataset, which we called “counter-evidence” SNPs. If eCAVIAR produced plausible evidence of colocalization (posterior prob>0.01) and we could find no SNPs that met our counter-evidence criteria in the expanded region, we considered the expanded region evidence for colocalization as strong. If we did find SNPs that met our counter-evidence criteria in the expanded region, then we compared the significance level for the eQTL/sQTL association of the counter-evidence SNP vs. the eQTL/sQTL association with index SNP (associated with the immune trait). If the counter-evidence SNP association with eQTL or sQTL had a neg log10 p value that was less or equal than 1.5 higher than the index SNP (GWAS significant SNP for the immune trait), then we considered the expanded region evidence as intermediate. If the difference in -log10 p values was >1.5, we considered the expanded region analysis to be negative.
+ To visualize the colocalization in the expanded region, we generated plots that show the -log10 p QTL vs. -log10 p GWAS for all of the GWAS significant SNPs with CLPP > 0.01. The plots included the association p values for all of the SNPs at +/- 1MB for eQTL and at +/- 500KB for sQTL from the gene which had a CLPP > 0.01. These plots are available at Figshare (GTEX expanded region analysis plots: https://doi.org/10.6084/m9.figshare.13089341; ; TCGA expanded region analysis plots: https://doi.org/10.6084/m9.figshare.13090031. . We color-coded these plots with the LD, based on the LD matrix from the TCGA. Counter-SNPs are found in the top left corner of these plots (i.e. strong association with the eQTL or sQTL but no association with the immune trait). Conversely if there were no counter-SNPs, then the strongest SNPs for association with the immune trait were also the strongest SNPs for the association with the eQTL/sQTL.
+
+
+[Reference Listing](https://doi.org/10.1016/j.immuni.2021.01.011)
+
+**Contributors:** Rosalyn Sayaman, Donglei Hu, Mohamad Saad, Elad Ziv, Davide Bedognetti
+
diff --git a/data/MethodsText/germline-gwas.md b/data/MethodsText/germline-gwas.md
new file mode 100644
index 0000000..0c337b5
--- /dev/null
+++ b/data/MethodsText/germline-gwas.md
@@ -0,0 +1,8 @@
+**Title:** Germline GWAS
+
+**Descriptions:** We selected each of the immune phenotypes that demonstrated nominally significant genome-wide heritability (N=33) for GWAS. GWAS was conducted on all of the genotyped SNPs that passed QC and all of the imputed SNPs that had imputation R2 > 0.5 and minor allele frequency > 0.005 in the 9,603 unrelated individuals (PLINK 1.9 identity by descent, IBD, pihat < 0.25). Minor allele frequencies were recalculated post-imputation for only the subset of 9,603 individuals (PLINK 1.9). Of the 39,127,678 SNPs available after imputation, 10,955,441 passed both imputation quality and frequency thresholds and thus were included in the association analysis.
+GWAS was performed using PLINK 1.9. Immune phenotypes that were approximately normally distributed or normally distributed after stratification by covariates were tested for association with SNPs using linear regression with age, tumor type, sex and PC1-7 as covariates. Immune traits that were dichotomized for heritability analyses were analyzed using logistic regression models, with the same covariates. For each GWAS we also calculated the genome-wide inflation coefficient (lambda). We used the traditional cutoff of p < 5x10-8 as a cutoff for genome-wide significance and p < 1x10-6 to denote suggestive loci. Since we only selected the subset of phenotypes that was heritable and since many of the phenotypes were highly correlated, we did not correct the GWAS for the number of phenotypes analyzed. SNPs were annotated based on spanned genomic ranges (R v3.5.0, Bioconductor package GenomicRanges_1.32.6) with rsIDs (R v3.5.0, R package snplist_0.18.1, Bioconductor package SNPlocs.Hsapiens.dbSNP144.GRCh37_0.99.20) and with genes within +/- 50KB, +/- 500KB, and +/- 1MB of the SNP (R v3.5.0, Bioconductor package biomaRt_2.36.1 using grch37.ensembl.org as host). Variant annotations for all genome-wide and suggestive SNPs were determined using the web interface of the Ensembl Variant Effect Predictor (VEP, https://grch37.ensembl.org/info/docs/tools/vep/index.html. All annotations were based on Homo sapiens (human) genome assembly GRCh37 (hg19) from Genome Reference Consortium. All association statistics for the GWAS are available at Figshare https://figshare.com/articles/dataset/Sayaman_et_al_TCGA_Germline-Immune_GWAS_Summary_Statistics/13077920.
+
+[Reference Listing](https://doi.org/10.1016/j.immuni.2021.01.011)
+
+**Contributors:** Rosalyn Sayaman, Elad Ziv
diff --git a/data/MethodsText/germline-heritability.md b/data/MethodsText/germline-heritability.md
new file mode 100644
index 0000000..a538224
--- /dev/null
+++ b/data/MethodsText/germline-heritability.md
@@ -0,0 +1,17 @@
+**Title:** Heritability
+
+**Descriptions:** We performed heritability analysis on 139 traits using a mixed-model approach implemented in genome-wide complex trait analysis (GCTA) genomic-relatedness-based
+restricted maximum-likelihood (GREML) method (Yang et al., 2010, 2011) to calculate the proportion of immune trait variation that is attributable to common genetic variants (Zaitlen and
+Kraft, 2012). Heritability analyses were conducted separately within each ancestry subgroup (NEuropean=7,813, NAfrican=863, NAsian=570, and NAmerican=209 individuals), which were derived from ancestry analysis.
+
+To reduce bias in the heritability estimates, we removed one of each pair of related individuals with Ajk > 0.05 (calculated from SNPs with MAF > 0.01) prior to running GREML. We calculated heritability using an unconstrained approach (allowing heritability to be < 0 - those values were truncated in iAtlas). We used the likelihood ratio test (LRT) implemented in GREML to test if heritability is different than zero for each of the immune traits analyzed and used Benjamini-Hochberg adjustment (Benjamini and Hochberg, 1995) to calculate the FDR. All heritability analyses were run with age, tumor type, sex and PC 1-7 as covariates.
+
+We also used GREML to determine whether there are any contextual factors that interact with genome-wide common variant effects, including the major immune subtypes as determined by Thorsson et al and somatic mutations (divided into tertiles and dichotomized at 10 MB). We implemented the gene x environment (GxE) feature calculation in the European in GREML. For
+those immune traits for which we found nominally significant (p < 0.05) interactions, we calculated heritability in each stratified subset, as well as with immune subtype as an additional
+covariate. For GxE calculations, the LRT tests the significance of the variance of GxE interaction effects.
+
+[Reference Listing](https://doi.org/10.1016/j.immuni.2021.01.011)
+
+**Contributors:** Rosalyn Sayaman, Elad Ziv
+
+
diff --git a/data/MethodsText/germline-rarevariants.md b/data/MethodsText/germline-rarevariants.md
new file mode 100644
index 0000000..92fa9c8
--- /dev/null
+++ b/data/MethodsText/germline-rarevariants.md
@@ -0,0 +1,12 @@
+**Title:** Rare Variants
+
+**Descriptions:** For rare variant analysis, we focused on well-annotated, germline pathogenic or likely pathogenic cancer predisposition variants as previously defined (allele frequency in 1000 Genomes and ExAC (release r0.3.1) < 0.05%) (Huang et al., 2018).
+Exome files related to samples for which all the covariates (age, imputed sex, PC 1-7, and cancer type) and at least one immune trait was available were retained (N = 9,138). There were 832 pathogenic/likely pathogenic SNPs/Indels events with at least one copy of rare allele in the whole exome sequencing data, corresponding to 586 distinct pathogenic SNPs/Indels mapping to 99 genes.
+
+We performed a pathway burden analysis using selected pre-defined biological pathways such as DNA damage repair and onco-genic processes, pan-cancer and per cancer (Bailey et al., 2018; Huang et al., 2018; Knijnenburg et al., 2018). These pathways were manually curated to generate a list of mutually exclusive pathways. The only genes that were not collapsed into pathways were BRCA1 and BRCA2 for which a sufficient number of events across cancers exist. Overall, 21 genotypic variables were used for analyses (Figure S7A). In the pan-cancer analysis, we only included genes (BRCA1/BRCA2) or pathways with a number of events (mutations) greater than 4 across cancers, including a total of 90 genes. For each pathway, variants that fall within its selected set of genes were collapsed based on the presence or absence of any rare variant (i.e., 0 if no rare variant was present and 1 if there is at least one variant). We conducted regression analyses (linear or logistic, as done for GWAS) to assess the association between the pathways’ burden of rare variants and immune traits. Traits assessed in these analyses were the same as the ones used for heritability analyses, with the addition of the immune subtypes (C1, C2, etc.), DNA-alteration related metrics such as the mutational load, the neoantigen load, the degree of copy number alterations (Thorsson et al., 2018) and the MANTIS score (threshold = 0.4, Middha et al., 2017). All pan-cancer regression models included the following covariates: age, sex, cancer type, and PC1-7.
+
+In the pan-cancer analysis, we used a Benjamini-Hochberg FDR (Benjamini and Hochberg, 1995) to correct for multiple hypothesis testing, accounting for all 21 genes and pathways tested and 154 phenotypes (139 immune traits, 9 DNA related metrics, and 6 immune subtypes). We used a cutoff of FDR p < 0.1 to identify significant gene/pathway-immune trait associations and a threshold of nominal p < 0.005 (FDR <= 0.25) to identify suggestive associations. We used a more permissive cut-off in these analyses than the ones used in the heritability and GWAS to reduce type II error due to the low number of events (germline mutations).
+
+[Reference Listing](https://doi.org/10.1016/j.immuni.2021.01.011)
+
+**Contributors:** Mohamad Saad, Jessica Roelands, Davide Bedognetti
\ No newline at end of file
diff --git a/data/germline/colocalization_GTEX_df.feather b/data/germline/colocalization_GTEX_df.feather
new file mode 100644
index 0000000..9e19dd2
Binary files /dev/null and b/data/germline/colocalization_GTEX_df.feather differ
diff --git a/data/germline/colocalization_TCGA_df.feather b/data/germline/colocalization_TCGA_df.feather
new file mode 100644
index 0000000..e23dc07
Binary files /dev/null and b/data/germline/colocalization_TCGA_df.feather differ
diff --git a/data/germline/germline_gwas.feather b/data/germline/germline_gwas.feather
new file mode 100644
index 0000000..37b2ea8
Binary files /dev/null and b/data/germline/germline_gwas.feather differ
diff --git a/data/germline/germline_heritability.feather b/data/germline/germline_heritability.feather
new file mode 100644
index 0000000..f42d8ef
Binary files /dev/null and b/data/germline/germline_heritability.feather differ
diff --git a/data/germline/germline_rare_variants.feather b/data/germline/germline_rare_variants.feather
new file mode 100644
index 0000000..c97c69c
Binary files /dev/null and b/data/germline/germline_rare_variants.feather differ
diff --git a/data/markdown/germline_heritability.markdown b/data/markdown/germline_heritability.markdown
new file mode 100644
index 0000000..ad82baf
--- /dev/null
+++ b/data/markdown/germline_heritability.markdown
@@ -0,0 +1,7 @@
+Explore the percentage of variance of immune phenotype traits explained by common genetic variance across different ancestry groups.
+
+Heritability analyses were performed using genomic-relatedness-based restricted maximum-likelihood (GREML) and provide estimates of the proportion of phenotypic variance explained by the genetic variance, V(Genotype)/Vp. The analyses were conducted separately within each ancestral subgroup, which were derived from ancestry analysis using the genotype data. Each immune trait is assigned to a particular Category and a particular Module, as described in the manuscript.
+
+Select a subset criteria (*Subset by*) and a group of interest (*Show associated results for*) to generate a bar plot summarizing the V(Genotype)/Vp for the immune traits in that group that have p-values lower than the selected p-value threshold. For a visualization of a single phenotype across different ancestry clusters, select 'Immune Feature' in *Subset by* and the trait of interest in the *Show associated results for* menu.
+
+For the European ancestry cluster, it is also possible to visualize the percentage of variance of immune traits accounted for by interaction between germline genotypes and immune subtypes (G x Immune Subtype).
diff --git a/data/markdown/tilmap.markdown b/data/markdown/tilmap.markdown
index f68c4fa..1de1c60 100644
--- a/data/markdown/tilmap.markdown
+++ b/data/markdown/tilmap.markdown
@@ -1,6 +1,6 @@
This module relates to the manuscript:
[Saltz et al. Spatial Organization And Molecular Correlation Of Tumor-Infiltrating Lymphocytes Using Deep Learning On Pathology Images; Cell Reports 23, 181-193, April 3 2018.]
-(https://www.cell.com/cell-reports/fulltext/S2211-1247(18)30447-9)
+(https://www.cell.com/cell-reports/fulltext/S2211-1247(18\)30447-9)
TCGA H&E digital pathology images were analyzed for tumor infiltrating lymphocytes (TILs) using deep learning.
The analysis identifies small spatial regions on the slide image - patches - that are rich in TILs.
diff --git a/functions/barplot.R b/functions/barplot.R
index f87b6fe..45e1752 100644
--- a/functions/barplot.R
+++ b/functions/barplot.R
@@ -53,3 +53,67 @@ create_barplot <- function(
}
+create_barplot_horizontal <- function(df,
+ x_col = "x",
+ y_col = "y",
+ error_col = "error",
+ key_col = NA,
+ color_col = NA,
+ label_col = NA,
+ order_by = NULL,
+ xlab = "",
+ ylab = "",
+ title = "",
+ showLegend = TRUE,
+ legendTitle = " ",
+ source_name = NULL,
+ bar_colors = NULL){
+ if(is.na(key_col)) key_col <- x_col
+ if(is.na(color_col)) color_col <- x_col
+ if(is.na(label_col)) label_col <- x_col
+
+ if (is.null(bar_colors)) {
+ bar_colors <- viridis::viridis_pal(option = "D")(dplyr::n_distinct(df[[color_col]]))
+ }
+ wrapr::let(
+ alias = c(
+ X = x_col,
+ Y = y_col,
+ KEY = key_col,
+ COLOR = color_col,
+ ERROR = error_col,
+ LABEL = label_col),
+ plotly::plot_ly(
+ df,
+ x = ~X,
+ y = ~Y,
+ color = ~COLOR,
+ text = ~LABEL,
+ key = ~KEY,
+ type = 'bar',
+ source = source_name,
+ colors = bar_colors,
+ orientation = 'h',
+ error_x = list(
+ visible = T,
+ type = "data",
+ array = ~ERROR,
+ color = 'black',
+ thickness = 1),
+ hoverinfo = 'text'
+ )) %>%
+ plotly::layout(
+ title = title,
+ xaxis = list(title = xlab),
+ yaxis = list(title = ylab,
+ categoryorder = "array",
+ categoryarray = ~order_by),
+ showlegend = showLegend,
+ legend = list(orientation = 'h', x = 0, y = 1,
+ title = list(text = legendTitle)
+ )
+ ) %>%
+ format_plotly()
+
+}
+
diff --git a/functions/boxplot.R b/functions/boxplot.R
index d0c2044..8a4b1f8 100644
--- a/functions/boxplot.R
+++ b/functions/boxplot.R
@@ -51,6 +51,65 @@ create_boxplot <- function(
) %>%
format_plotly() %>%
I
-
-
}
+
+
+create_boxplot_from_summary_stats <- function(
+ df,
+ y_col = "y",
+ q1_col,
+ median_col,
+ q3_col,
+ min_col,
+ max_col,
+ mean_col = NA,
+ key_col = NA,
+ color_col = NA,
+ label_col = NA,
+ order_by = NULL,
+ title = "",
+ xlab = "",
+ ylab = "",
+ source_name = NULL,
+ fill_colors = NA){
+
+ if(is.na(key_col)) key_col <- y_col
+ if(is.na(color_col)) color_col <- y_col
+
+ wrapr::let(
+ alias = c(
+ Y = y_col,
+ Q1 = q1_col,
+ Q2 = median_col,
+ Q3 = q3_col,
+ MIN = min_col,
+ MAX = max_col,
+ MEAN = mean_col,
+ KEY = key_col,
+ COLOR = color_col),
+ plotly::plot_ly(
+ df,
+ y = ~Y,
+ #color = ~COLOR,
+ type = "box",
+ q1= ~Q1,
+ median= ~Q2,
+ q3= ~Q3,
+ lowerfence= ~MIN,
+ upperfence= ~MAX,
+ mean= ~MEAN,
+ #fillcolor = fill_colors,
+ #colors = fill_colors,
+ source = source_name
+ )) %>%
+ plotly::layout(
+ title = title,
+ xaxis = list(title = xlab),
+ yaxis = list(title = ylab,
+ ategoryorder = "array",
+ categoryarray = ~order_by)
+ ) %>%
+ format_plotly() %>%
+ I
+}
+
diff --git a/functions/germline_utils.R b/functions/germline_utils.R
new file mode 100644
index 0000000..62e1124
--- /dev/null
+++ b/functions/germline_utils.R
@@ -0,0 +1,176 @@
+
+add_plotly_label <- function(tbl, title, name, group){
+ dplyr::mutate(tbl, label = paste0(
+ "", title, ": ", {{name}}, " (", {{group}}, ")"
+ ))
+}
+
+add_plotly_value_label <- function(tbl, cols){
+ tbl %>%
+ tidyr::pivot_longer(
+ .,
+ tidyselect::all_of(cols),
+ names_to = "value_name",
+ values_to = "value"
+ ) %>%
+ dplyr::mutate(value_label = stringr::str_glue(
+ "{name}: {value}",
+ name = stringr::str_to_upper(.data$value_name),
+ value = sprintf("%0.3f", .data$value)
+ )) %>%
+ dplyr::group_by(.data$label) %>%
+ dplyr::mutate(value_label = paste0(
+ .data$value_label,
+ collapse = ""
+ )) %>%
+ dplyr::ungroup() %>%
+ tidyr::pivot_wider(
+ .,
+ names_from = .data$value_name,
+ values_from = .data$value
+ )
+}
+
+create_plotly_label <- function(
+ tbl,
+ name,
+ group,
+ cols,
+ title = "ParticipantBarcode"
+){
+
+ tbl %>%
+ add_plotly_label(title, {{name}}, {{group}}) %>%
+ add_plotly_value_label(tidyselect::all_of(cols)) %>%
+ tidyr::unite(
+ "label",
+ .data$label,
+ .data$value_label,
+ sep = ""
+ )
+}
+
+#Heritability functions
+
+#' Prepare heritability tibble for plotting
+#'
+#' @param heritablity_data A tibble
+#' @param parameter Parameter to be used for selection of results (eg, ancestry cluster, immune feature)
+#' @param group Specific group, in the selected parameter, to be displayed (eg. European - ancestry cluster, NK cells - immune feature)
+#' @param pval_thres Maximun p-value to be included
+#' @importFrom magrittr %>%
+
+create_heritability_df <- function(
+ heritablity_data,
+ parameter = "cluster",
+ group = "European",
+ pval_thres = 0.05,
+ ancestry_labels
+){
+
+ ancestry_df <- names(ancestry_labels)
+ names(ancestry_df) <- ancestry_labels
+
+ df <- heritablity_data %>%
+ dplyr::filter(.[[parameter]] == group) %>%
+ dplyr::filter(p_value <= pval_thres) %>%
+ dplyr::filter(variance > 0) %>%
+ create_plotly_label(
+ ., paste(.$display, "- ", ancestry_df[cluster], "Ancestry"),
+ paste("\n Immune Trait Category:",.$category, "\n Immune Trait Module:", .$module),
+ c("variance", "se", "p_value","fdr"),
+ title = "Immune Trait"
+ )
+
+ #creating the y label
+ if(parameter == "cluster") df <- df %>% mutate(ylabel = display)
+ else if (parameter == "category" | parameter == "module")
+ df <- df %>% mutate(ylabel = paste(ancestry_df[cluster], display, sep = " - "))
+ else df <- df %>% mutate(ylabel = paste(ancestry_df[cluster], .[[parameter]], sep = " - "))
+}
+
+format_heritability_plot <- function(p, hdf, fdr = FALSE){
+ p <- p %>%
+ plotly::layout(
+ xaxis = list(
+ tickformat = "%"
+ )
+ )
+ if(fdr == TRUE){
+ p <- p %>%
+ plotly::add_annotations(x = hdf$variance+hdf$se+0.01,
+ y = hdf$ylabel,
+ text = (hdf$plot_annot),
+ xref = "x",
+ yref = "y",
+ showarrow = F,
+ font=list(color='black')) %>%
+ plotly::add_annotations( text="LRT FDR \n † <= 0.1 \n * <= 0.05 \n ** <= 0.01 \n *** <= 0.001", xref="paper", yref="paper",
+ x=1.03, xanchor="left",
+ y=0, yanchor="bottom",
+ legendtitle=TRUE, showarrow=FALSE )
+ }
+ p
+}
+
+#' Build Manhattan plot tibble
+#'
+#' @param gwas_df A Tibble with columns sample_id and group
+#' @param chr_selected An integer in the id column of the samples table
+#' @param bp_min An integer in the id column of the samples table
+#' @param bp_max An integer in the id column of the samples table
+#' @param feature_selected An integer in the id column of the samples table
+#' @importFrom magrittr %>%
+#' @importFrom dplyr left_join filter group_by summarise mutate
+#' @importFrom rlang .data
+build_manhattanplot_tbl <- function(
+ gwas_df,
+ chr_selected,
+ bp_min,
+ bp_max,
+ to_select,
+ to_highlight,
+ to_exclude) {
+
+ if(to_highlight == FALSE & !is.null(to_exclude)) gwas <- gwas_df %>% dplyr::filter(!(display %in% to_exclude))
+ else if(to_highlight == TRUE) gwas <- gwas_df %>% dplyr::filter(display %in% to_select)
+ else gwas <- gwas_df
+
+ gwas %>%
+ dplyr::filter(chr %in% chr_selected) %>%
+ dplyr::group_by(chr) %>%
+ dplyr::summarise(chr_len=max(bp), .groups = "drop_last") %>%
+ dplyr::mutate(tot=cumsum(as.numeric(chr_len))-chr_len) %>%
+ dplyr::select(-chr_len) %>%
+ dplyr::left_join(gwas, ., by = "chr") %>%
+ dplyr::arrange(chr, bp) %>%
+ dplyr::mutate(x_col=bp+tot) %>%
+ dplyr::mutate( log10p = -log10(p_value),
+ text = paste("",display, "",
+ "\n(Immune Trait Category: ", `category`, ")",
+ "\nSNP name: ", snp_id, "\nSNP: ", snp_col, "\nChromosome: ", chr, "\nPosition: ", bp,
+ "\nPLINK MAF: ", maf, sep=""))
+}
+
+get_mhtplot_xlabel <- function(
+ selected_region = input$selection,
+ gwas_df = gwas_mht(),
+ x_min = selected_min(),
+ x_max = selected_max()
+){
+ if(selected_region == "See all chromosomes"){
+ gwas_df %>%
+ dplyr::group_by(chr) %>%
+ dplyr::summarize(center=( max(x_col) + min(x_col) ) / 2 , .groups = "drop") %>%
+ dplyr::rename(label = chr)
+ }else{
+ breaks <- c(x_min, (x_min+x_max)/2, x_max)
+ data.frame(
+ label = paste(format(round(breaks / 1e6, 2), trim = TRUE), "Mb"),
+ center = breaks,
+ stringsAsFactors = FALSE
+ )
+ }
+}
+
+
diff --git a/functions/load_data.R b/functions/load_data.R
index 28f9ed1..00704c8 100644
--- a/functions/load_data.R
+++ b/functions/load_data.R
@@ -127,6 +127,18 @@ load_io_response <- function(){
}
}
+load_germline <- function(){
+ if (!USE_REMOTE_BQ) {
+
+ list(
+ heritability = feather::read_feather("data/germline/germline_heritability.feather"),
+ gwas = feather::read_feather("data/germline/germline_gwas.feather"),
+ coloc_tcga = feather::read_feather("data/germline/colocalization_TCGA_df.feather"),
+ coloc_gtex = feather::read_feather("data/germline/colocalization_GTEX_df.feather"),
+ rv_stats = feather::read_feather("data/germline/germline_rare_variants.feather")
+ )
+ }
+}
## selection choices for the cell fractions. Lots of other choices possible.
create_cell_fraction_options <- function() {
@@ -218,3 +230,16 @@ load_io_data <- function(){
im_expr = io_data$im_expr_io_df
)
}
+
+load_germline_data <- function(){
+
+ germline_data <- load_germline()
+
+ list(
+ heritability = germline_data$heritability,
+ gwas = germline_data$gwas,
+ coloc_tcga = germline_data$coloc_tcga,
+ coloc_gtex = germline_data$coloc_gtex,
+ rare_variants = germline_data$rv_stats
+ )
+}
\ No newline at end of file
diff --git a/functions/manhattanplot.R b/functions/manhattanplot.R
new file mode 100644
index 0000000..146ed65
--- /dev/null
+++ b/functions/manhattanplot.R
@@ -0,0 +1,34 @@
+create_manhattanplot <- function(
+ df,
+ x_label,
+ y_min,
+ y_max,
+ x_name = NULL,
+ y_name = NULL,
+ x_limits = NULL,
+ plot_title = "",
+ source_name = NULL
+ ) {
+
+ if(is.null(x_limits)) x_limits <- c(min(df$x_col), max(df$x_col))
+
+ plotly::ggplotly(ggplot2::ggplot(df, aes(x=x_col, y=log10p, text=text)) +
+ geom_point(data=subset(df, is_highlight=="no"), aes(color=as.factor(chr)), alpha=0.8, size=1.3) +
+ scale_color_manual(values = rep(c("#19a8c7", "#12748a"), 22)) +
+ scale_x_continuous(label = x_label$label, breaks= x_label$center, limits = x_limits) +
+ scale_y_continuous(expand = c(0, 0.5), limits = c(y_min, y_max)) +
+ geom_point(data=subset(df, is_highlight=="yes"), color="orange", size=2) +
+ geom_point(data=subset(df, is_highlight=="snp"), shape = 23, fill="red", size=2) +
+ theme_bw() +
+ theme(
+ legend.position="none",
+ panel.border = element_blank(),
+ panel.grid.major.x = element_blank(),
+ panel.grid.minor.x = element_blank()
+ )+
+ labs(
+ title = plot_title,
+ y = y_name, x = x_name),
+ tooltip="text",
+ source = source_name)
+}
diff --git a/global.R b/global.R
index 92b5304..c161200 100644
--- a/global.R
+++ b/global.R
@@ -8,6 +8,7 @@ USE_REMOTE_GS <- config_yaml$gs_remote
panimmune_data <- load_data()
ioresponse_data <- load_io_data()
+germline_data <- load_germline_data()
purrr::walk(config_yaml$module_files, source)
purrr::walk(config_yaml$page_files, source)
diff --git a/modules/germlinegwas.R b/modules/germlinegwas.R
new file mode 100644
index 0000000..f021dce
--- /dev/null
+++ b/modules/germlinegwas.R
@@ -0,0 +1,513 @@
+germline_gwas_ui <- function(id){
+
+ ns <- shiny::NS(id)
+ shiny::tagList(
+ messageBox(
+ width = 12,
+ shiny::p("GWAS were performed on 33 immune traits that demonstrated nominally significant heritability (p < 0.05) in at least one ancestry group. Here you can visualize the significant (p < 10-6) GWAS hits, as a Manhattan plot."),
+ shiny::p("Select Immune Features of interest to highlight or select the GWAS hits associated with this trait. You can also choose to exclude GWAS hits associated with a selected immune feature (or features)."),
+ shiny::p("If you choose the *Select a region option*, you will be able to select a region of interest and see the genomic region on a IGV plot."),
+ shiny::p("More information on a particular SNP, including links to external resources, can be obtained by clicking on the Manhattan plot, or by searching on the dropdown menu on the right."),
+ shiny::p("Manuscript context: An image similar to Figure 4A is generated with the 'See all chromosomes' option, for immune feature “IFN 21978456”. To generate an image like Figure 4C, change the range of visualization to 'Select a region', Chromosome 2 and then select the coordinates by zooming in the plot, or by manually updating the start and end of the region of interest."),
+ p("GWAS results can also be visualized in ",
+ a(href = "https://pheweb-tcga.qcri.org/about", "Pheweb.")),
+ shiny::actionLink(ns("method_link_gwas"), "Click to view method description.")
+ ),
+ shiny::column(
+ width = 9,
+ optionsBox(
+ width = 12,
+ shiny::column(
+ width = 3,
+ shiny::radioButtons(ns("selection"), "Select range of visualization", choices = c("See all chromosomes", "Select a region"), selected = "See all chromosomes")
+ ),
+ shiny::column(
+ width = 5,
+ shiny::uiOutput(ns("features")),
+ shiny::checkboxInput(ns("only_selected"), "Display only selected feature(s)")
+ ),
+ shiny::column(
+ width = 4,
+ shiny:: conditionalPanel(
+ condition = paste("" , paste0("input['", ns("only_selected"), "'] == false")),
+ shiny::uiOutput(ns("to_exclude"))
+ )
+ )
+ ),
+ plotBox(
+ width = 12,
+ plotly::plotlyOutput(ns("mht_plot"), height = "300px") %>%
+ shinycssloaders::withSpinner(.),
+ shiny::conditionalPanel(paste0("input['", ns("selection"), "'] == 'Select a region'"),
+ igvShiny::igvShinyOutput(ns('igv_plot')) %>%
+ shinycssloaders::withSpinner(.)
+ )
+ )
+ ),
+ shiny::column(
+ width = 3,
+ shiny::verticalLayout(
+ optionsBox(
+ width = 12,
+ shiny::uiOutput(ns("search_snp"))
+ ),
+ messageBox(
+ width = 12,
+ shiny::uiOutput(ns("links"))
+ ),
+ tableBox(
+ width = 12,
+ DT::DTOutput(ns("snp_tbl"))
+ )
+ )
+ ),
+ messageBox(
+ width = 12,
+ shiny::p("We conducted a GWAS paired with colocalization analyses, with eQTL and sQTL analyses performed in TCGA and GTEx.
+ Results with a Colocalization Posterior Probability (CLPP) > 0.01 are summarized in the tables below."),
+ shiny::p("Click on a table row to visualize the plot. The table is updated with available plots in the region displayed at the manhattan plot."),
+ shiny::actionLink(ns("method_link_colocalization"), "Click to view method description.")
+ ),
+
+ shiny::fluidRow(
+ tableBox(
+ width = 6,
+ div(DT::DTOutput(ns("colocalization_tcga")) %>%
+ shinycssloaders::withSpinner(.),
+ style = "font-size: 75%"),
+ shiny::uiOutput(ns("tcga_colocalization_plot"))
+ ),
+ tableBox(
+ width = 6,
+ div(DT::DTOutput(ns("colocalization_gtex")) %>%
+ shinycssloaders::withSpinner(.),
+ style = "font-size: 75%"),
+ shiny::uiOutput(ns("gtex_colocalization_plot"))
+ )
+ )
+ )
+}
+
+germline_gwas_server <- function(input, output, session) {
+
+ ns <- session$ns
+
+ colocalization_plot <- reactive({ #get files with the selected SNP
+ feather::read_feather("data/germline/colocalization_TCGA_df.feather")
+ })
+
+ gtex_coloc <- reactive({
+ feather::read_feather("data/germline/colocalization_GTEX_df.feather")
+ })
+
+ immune_feat <- reactive({
+
+ germline_data$gwas %>%
+ dplyr::select(display, category) %>%
+ dplyr::group_by(category) %>%
+ tidyr::nest(data = c(display))%>%
+ dplyr::mutate(data = purrr::map(data, tibble::deframe)) %>%
+ tibble::deframe()
+
+ })
+
+ output$features <- renderUI({
+ shiny::selectizeInput(ns('immunefeature'), "Select Immune Feature(s)",
+ choices = immune_feat(),
+ selected = c("CD8 T cells", "NK cells"),
+ multiple = TRUE)
+ })
+
+ output$to_exclude <- renderUI({
+ shiny::selectizeInput(ns('exclude_feat'), "Exclude Immune Feature (optional)",
+ choices = immune_feat(),
+ selected = c("MHC2 21978456", "Th17 cells"),
+ multiple = TRUE)
+ })
+
+ output$search_snp <- renderUI({
+ shiny::req(subset_gwas())
+ snp_options <- (subset_gwas() %>% dplyr::filter(snp_id != "NA"))$snp_id
+ shiny::selectInput(ns("snp_int"), "Click on the plot or search for a SNP id:",
+ choices = c("", snp_options))
+ })
+
+ observe({
+ updateSelectInput(session, "snp_int", selected = snp_of_int$ev)
+ })
+
+ #keeping track of the selected chromossome
+ selected_chr_reactive <- reactiveValues(ev = 1)
+
+ observeEvent(input[[sprintf("currentGenomicRegion.%s", "igv_plot")]], {
+ shiny::req(input$selection == "Select a region")
+ #if(!("width" %in% names(plotly::event_data("plotly_relayout", source = "gwas_mht", priority = "event")))){
+ new_chr <- as.numeric(sub("chr(.*):.*", "\\1", input[[sprintf("currentGenomicRegion.%s", "igv_plot")]]))
+ if(new_chr %in% c(1:22)) selected_chr_reactive$ev <- new_chr
+ #}
+ })
+
+ selected_chr <- reactive({
+ switch(
+ input$selection,
+ "See all chromosomes" = c(1:22),
+ "Select a region" = selected_chr_reactive$ev
+ )
+ })
+
+ chr_size <- reactive({
+ shiny::req(input$selection == "Select a region", selected_chr())
+
+ c((min((germline_data$gwas %>% dplyr::filter(chr == selected_chr()))$bp)),
+ (max((germline_data$gwas %>% dplyr::filter(chr == selected_chr()))$bp)))
+ })
+
+ #adding interactivity to select a region from zooming in the plot
+
+ clicked_int <- reactiveValues(ev=NULL)
+
+ observe({
+ shiny::req(input$selection == "Select a region")
+ #if a user resizes the browser, a new event data will be released, so let's guarantee that this will not affect the visualization
+ if(!("width" %in% names(plotly::event_data("plotly_relayout", source = "gwas_mht", priority = "event")))){
+ clicked_int$ev <- plotly::event_data("plotly_relayout", source = "gwas_mht", priority = "event")
+ }
+ })
+
+ #reset region with change of chromosome or selection of all chromosomes
+ toReset <- reactive({
+ shiny::req(input$selection == "Select a region")
+ list(selected_chr(),
+ input$selection)
+ })
+
+ observeEvent(toReset(), {
+ clicked_int$ev <- NULL
+ })
+
+ #Creating the object that stores the selected range (either by zoom on manhattan plot or change in the IGV plot)
+ chr_range <- reactiveValues(range = NULL)
+
+ observe({
+ shiny::req(input$selection == "Select a region",
+ chr_size())
+
+ if(is.null(clicked_int$ev)){ #default option is min and max positions for the chromosome
+ chr_range$range = chr_size()
+ } else { #Update range after a zoom in the plot - need to compare with chr_size because plot has x-axis longer than chr_size
+ chr_range$range = c((floor(max(chr_size()[1], clicked_int$ev$`xaxis.range[0]`))),
+ (ceiling(min(chr_size()[2], clicked_int$ev$`xaxis.range[1]`))))
+ }
+ })
+
+ observeEvent(input[[sprintf("currentGenomicRegion.%s", "igv_plot")]], { #this observer is only activated when a change is made on the IGV plot
+ #if(!("width" %in% names(plotly::event_data("plotly_relayout", source = "gwas_mht", priority = "event")))){
+ newLoc <- input[[sprintf("currentGenomicRegion.%s", "igv_plot")]]
+
+ pattern <- "chr(.*):(.*)-(.*)"
+ sel_start <- as.numeric(gsub(",", "", sub(pattern, "\\2", newLoc)))
+ sel_end <- as.numeric(gsub(",", "", sub(pattern, "\\3", newLoc)))
+
+ chr_range$range <- c(sel_start,
+ sel_end)
+ #}
+ })
+
+ selected_min <- reactive({
+ switch(
+ input$selection,
+ "See all chromosomes" = 1,
+ "Select a region" = chr_range$range[1]
+ )
+ })
+
+ selected_max <- reactive({
+ switch(
+ input$selection,
+ "See all chromosomes" = 245246279,
+ "Select a region" = chr_range$range[2]
+ )
+ })
+
+ # Prepare the dataset
+ toUpdate <- reactive({
+ list(
+ input$immunefeature,
+ input$exclude_feat,
+ input$only_selected,
+ selected_chr(),
+ input$go_button
+ )
+ })
+
+ gwas_mht <- eventReactive(toUpdate(),{
+ shiny::req(immune_feat(), selected_chr(), selected_min(), selected_max())
+ build_manhattanplot_tbl(
+ gwas_df = germline_data$gwas,
+ chr_selected = selected_chr(),
+ bp_min = selected_min(),
+ bp_max = selected_max(),
+ to_select = input$immunefeature,
+ to_highlight = input$only_selected,
+ to_exclude = input$exclude_feat)
+ })
+
+ subset_gwas <- reactive({ #updates when range is changed
+ shiny::req(gwas_mht())
+ gwas_mht() %>%
+ dplyr::filter(chr %in% selected_chr()) %>%
+ dplyr::filter(bp >= selected_min() & bp <= selected_max())
+ })
+
+ axisdf <- eventReactive(gwas_mht(), {
+ shiny::req(gwas_mht(), subset_gwas())
+ get_mhtplot_xlabel(
+ selected_region = input$selection,
+ gwas_df = gwas_mht(),
+ x_min = selected_min(),
+ x_max = selected_max()
+ )
+ })
+
+ x_title <- reactive({
+ if(input$selection == "See all chromosomes") "Chromosome"
+ else ""
+ })
+
+ output$mht_plot <- plotly::renderPlotly({
+ shiny::req(subset_gwas(), axisdf())
+
+ shiny::validate(
+ shiny::need(nrow(subset_gwas()) > 0, "Select a region with a GWAS hit.")
+ )
+
+ if(input$only_selected == 0) gwas_df <- subset_gwas() %>% dplyr::mutate(is_highlight=ifelse(display %in% input$immunefeature, "yes", "no"))
+ else gwas_df <- subset_gwas() %>% dplyr::mutate(is_highlight = "no")
+
+ gwas_df %>%
+ dplyr::mutate(is_highlight = replace(is_highlight, snp_id == snp_of_int$ev, "snp")) %>%
+ create_manhattanplot(
+ df = .,
+ x_label = axisdf(),
+ y_min = 6,
+ y_max = ceiling(max(gwas_df$log10p)),
+ x_limits = c(selected_min(), max(selected_max(), subset_gwas()$x_col)),
+ x_name = x_title(),
+ y_name = "- log10(p-value)",
+ plot_title = "",
+ source_name = "gwas_mht"
+ )
+ })
+
+ output$igv_plot <- igvShiny::renderIgvShiny({
+ shiny::req(subset_gwas())
+ shiny::req(input$selection == "Select a region")
+
+ igvShiny::igvShiny(list(
+ genomeName="hg19",
+ initialLocus= paste0("chr", selected_chr(), ":", scales::comma(selected_min()), "-", scales::comma(selected_max()))
+ ),
+ displayMode="SQUISHED")
+ })
+
+ #adding interactivity to select a SNP from the plot or from the dropdown menu
+
+ clicked_snp <- reactiveValues(ev=NULL)
+
+ observe({
+ eventdata <- plotly::event_data( "plotly_click", source = "gwas_mht")
+ if(is.null(eventdata)){
+ clicked_snp$ev <- NULL
+ }else{
+ x_pos <- eventdata$x
+ y_pos <- round(eventdata$y, 2)
+
+ check_df <- gwas_mht()
+ check_df$log10p <- round(check_df$log10p, 2)
+
+ clicked_snp$ev <- as.character(check_df %>%
+ dplyr::filter(x_col == x_pos & log10p == y_pos) %>%
+ dplyr::select(snp_id))
+ }
+ })
+
+ snp_of_int <- reactiveValues(ev="")
+
+ shiny::observeEvent(clicked_snp$ev,{
+ snp_of_int$ev <- clicked_snp$ev
+ })
+
+ shiny::observeEvent(input$snp_int,{
+ snp_of_int$ev <- input$snp_int
+ })
+
+ # clear selected snp on double click
+ observeEvent(plotly::event_data("plotly_doubleclick", source = "gwas_mht"), {
+ snp_of_int$ev <- ""
+ })
+
+ selected_snp <- reactive({
+ shiny::req(gwas_mht(), axisdf())
+
+ shiny::validate(
+ shiny::need(!is.null(snp_of_int$ev),
+ "Click manhattan plot to select a SNP."))
+
+ shiny::validate(
+ shiny::need(snp_of_int$ev != "NA",
+ "Selected SNP has no SNP id"))
+
+ gwas_mht() %>%
+ dplyr::filter(snp_id == snp_of_int$ev) %>%
+ dplyr::select(snp_id, snp_col, chr, bp) %>%
+ dplyr::distinct()
+
+ })
+
+ output$links <- renderUI({
+ shiny::validate(
+ shiny::need(selected_snp()$snp_id %in% gwas_mht()$snp_id, "Select SNP")
+ )
+ #creating the links for external sources
+ dbsnp <- paste0("https://www.ncbi.nlm.nih.gov/snp/", selected_snp()$snp_id)
+ gtex <- paste0("https://gtexportal.org/home/snp/", selected_snp()$snp_id)
+ gwascat <- paste0("https://www.ebi.ac.uk/gwas/search?query=", selected_snp()$snp_id)
+ pheweb <- paste0("http://pheweb-tcga.qcri.org/variant/", gsub(':([[:upper:]])', "-\\1", selected_snp()$snp_col))
+ dice <- paste0("https://dice-database.org/eqtls/", selected_snp()$snp_id)
+
+ p(strong(selected_snp()$snp_id), tags$br(),
+ selected_snp()$snp_col, tags$br(),
+ "View more SNP information at",
+ tags$a(href = dbsnp, "dbSNP, "),
+ tags$a(href = gtex, "GTEx, "),
+ tags$a(href = gwascat, "GWAS Catalog, "),
+ tags$a(href = pheweb, "PheWeb, "),
+ tags$a(href = dice, "DICE")
+ )
+ })
+
+ output$snp_tbl <- DT::renderDT({
+ shiny::req(gwas_mht())
+ shiny::validate(
+ shiny::need(selected_snp()$snp_id %in% gwas_mht()$snp_id, "")
+ )
+
+ snp_df <- gwas_mht() %>%
+ dplyr::filter(snp_id == selected_snp()$snp_id) %>%
+ dplyr::mutate(nlog = round(log10p, 2)) %>%
+ dplyr::select(
+ Trait = display,
+ `-log10(p)` = nlog)
+
+ DT::datatable(
+ snp_df,
+ rownames = FALSE,
+ caption = paste("GWAS hits"),
+ options = list(dom = 't')
+ )
+ })
+
+ #COLOCALIZATION
+ coloc_label <- reactive({
+ switch(
+ input$selection,
+ "See all chromosomes" = "for all chromosomes",
+ "Select a region" = paste("for chromosome", selected_chr())
+ )
+ })
+ ##TCGA
+ col_tcga <- reactive({
+ germline_data$coloc_tcga %>%
+ dplyr::filter(chr %in% selected_chr()) %>%
+ dplyr::select("Plot" = plot_type, "SNP" = snp_id, Trait = display, QTL, Gene = gene, `Causal SNPs` = C1C2, Splice = splice, chr, link_plot)
+ })
+
+ output$colocalization_tcga <- DT::renderDT({
+
+ shiny::req(selected_chr())
+
+ DT::datatable(
+ col_tcga() %>% dplyr::select(!link_plot),
+ escape = FALSE,
+ rownames = FALSE,
+ caption = paste("TCGA colocalization plots available ", coloc_label()),
+ selection = 'single',
+ options = list(
+ pageLength = 5,
+ lengthMenu = c(5, 10, 15, 20)
+ )
+ )
+ })
+
+ output$tcga_colocalization_plot <- shiny::renderUI({
+ shiny::req(selected_snp(), input$colocalization_tcga_rows_selected)
+
+ shiny::validate(
+ shiny::need(
+ !is.null(input$colocalization_tcga_rows_selected), "Click on table to see plot"))
+
+ link_plot <- as.character(col_tcga()[input$colocalization_tcga_rows_selected, "link_plot"])
+
+ tags$div(
+ tags$hr(),
+ tags$img(src = link_plot,
+ width = "100%")
+ )
+ })
+
+ ##GTEX
+
+ output$colocalization_gtex <- DT::renderDT({
+ shiny::req(selected_chr())
+
+ DT::datatable(
+ germline_data$coloc_gtex %>%
+ dplyr::filter(chr %in% selected_chr()) %>%
+ dplyr::select("SNP" = snp_id, Trait = display, QTL, Tissue = tissue, Gene = gene, chr),
+ escape = FALSE,
+ rownames = FALSE,
+ caption = paste("GTEX colocalization plots available ", coloc_label()),
+ selection = 'single',
+ options = list(
+ pageLength = 5,
+ lengthMenu = c(5, 10, 15, 20)
+ )
+ )
+ })
+
+ output$gtex_colocalization_plot <- shiny::renderUI({
+ shiny::req(input$colocalization_gtex_rows_selected)
+
+ shiny::validate(
+ shiny::need(
+ !is.null(input$colocalization_gtex_rows_selected), "Click on table to see plot"))
+
+ link_plot <- as.character(germline_data$coloc_gtex[input$colocalization_gtex_rows_selected, "link_plot"])
+
+ tags$div(
+ tags$hr(),
+ tags$p(paste("GTEX Splice ID: ", as.character(germline_data$coloc_gtex[input$colocalization_gtex_rows_selected, "splice"]))),
+ tags$img(src = link_plot,
+ width = "100%")
+ )
+ })
+
+ observeEvent(input$method_link_gwas,{
+ shiny::showModal(modalDialog(
+ title = "Method",
+ includeMarkdown("data/MethodsText/germline-gwas.md"),
+ easyClose = TRUE,
+ footer = NULL
+ ))
+ })
+
+ observeEvent(input$method_link_colocalization,{
+ shiny::showModal(modalDialog(
+ title = "Method",
+ includeMarkdown("data/MethodsText/germline-colocalization.md"),
+ easyClose = TRUE,
+ footer = NULL
+ ))
+ })
+ }
+
diff --git a/modules/germlineheritability.R b/modules/germlineheritability.R
new file mode 100644
index 0000000..398122b
--- /dev/null
+++ b/modules/germlineheritability.R
@@ -0,0 +1,171 @@
+germline_heritability_ui <- function(id){
+
+ ns <- shiny::NS(id)
+ shiny::tagList(
+ messageBox(
+ width = 12,
+ includeMarkdown("data/markdown/germline_heritability.markdown")
+ ),
+ optionsBox(
+ width = 3,
+ shiny::column(
+ width = 12,
+ shiny::selectizeInput(ns("parameter"), "Subset by",
+ choices = c("Ancestry" = "cluster",
+ "Immune Feature" = "display",
+ "Immune Category" = "category",
+ "Immune Module" = "module"
+ ),
+ selected = "Ancestry"),
+ shiny::uiOutput(ns("selection_options")),
+ shiny::sliderInput(ns("pvalue"),
+ "Select p-value threshold",
+ min = 0, max = 0.5, value = 0.05, step = 0.01),
+ shiny::selectizeInput(ns("order_bars"),
+ "Order bars by ",
+ choices = list("V(Genotype)/Vp" = "variance",
+ "LRT p-value" = "p_value",
+ "LRT FDR" = "fdr",
+ "Immune Trait Category" = "category",
+ "Immune Trait Module" = "module",
+ "Ancestry" = "cluster"
+ ),
+ selected = "Variance")
+ )
+ ),
+ plotBox(
+ width = 9,
+ plotly::plotlyOutput(ns("heritability"), height = "700px") %>%
+ shinycssloaders::withSpinner(.)
+ )
+ )
+}
+
+germline_heritability_server <- function(input, output, session){
+
+ ancestry_options <- reactive({
+ c("Ad Mixed American" = "American", "African" = "African", "Asian" = "Asian", "European"= "European", "European by Immune Subtype" = "European_immune")
+ })
+
+ ns <- session$ns
+
+ output$selection_options <- renderUI({
+ shiny::req(input$parameter)
+
+ if(input$parameter == "cluster") opt <- ancestry_options()
+
+ if(input$parameter == "display"){
+ opt <- germline_data$heritability %>%
+ dplyr::select(display,category) %>%
+ dplyr::group_by(category) %>%
+ tidyr::nest(data = c(display))%>%
+ dplyr::mutate(data = purrr::map(data, tibble::deframe)) %>%
+ tibble::deframe()
+ }
+ if(input$parameter == "category") opt <- unique(germline_data$heritability$category)
+ if(input$parameter == "module") opt <- unique(germline_data$heritability$module)
+
+ shiny::selectizeInput(ns("group"), "Show associated results for", choices = opt, selected = opt[4])
+
+ })
+
+ plot_title <- reactive({
+ if(input$parameter == "cluster"){
+ if(input$group != "European_immune") "V(Genotype)/Vp"
+ else "V(Genotype x Immune Subtype)/Vp"
+ } else{
+ paste("V(Genotype)/Vp", input$group, sep = " - ")
+ }
+ })
+
+ hdf <- reactive({
+ shiny::req(input$group)
+ create_heritability_df(
+ heritablity_data = germline_data$heritability,
+ parameter = input$parameter,
+ group = input$group,
+ pval_thres =input$pvalue,
+ ancestry_labels = ancestry_options()
+ )
+ })
+
+ output$heritability <- plotly::renderPlotly({
+ shiny::req(hdf())
+ shiny::validate(
+ shiny::need(nrow(hdf())>0, "No Immune Trait with a p-value lower than selected.")
+ )
+
+ #order bars
+ if(is.numeric(hdf()[[input$order_bars]])) plot_levels <-levels(reorder(hdf()[["ylabel"]], hdf()[[input$order_bars]], sort))
+ else plot_levels <- (hdf() %>%
+ dplyr::arrange(.[[input$order_bars]], variance))$ylabel %>%
+ as.factor()
+
+
+ hdf() %>%
+ dplyr::mutate('Neg_log10_p_value' = -log10(p_value)) %>% #changing column name to legend title display
+ create_barplot_horizontal(
+ df = .,
+ x_col = "variance",
+ y_col = "ylabel",
+ error_col = "se",
+ key_col = NA,
+ color_col = "Neg_log10_p_value",
+ label_col = "label",
+ xlab = "Heritability",
+ ylab = "",
+ order_by = plot_levels,
+ title = plot_title(),
+ showLegend = TRUE,
+ legendTitle = "LRT \n p-value",
+ source_name = "heritability_plot",
+ bar_colors = NULL
+ ) %>%
+ format_heritability_plot(., hdf(), fdr = TRUE)
+ })
+
+ # output$heritability_cov <- plotly::renderPlotly({
+ #
+ # eventdata <- plotly::event_data( "plotly_click", source = "heritability_plot")
+ # sub_clusters <- c("Covar:Immune Subtype", "C1", "C2", "C3")
+ #
+ # shiny::validate(
+ # shiny::need(!is.null(eventdata),
+ # "Click bar plot"))
+ # selected_plot_trait <- eventdata$y[[1]]
+ #
+ # hdf_plot <- germline_data$heritability %>%
+ # dplyr::filter(cluster %in% sub_clusters & display == selected_plot_trait)
+ #
+ # plot_colors <- c("#bebebe", "#FF0000", "#FFFF00", "#00FF00")
+ # names(plot_colors) <- sub_clusters
+ #
+ # hdf_plot$cluster <- factor(hdf_plot$cluster, levels = c("C3", "C2", "C1", "Covar:Immune Subtype" ))
+ #
+ # create_barplot_horizontal(
+ # df = hdf_plot,
+ # x_col = "Variance",
+ # y_col = "cluster",
+ # error_col = "SE",
+ # key_col = NA,
+ # color_col = "cluster",
+ # label_col = NA,
+ # xlab = "Heritability",
+ # ylab = "",
+ # title = paste("Random data for", selected_plot_trait),
+ # showLegend = FALSE,
+ # source_name = NULL,
+ # bar_colors = plot_colors
+ # ) %>%
+ # format_heritability_plot(., hdf_plot, fdr = FALSE)
+ # })
+
+ observeEvent(input$method_link,{
+ shiny::showModal(modalDialog(
+ title = "Method",
+ includeMarkdown("data/MethodsText/germline-heritability.md"),
+ easyClose = TRUE,
+ footer = NULL
+ ))
+ })
+}
diff --git a/modules/germlinemodule.R b/modules/germlinemodule.R
new file mode 100644
index 0000000..5df222e
--- /dev/null
+++ b/modules/germlinemodule.R
@@ -0,0 +1,44 @@
+germline_ui <- function(id){
+
+ ns <- shiny::NS(id)
+
+ shiny::tagList(
+ titleBox(
+ "iAtlas Explorer — Germline Analysis"
+ ),
+ textBox(
+ width = 12,
+ p("This module provides interactive visualizations related to the manuscript ",
+ a(href = "https://doi.org/10.1016/j.immuni.2021.01.011", "Sayaman et al., Germline genetic contribution to the immune landscape of cancer, Immunity (2021)")),
+ p("Explore the germline genetic contribution to the immune landscape of cancer with results of heritability analysis, GWAS, and rare variant analysis across 30 non-hematological cancer types characterized by the TCGA. All analyses are adjusted for cancer type, age at diagnosis, sex, and the first seven components from principal component analysis (PCA) done on SNP data, which capture overall genetic ancestry.")
+ ),
+ sectionBox(
+ title = "Heritability",
+ germline_heritability_ui(ns("germline_heritability"))
+ ),
+ sectionBox(
+ title = "GWAS",
+ germline_gwas_ui(ns("germline_gwas-module"))
+ ),
+ sectionBox(
+ title = "Rare Variants",
+ germline_rarevariants_ui(ns("germline_rarevariants"))
+ )
+ )
+}
+
+germline_server <- function(input, output, session){
+
+ callModule(
+ germline_heritability_server,
+ "germline_heritability"
+ )
+ callModule(
+ germline_gwas_server,
+ "germline_gwas-module"
+ )
+ callModule(
+ germline_rarevariants_server,
+ "germline_rarevariants"
+ )
+}
\ No newline at end of file
diff --git a/modules/germlinerarevariants.R b/modules/germlinerarevariants.R
new file mode 100644
index 0000000..3475af6
--- /dev/null
+++ b/modules/germlinerarevariants.R
@@ -0,0 +1,113 @@
+germline_rarevariants_ui <- function(id){
+
+ ns <- shiny::NS(id)
+ shiny::tagList(
+ messageBox(
+ width = 12,
+ shiny::p("The boxplots show the values of selected immune traits across samples with germline mutations in genes belonging to defined functional categories, or pathways."),
+ shiny::p("We performed association analyses between germline pathogenic and likely pathogenic cancer predisposition variants in high penetrance susceptibility genes, and immune traits and immune
+ subtypes. Since mutations in most of the genes were rare we collapsed genes into categories summarizing different biologic processes or functions, when possible."),
+ shiny::actionLink(ns("method_link"), "Click to view method description.")
+ ),
+ optionsBox(
+ width = 12,
+ shiny::column(
+ width = 8,
+ shiny::uiOutput(ns("features"))
+ ),
+ shiny::column(
+ width = 4,
+ shiny::selectizeInput(ns("order_box"),
+ "Order plot by ",
+ choices = list(
+ "p-value" = "p_value",
+ "Median" = "q2",
+ "Mean" = "mean",
+ "Min" = "min",
+ "Max" = "max",
+ "Number of patients with mutation" = "n_mutations"
+ ),
+ selected = "p_value")
+ )
+ ),
+ plotBox(
+ width = 12,
+ plotly::plotlyOutput(ns("dist_plot"), height = "700px") %>%
+ shinycssloaders::withSpinner(.)
+ ),
+ messageBox(
+ width = 3,
+ shiny::p("Tests comparing a pathway group with all other groups were performed.
+ In the Pathway column, 'Multiple' refers to samples with mutation in more than one pathway; and 'No defect' refers to samples with no mutation in the studied pathways.")
+ ),
+ plotBox(
+ width = 9,
+ DT::dataTableOutput(ns("stats_tbl"))
+ )
+
+ )
+}
+
+germline_rarevariants_server <- function(input, output, session) {
+
+ ns <- session$ns
+
+ output$features <- renderUI({
+
+ trait_choices <- germline_data$rare_variants %>%
+ dplyr::select(display,category) %>%
+ dplyr::group_by(category) %>%
+ tidyr::nest(data = c(display))%>%
+ dplyr::mutate(data = purrr::map(data, tibble::deframe)) %>%
+ tibble::deframe()
+
+ shiny::selectInput(ns("feature"),
+ "Search and select Immune Trait",
+ choices = trait_choices,
+ selected = trait_choices[1])
+ })
+
+ selected_data <- reactive({
+ germline_data$rare_variants %>%
+ dplyr::filter(display == input$feature)
+ })
+
+ output$dist_plot <- plotly::renderPlotly({
+ shiny::req(input$feature)
+
+ df <- selected_data() %>% tidyr::drop_na()
+ plot_levels <- (df %>% dplyr::arrange(desc(.[[input$order_box]])))$pathway
+
+ create_boxplot_from_summary_stats(
+ df,
+ "pathway",
+ "q1",
+ "q2",
+ "q3",
+ "min",
+ "max",
+ "mean",
+ order_by = plot_levels#,
+ #color_col = "p_value"#,
+ # fill_colors = bar_colors
+ )
+ })
+
+ output$stats_tbl <- DT::renderDataTable({
+ shiny::req(input$feature)
+ DT::datatable(
+ selected_data() %>% dplyr::select(Pathway = pathway, 'Patients with mutation' = n_mutations, 'Total patients' = n, 'p-value' = p_value) ,
+ rownames = FALSE,
+ options = list(order = list(3, 'asc'))
+ ) %>% DT::formatRound(columns= "p-value", digits=3)
+ })
+
+ observeEvent(input$method_link,{
+ shiny::showModal(modalDialog(
+ title = "Method",
+ includeMarkdown("data/MethodsText/germline-rarevariants.md"),
+ easyClose = TRUE,
+ footer = NULL
+ ))
+ })
+}
\ No newline at end of file
diff --git a/pages/explorepage.R b/pages/explorepage.R
index b89cdcd..fc167b5 100644
--- a/pages/explorepage.R
+++ b/pages/explorepage.R
@@ -61,17 +61,22 @@ explorepage <- dashboardPage(
tabName = "cnvs",
icon = icon("cog")
),
+ menuSubItem(
+ "Germline Analysis",
+ tabName = "germline",
+ icon = icon("cog")
+ ),
menuSubItem(
"Extracellular Networks",
tabName = "cytokine_network",
- icon = icon("cog")
- ),
- menuSubItem(
- "Cell-Interaction Diagram",
- tabName = "cell_image",
- icon = icon("cog")
- )
- ),
+ icon = icon("cog")
+ ),
+ menuSubItem(
+ "Cell-Interaction Diagram",
+ tabName = "cell_image",
+ icon = icon("cog")
+ )
+ ),
menuItem("Molecular Response to ICI",
icon = icon("bar-chart"), startExpanded = TRUE,
menuSubItem(
@@ -264,10 +269,10 @@ explorepage <- dashboardPage(
),
imgLinkBox(
width = 6,
- title = "Extracellular Networks",
- linkId = "link_to_module11",
- imgSrc = "images/cytokinenet.png",
- boxText = "Explore the extracellular networks modulating tumoral immune response.",
+ title = "Germline Analysis",
+ linkId = "link_to_germline",
+ imgSrc = "images/germline.png",
+ boxText = "Explore the germline genetic contribution to the immune landscape of cancer.",
linkText = "Open Module"
)
),
@@ -279,6 +284,14 @@ explorepage <- dashboardPage(
imgSrc = "images/cell-image.png",
boxText = "Explore cell and protein abundance on an illustration.",
linkText = "Open Module"
+ ),
+ imgLinkBox(
+ width = 6,
+ title = "Extracellular Networks",
+ linkId = "link_to_module11",
+ imgSrc = "images/cytokinenet.png",
+ boxText = "Explore the extracellular networks modulating tumoral immune response.",
+ linkText = "Open Module"
)
)
),
@@ -385,6 +398,10 @@ explorepage <- dashboardPage(
tabName = "cell_image",
cellimage_UI("module12")
),
+ tabItem(
+ tabName = "germline",
+ germline_ui("germline")
+ ),
tabItem(
tabName = "ioresponse_overview",
ioresponseoverview_UI("io_response_overview")
diff --git a/renv.lock b/renv.lock
index 93bd243..3492d43 100644
--- a/renv.lock
+++ b/renv.lock
@@ -1,6 +1,6 @@
{
"R": {
- "Version": "4.0.2",
+ "Version": "4.0.3",
"Repositories": [
{
"Name": "CRAN",
@@ -29,7 +29,7 @@
]
},
"Bioconductor": {
- "Version": "3.11"
+ "Version": "3.10"
},
"Packages": {
"AnnotationDbi": {
@@ -66,9 +66,9 @@
},
"BiocParallel": {
"Package": "BiocParallel",
- "Version": "1.20.0",
+ "Version": "1.20.1",
"Source": "Bioconductor",
- "Hash": "03d8e08a5402feac792d7165ad55fcfb"
+ "Hash": "744ce1b8f59ad5827fe03f30a4fe8e50"
},
"BiocVersion": {
"Package": "BiocVersion",
@@ -76,12 +76,18 @@
"Source": "Bioconductor",
"Hash": "b69e4e634db423b8e6c58103d579ec95"
},
+ "Biostrings": {
+ "Package": "Biostrings",
+ "Version": "2.54.0",
+ "Source": "Bioconductor",
+ "Hash": "edf03f0e37fc3c09c95dcf8bf3900972"
+ },
"Cairo": {
"Package": "Cairo",
"Version": "1.5-12",
"Source": "Repository",
"Repository": "CRAN",
- "Hash": "3cf79cef0ec215d7cfdf9f7edc26bbae"
+ "Hash": "a44aec693253e4eb6c45d2fd789091a0"
},
"DBI": {
"Package": "DBI",
@@ -104,11 +110,41 @@
"Repository": "CRAN",
"Hash": "bc7ee1e8b4cb953b4d17c17c5c1351ca"
},
+ "DelayedArray": {
+ "Package": "DelayedArray",
+ "Version": "0.12.3",
+ "Source": "Bioconductor",
+ "Hash": "b6d613d1e53206ce39aa7a27a1704486"
+ },
+ "GenomeInfoDb": {
+ "Package": "GenomeInfoDb",
+ "Version": "1.22.1",
+ "Source": "Bioconductor",
+ "Hash": "df46d6ce62f1e897fecbfc5e847d823c"
+ },
+ "GenomeInfoDbData": {
+ "Package": "GenomeInfoDbData",
+ "Version": "1.2.2",
+ "Source": "Bioconductor",
+ "Hash": "de42132c04371f624cdea8de86e8fc5d"
+ },
+ "GenomicAlignments": {
+ "Package": "GenomicAlignments",
+ "Version": "1.22.1",
+ "Source": "Bioconductor",
+ "Hash": "0bc774dd3636e0aff56a80da6f928211"
+ },
+ "GenomicRanges": {
+ "Package": "GenomicRanges",
+ "Version": "1.38.0",
+ "Source": "Bioconductor",
+ "Hash": "8ff54983afa8eda100fa0fcadd6816bf"
+ },
"IRanges": {
"Package": "IRanges",
- "Version": "2.20.1",
+ "Version": "2.20.2",
"Source": "Bioconductor",
- "Hash": "a17a0b4e2169f7d449138a114376a81d"
+ "Hash": "148fe882b25f679b03afc45da15e760c"
},
"ImmuneSubtypeClassifier": {
"Package": "ImmuneSubtypeClassifier",
@@ -120,7 +156,7 @@
"RemoteRepo": "ImmuneSubtypeClassifier",
"RemoteRef": "master",
"RemoteSha": "2257fee0db18cfcc79356e567801e062fff67124",
- "Hash": "a47ebf36879302c80a0e4b001a12db8c"
+ "Hash": "cb96674accfcf410cf6c97868dd5730f"
},
"KMsurv": {
"Package": "KMsurv",
@@ -220,11 +256,43 @@
"Repository": "CRAN",
"Hash": "f3ca785924863b0e4c8cb23b6a5c75a1"
},
+ "Rhtslib": {
+ "Package": "Rhtslib",
+ "Version": "1.18.1",
+ "Source": "Bioconductor",
+ "Hash": "70d3c447ca9f22a8f0b07328dbe32421"
+ },
+ "Rsamtools": {
+ "Package": "Rsamtools",
+ "Version": "2.2.3",
+ "Source": "Bioconductor",
+ "Hash": "6d7d5bb29dd9bb69bfabccfa595a8a53"
+ },
+ "Rtsne": {
+ "Package": "Rtsne",
+ "Version": "0.15",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Hash": "f153432c4ca15b937ccfaa40f167c892"
+ },
"S4Vectors": {
"Package": "S4Vectors",
- "Version": "0.24.1",
+ "Version": "0.24.4",
+ "Source": "Bioconductor",
+ "Hash": "e338665aea0ba0bbf7615d318b2eccee"
+ },
+ "SummarizedExperiment": {
+ "Package": "SummarizedExperiment",
+ "Version": "1.16.1",
"Source": "Bioconductor",
- "Hash": "57d4fa11a8f7fd2f87b444a5de69b113"
+ "Hash": "1f4c0859b8f338bd9f8c0b7967e719a3"
+ },
+ "V8": {
+ "Package": "V8",
+ "Version": "3.4.0",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Hash": "8c5e8c58ff4fc8dfc67e24985005159b"
},
"XML": {
"Package": "XML",
@@ -233,6 +301,12 @@
"Repository": "CRAN",
"Hash": "0ec6acb7f3e2f376ca6b9541b9709107"
},
+ "XVector": {
+ "Package": "XVector",
+ "Version": "0.26.0",
+ "Source": "Bioconductor",
+ "Hash": "b72b7c53049b71fbfd0792fb7ec66987"
+ },
"amap": {
"Package": "amap",
"Version": "0.8-17",
@@ -481,8 +555,8 @@
"Source": "GitHub",
"RemoteType": "github",
"RemoteHost": "api.github.com",
- "RemoteUsername": "cytoscape",
"RemoteRepo": "cyjShiny",
+ "RemoteUsername": "cytoscape",
"RemoteRef": "master",
"RemoteSha": "956a3cb5a8f709f4134f9774e6a767ce2b141764",
"Hash": "53ef28c7c9683859e9c4de113d3e6968"
@@ -548,7 +622,7 @@
"Version": "1.0.0",
"Source": "Repository",
"Repository": "CRAN",
- "Hash": "c426258a806b7e69613432b197b9954d"
+ "Hash": "4011f62581a34080e44105d4aa05a97f"
},
"ellipsis": {
"Package": "ellipsis",
@@ -750,7 +824,7 @@
"Version": "1.4.2",
"Source": "Repository",
"Repository": "CRAN",
- "Hash": "d4e25697c450c01b202c79ef35694a83"
+ "Hash": "6efd734b14c6471cfe443345f3e35e29"
},
"googlesheets": {
"Package": "googlesheets",
@@ -856,6 +930,18 @@
"Repository": "CRAN",
"Hash": "7146fea4685b4252ebf478978c75f597"
},
+ "igvShiny": {
+ "Package": "igvShiny",
+ "Version": "1.2.14",
+ "Source": "GitHub",
+ "RemoteType": "github",
+ "RemoteHost": "api.github.com",
+ "RemoteUsername": "heimannch",
+ "RemoteRepo": "igvShiny",
+ "RemoteRef": "master",
+ "RemoteSha": "642e33ac94db2796d82ec208302e64fe4642fbf3",
+ "Hash": "5b13358b0994548a8f1f1fb891f57e70"
+ },
"ini": {
"Package": "ini",
"Version": "0.3.1",
@@ -938,7 +1024,7 @@
"Version": "0.2.0",
"Source": "Repository",
"Repository": "CRAN",
- "Hash": "dc0e9c03b3635ff433b045ce6bf0612d"
+ "Hash": "361811f31f71f8a617a9a68bf63f1f42"
},
"limma": {
"Package": "limma",
@@ -1126,7 +1212,7 @@
"Version": "4.9.2.1",
"Source": "Repository",
"Repository": "CRAN",
- "Hash": "286590ead74fada39b8dc0b47e118b0b"
+ "Hash": "b08edf378e0e38959a6983e3d5902795"
},
"plyr": {
"Package": "plyr",
@@ -1226,6 +1312,13 @@
"Repository": "CRAN",
"Hash": "22aca7d1181718e927d403a8c2d69d62"
},
+ "randomcoloR": {
+ "Package": "randomcoloR",
+ "Version": "1.1.0.1",
+ "Source": "Repository",
+ "Repository": "CRAN",
+ "Hash": "dd08bb0be91b93194fa944b68b3bccb0"
+ },
"rapidjsonr": {
"Package": "rapidjsonr",
"Version": "1.1",
@@ -1277,7 +1370,8 @@
"RemoteUsername": "rstudio",
"RemoteRepo": "renv",
"RemoteRef": "0.9.3-3",
- "RemoteSha": "4fd2ea4975f9946afae7691315b9a8c6bfabd8b3"
+ "RemoteSha": "4fd2ea4975f9946afae7691315b9a8c6bfabd8b3",
+ "Hash": "63232c4242a6d1c0d35eb6bdf7015308"
},
"reprex": {
"Package": "reprex",
@@ -1305,7 +1399,7 @@
"Version": "0.4.8",
"Source": "Repository",
"Repository": "CRAN",
- "Hash": "ff31d958a041593f58ba04fc637d90dd"
+ "Hash": "843a6af51414bce7f8a8e372f11d6cd0"
},
"rmarkdown": {
"Package": "rmarkdown",
@@ -1361,6 +1455,12 @@
"Repository": "CRAN",
"Hash": "da31c988698b91fdf6a3e2317679d6cb"
},
+ "rtracklayer": {
+ "Package": "rtracklayer",
+ "Version": "1.46.0",
+ "Source": "Bioconductor",
+ "Hash": "a635995c99bc0e67fd23167f859893af"
+ },
"rversions": {
"Package": "rversions",
"Version": "2.0.0",
@@ -1537,10 +1637,10 @@
},
"tidyselect": {
"Package": "tidyselect",
- "Version": "0.2.5",
+ "Version": "1.1.0",
"Source": "Repository",
"Repository": "CRAN",
- "Hash": "971842fead8ee9e150495a0ede343a98"
+ "Hash": "6ea435c354e8448819627cf686f66e0a"
},
"tidyverse": {
"Package": "tidyverse",
@@ -1582,7 +1682,7 @@
"Version": "0.3.4",
"Source": "Repository",
"Repository": "CRAN",
- "Hash": "5c2d0fe441406cba811b46708ea28e41"
+ "Hash": "0bc90078aeee42f2520b1d0a33bd6758"
},
"viridis": {
"Package": "viridis",
@@ -1668,6 +1768,12 @@
"Repository": "CRAN",
"Hash": "ee9b643aa8331c45d8d82eb3a137c9bc"
},
+ "zlibbioc": {
+ "Package": "zlibbioc",
+ "Version": "1.32.0",
+ "Source": "Bioconductor",
+ "Hash": "f7a31247eadfb45098bcf2e8c4aebb49"
+ },
"zoo": {
"Package": "zoo",
"Version": "1.8-6",
diff --git a/server.R b/server.R
index facd6b7..d46d6d4 100644
--- a/server.R
+++ b/server.R
@@ -141,6 +141,11 @@ shinyServer(function(input, output, session) {
reactive(subset_df()),
reactive(plot_colors()))
+ # Germline
+ callModule(
+ germline_server,
+ "germline")
+
#IO Molecular Response Overview
callModule(
ioresponseoverview,
@@ -222,6 +227,9 @@ shinyServer(function(input, output, session) {
observeEvent(input$link_to_module12, {
shinydashboard::updateTabItems(session, "explorertabs", "cell_image")
})
+ observeEvent(input$link_to_germline, {
+ shinydashboard::updateTabItems(session, "explorertabs", "germline")
+ })
observeEvent(input$link_to_io_response_overview, {
shinydashboard::updateTabItems(session, "explorertabs", "ioresponse_overview")
})
diff --git a/www/images/germline.png b/www/images/germline.png
new file mode 100644
index 0000000..1bebb50
Binary files /dev/null and b/www/images/germline.png differ