Nothing
#' GeneTonic
#'
#' GeneTonic, main function for the Shiny app
#'
#' @param dds A `DESeqDataSet` object, normally obtained after running your data
#' through the `DESeq2` framework.
#' @param res_de A `DESeqResults` object. As for the `dds` parameter, this is
#' also commonly used in the `DESeq2` framework.
#' @param res_enrich A `data.frame` object, storing the result of the functional
#' enrichment analysis. Required columns for enjoying the full functionality of
#' [GeneTonic()] include:
#' - a gene set identifier (e.g. GeneOntology id, `gs_id`) and its term description
#' (`gs_description`)
#' - a numeric value for the significance of the enrichment (`gs_pvalue`)
#' - a column named `gs_genes` containing a comma separated vector of the gene names
#' associated to the term, one for each term
#' - the number of genes in the geneset of interest detected as differentially
#' expressed (`gs_de_count`), or in the background set of genes (`gs_bg_count`)
#' See [shake_topGOtableResult()] or [shake_enrichResult()] for examples of such
#' formatting helpers
#' @param annotation_obj A `data.frame` object, containing two columns, `gene_id`
#' with a set of unambiguous identifiers (e.g. ENSEMBL ids) and `gene_name`,
#' containing e.g. HGNC-based gene symbols. This object can be constructed via
#' the `org.eg.XX.db` packages, e.g. with convenience functions such as
#' [pcaExplorer::get_annotation_orgdb()].
#' @param project_id A character string, which can be considered as an identifier
#' for the set/session, and will be e.g. used in the title of the report created
#' via [happy_hour()]
#'
#' @return A Shiny app object is returned, for interactive data exploration
#' @export
#'
#' @author Federico Marini
#'
#' @examples
#' library("macrophage")
#' library("DESeq2")
#' library("org.Hs.eg.db")
#' library("AnnotationDbi")
#'
#' # dds object
#' data("gse", package = "macrophage")
#' dds_macrophage <- DESeqDataSet(gse, design = ~line + condition)
#' rownames(dds_macrophage) <- substr(rownames(dds_macrophage), 1, 15)
#' dds_macrophage <- estimateSizeFactors(dds_macrophage)
#'
#' # annotation object
#' anno_df <- data.frame(
#' gene_id = rownames(dds_macrophage),
#' gene_name = mapIds(org.Hs.eg.db,
#' keys = rownames(dds_macrophage),
#' column = "SYMBOL",
#' keytype = "ENSEMBL"),
#' stringsAsFactors = FALSE,
#' row.names = rownames(dds_macrophage)
#' )
#'
#' # res object
#' data(res_de_macrophage, package = "GeneTonic")
#' res_de <- res_macrophage_IFNg_vs_naive
#'
#' # res_enrich object
#' data(res_enrich_macrophage, package = "GeneTonic")
#' res_enrich <- shake_topGOtableResult(topgoDE_macrophage_IFNg_vs_naive)
#' res_enrich <- get_aggrscores(res_enrich, res_de, anno_df)
#'
#' # now everything is in place to launch the app
#' if (interactive())
#' GeneTonic(dds = dds_macrophage,
#' res_de = res_de,
#' res_enrich = res_enrich,
#' annotation_obj = anno_df,
#' project_id = "myexample")
#'
GeneTonic <- function(dds,
res_de,
res_enrich,
annotation_obj,
project_id = "") {
# https://projects.lukehaas.me/css-loaders/
# or even think of https://cran.r-project.org/web/packages/shinycustomloader/README.html
oopt <- options(spinner.type = 6, spinner.color = .biocgreen)
# play nice with other previously chosen options
on.exit(options(oopt))
usage_mode <- "shiny_mode"
# checks on the objects provided
checkup_GeneTonic(dds,
res_de,
res_enrich,
annotation_obj)
# clean up the result object, e.g. removing the NAs in the relevant columns
res_de <- res_de[!is.na(res_de$log2FoldChange), ]
message("Removing ", sum(is.na(res_de$log2FoldChange)), " rows from the result object - logFC detected as NA")
# UI definition -----------------------------------------------------------
# dashpage definition -----------------------------------------------------
genetonic_ui <- bs4Dash::bs4DashPage(
# enable_preloader = TRUE,
title = "GeneTonic",
sidebar_collapsed = TRUE,
controlbar_collapsed = TRUE,
# navbar definition -------------------------------------------------------
navbar = bs4Dash::bs4DashNavbar(
skin = "dark",
controlbarIcon = "gears",
fixed = TRUE,
leftUi = tagList(
tags$code(tags$h3("GeneTonic")),
actionButton("bookmarker", label = "Bookmark", icon = icon("heart"),
style = "color: #ffffff; background-color: #ac0000; border-color: #ffffff", class = "ml-5")
),
rightUi = tagList(
shinyWidgets::dropdownButton(
inputId = "ddbtn_docs",
circle = FALSE,
status = "info",
icon = icon("book"),
width = "300px",
size = "xs",
right = TRUE,
tooltip = shinyWidgets::tooltipOptions(title = "More documentation"),
tags$h5("Documentation"),
actionButton(
inputId = "btn_docs_vignette",
icon = icon("book-open"),
label = "Open GeneTonic Vignette", style = .actionbutton_biocstyle,
onclick = ifelse(system.file("doc", "GeneTonic_manual.html", package = "GeneTonic") != "",
"",
"window.open('https://federicomarini.github.io/GeneTonic/articles/GeneTonic_manual.html', '_blank')")
# sprintf("window.open('http://bioconductor.org/packages/%s/bioc/vignettes/GeneTonic/inst/doc/GeneTonic_manual.html', '_blank')",
# ifelse(unlist(packageVersion("GeneTonic"))[2] %% 2L==0L, "release", "devel")
# )
# )
),
actionButton(
inputId = "btn_first_help",
icon = icon("question-circle"),
label = "First Help", style = .actionbutton_biocstyle
)
),
shinyWidgets::dropdownButton(
inputId = "ddbtn_info",
circle = FALSE,
status = "info",
icon = icon("info"),
width = "300px",
size = "xs",
right = TRUE,
tooltip = shinyWidgets::tooltipOptions(title = "More info!"),
tags$h5("Additional information"),
actionButton(
inputId = "btn_info_session",
icon = icon("info-circle"),
label = "About this session", style = .actionbutton_biocstyle
),
actionButton(
inputId = "btn_info_genetonic",
icon = icon("heart"),
label = "About GeneTonic", style = .actionbutton_biocstyle
)
)
)
),
# sidebar definition ------------------------------------------------------
sidebar = bs4Dash::bs4DashSidebar(
title = HTML("<small>GeneTonic</small>"),
src = "GeneTonic/GeneTonic.png",
skin = "dark",
status = "primary",
brandColor = NULL,
url = "https://bioconductor.org/packages/GeneTonic",
# src = "logos/online-learning.png",
elevation = 1,
opacity = 0.8,
bs4SidebarMenu(
id = "gt_tabs",
bs4SidebarMenuItem(
"Welcome!",
tabName = "tab_welcome",
icon = "home"
),
bs4SidebarMenuItem(
"Gene-Geneset",
tabName = "tab_ggs",
icon = "share-alt-square"
),
bs4SidebarMenuItem(
"Enrichment Map",
tabName = "tab_emap",
icon = "project-diagram" # hubspot? map?
),
bs4SidebarMenuItem(
"Overview",
tabName = "tab_overview",
icon = "eye"
),
bs4SidebarMenuItem(
"GSViz",
tabName = "tab_gsviz",
icon = "images"
),
bs4SidebarMenuItem(
"Bookmarks",
tabName = "tab_bookmarks",
icon = "bookmark"
)
)
),
# body definition ---------------------------------------------------------
body = bs4Dash::bs4DashBody(
rintrojs::introjsUI(),
## Define output size and style of error messages
## plus, define the myscrollbox div to prevent y overflow when page fills up
tags$head(
tags$style(
HTML(
".shiny-output-error-validation {
font-size: 15px;
color: forestgreen;
text-align: center;
}
#myScrollBox{
overflow-y: scroll;
.dataTables_wrapper{
overflow-x: scroll;
}
}
"
)
)
),
tags$head(
tags$style(
".biocdlbutton{background-color:#0092AC;} .biocdlbutton{color: #ffffff;}"
)
),
tags$script(HTML("$(function(){
$(document).keyup(function(e) {
if (e.which == 17) {
$('#bookmarker').click()
}
});
})")),
# 27: esc, works
# 60, <, works NOT1
# 17, ctrl left, works
# see more here:
# https://stackoverflow.com/questions/41675059/keyboard-shortcuts-to-trigger-reactive-flows-in-r-shiny
# https://stackoverflow.com/questions/10655202/detect-multiple-keys-on-single-keypress-event-in-jquery
# http://keycode.info/
bs4TabItems(
# ui panel welcome -----------------------------------------------------------
bs4TabItem(
tabName = "tab_welcome",
fluidRow(
column(
width = 11
),
column(
width = 1,
actionButton(
"tour_firststeps", label = "", icon = icon("question-circle"),
style = .helpbutton_biocstyle
)
)
),
fluidRow(
h2("Overview on the provided input")
),
fluidRow(
bs4Dash::bs4Card(
width = 6,
inputId = "card_em",
title = "Expression Matrix",
status = "danger",
solidHeader = FALSE,
collapsible = TRUE,
collapsed = TRUE,
closable = FALSE,
DT::dataTableOutput("overview_dds")
),
bs4Dash::bs4Card(
width = 6,
inputId = "card_de",
title = "DE results",
status = "warning",
solidHeader = FALSE,
collapsible = TRUE,
collapsed = TRUE,
closable = FALSE,
DT::dataTableOutput("overview_res_de")
),
bs4Dash::bs4Card(
width = 6,
inputId = "card_enrich",
title = "Functional analysis results",
status = "success",
solidHeader = FALSE,
collapsible = TRUE,
collapsed = TRUE,
closable = FALSE,
DT::dataTableOutput("overview_res_enrich")
),
bs4Dash::bs4Card(
width = 6,
inputId = "card_anno",
title = "Annotation info",
status = "info",
solidHeader = FALSE,
collapsible = TRUE,
collapsed = TRUE,
closable = FALSE,
DT::dataTableOutput("overview_annotation")
)
),
uiOutput("ui_infoboxes")
),
# ui panel geneset-gene ---------------------------------------------------
bs4TabItem(
tabName = "tab_ggs",
fluidRow(
column(
width = 11
),
column(
width = 1,
actionButton(
"tour_ggs", label = "", icon = icon("question-circle"),
style = .helpbutton_biocstyle
)
)
),
fluidRow(
column(
width = 8,
withSpinner(
visNetworkOutput("ggsnetwork",
height = "700px",
width = "100%")
)
),
column(
width = 4,
bs4Card(
title = "Geneset Box",
width = 12,
closable = FALSE,
uiOutput("ui_ggs_genesetbox")
),
# box(),
hr(),
bs4Card(
title = "Gene Box",
width = 12,
closable = FALSE,
uiOutput("ui_ggs_genebox")
)
)
)
),
# ui panel enrichment map -------------------------------------------------
bs4TabItem(
tabName = "tab_emap",
fluidRow(
column(
width = 11
),
column(
width = 1,
actionButton(
"tour_emap", label = "", icon = icon("question-circle"),
style = .helpbutton_biocstyle
)
)
),
fluidRow(
column(
width = 8,
withSpinner(
tagList(
selectInput(
inputId = "emap_colorby",
label = "Color emap by",
choices = colnames(res_enrich)[unlist(lapply(res_enrich, is.numeric))],
selected = "gs_pvalue"),
visNetworkOutput("emap_visnet",
height = "700px",
width = "100%")
)
)
),
column(
width = 4,
bs4Card(
title = "Geneset Box",
width = 12,
closable = FALSE,
uiOutput("ui_emap_sidecontent")
)
)
),
fluidRow(
bs4Dash::bs4Card(
width = 12,
inputId = "card_distillery",
title = "Geneset distillery",
status = "info",
solidHeader = FALSE,
collapsible = TRUE,
collapsed = TRUE,
closable = FALSE,
fluidRow(
column(
width = 8,
withSpinner(
DT::dataTableOutput("dt_distill")
),
uiOutput("distill_launch"),
numericInput(
inputId = "n_genesets_distill",
label = "Number of genesets",
value = min(50, nrow(res_enrich)), min = 1, max = nrow(res_enrich)
)
),
column(
width = 4,
bs4Card(
title = "Meta-geneset Box",
width = 12,
closable = FALSE,
uiOutput("ui_metags_sidecontent")
)
)
)
)
)
),
# ui panel overview --------------------------------------------------------
bs4TabItem(
tabName = "tab_overview",
fluidRow(
column(
width = 11
),
column(
width = 1,
actionButton(
"tour_overview", label = "", icon = icon("question-circle"),
style = .helpbutton_biocstyle
)
)
),
fluidRow(
bs4Dash::column(
width = 11,
offset = 0,
bs4Dash::bs4TabCard(
id = "tabcard_deview",
title = "Overview",
side = "right",
elevation = 2,
width = 12,
closable = FALSE,
bs4TabPanel(
tabName = "Geneset Volcano",
active = TRUE,
withSpinner(plotOutput("gs_volcano",
height = "650px"))
),
bs4TabPanel(
tabName = "Geneset Volcano - simplified",
active = FALSE,
numericInput(inputId = "gs_overlap",
label = "Gene Set overlap",
value = 0.6, min = 0, max = 1, step = 0.05),
withSpinner(plotOutput("gs_volcano_simplified",
height = "650px"))
),
bs4TabPanel(
tabName = "Enhanced Table",
active = FALSE,
withSpinner(plotOutput("enriched_funcres",
height = "650px"))
),
bs4TabPanel(
tabName = "Enhanced Table - interactive",
active = FALSE,
withSpinner(plotlyOutput("enriched_funcres_plotly",
height = "650px"))
)
)
)
)
),
# ui panel GSViz ------------------------------------------------------
bs4TabItem(
tabName = "tab_gsviz",
fluidRow(
column(
width = 11
),
column(
width = 1,
actionButton(
"tour_gsviz", label = "", icon = icon("question-circle"),
style = .helpbutton_biocstyle
)
)
),
fluidRow(
bs4Dash::column(
width = 11,
offset = 0,
bs4Dash::bs4TabCard(
id = "tabcard_genesets",
title = "GSViz",
side = "right",
elevation = 2,
width = 12,
closable = FALSE,
bs4TabPanel(
tabName = "Scores Heatmap",
active = TRUE,
withSpinner(plotOutput("gsscores_heatmap",
height = "650px"))
),
bs4TabPanel(
tabName = "Alluvial Plot",
active = FALSE,
withSpinner(plotlyOutput("alluvial_genesets",
height = "650px"))
),
bs4TabPanel(
tabName = "Summary Heatmap",
active = FALSE,
withSpinner(plotOutput("gs_summaryheat",
height = "650px"))
),
bs4TabPanel(
tabName = "Geneset MDS",
active = FALSE,
withSpinner(plotOutput("mds_genesets",
height = "650px"))
),
bs4TabPanel(
tabName = "Summary Overview",
active = FALSE,
withSpinner(plotOutput("gs_summaryoverview",
height = "650px"))
),
bs4TabPanel(
tabName = "Geneset Radar",
active = FALSE,
withSpinner(plotlyOutput("gs_summaryradar",
height = "650px"))
),
bs4TabPanel(
tabName = "Geneset Dendrogram",
active = FALSE,
withSpinner(plotOutput("gs_dendro",
height = "650px"))
)
)
)
)
),
# ui panel bookmark ------------------------------------------------------
bs4TabItem(
tabName = "tab_bookmarks",
fluidRow(
column(
width = 11
),
column(
width = 1,
actionButton(
"tour_bookmarks", label = "", icon = icon("question-circle"),
style = .helpbutton_biocstyle
)
)
),
fluidRow(
column(
width = 12,
uiOutput("ui_bookmarks")
)
),
fluidRow(
bs4Dash::column(
width = 8,
offset = 2,
br(), br(),
gt_downloadButton(
"start_happyhour",
"Start the happy hour!",
class = "biocdlbutton",
icon = "cocktail") # magic?
)
),
hr(),
br(), br(), br(),
fluidRow(
column(
width = 4,
textInput(
"se_export_name",label = "Choose a filename for the serialized .rds object",
value = "se_GeneTonic_toiSEE.rds"
)
),
column(
width = 4,
gt_downloadButton(
"button_iSEEexport",
label = "Export as serialized SummarizedExperiment",
class = "biocdlbutton",
icon = "glasses"
)
)
)
)
)
),
# controlbar definition ---------------------------------------------------
controlbar = bs4Dash::bs4DashControlbar(
numericInput(inputId = "de_fdr",
label = "False Discovery Rate (FDR) for DE",
value = 0.05, min = 0.0001, max = 1, step = 0.01),
numericInput(inputId = "n_genesets",
label = "Number of genesets",
value = 15, min = 1, max = nrow(res_enrich)),
selectInput("exp_condition", label = "Group/color by: ",
choices = c(NULL, names(colData(dds))), selected = NULL, multiple = TRUE)
),
# footer definition -------------------------------------------------------
footer = bs4DashFooter(
GeneTonic_footer,
right_text = NULL
)
)
options(shiny.maxRequestSize = 15 * 1024^2)
#nocov start
genetonic_server <- function(input, output, session) {
# reactive objects and setup commands -------------------------------------
reactive_values <- reactiveValues()
reactive_values$mygenes <- c()
reactive_values$mygenesets <- c()
myvst <- vst(dds)
res_enhanced <- get_aggrscores(res_enrich = res_enrich,
res_de = res_de,
annotation_obj = annotation_obj)
# output$ui_exp_condition <- renderUI({
# selectInput("exp_condition", label = "Group/color by: ",
# choices = c(NULL, poss_covars), selected = NULL, multiple = TRUE)
# })
# panel Welcome -----------------------------------------------------------
output$overview_dds <- DT::renderDataTable({
DT::datatable(
counts(dds),
options = list(scrollX = TRUE, scrollY = "400px")
)
})
output$overview_res_de <- DT::renderDataTable({
DT::datatable(
as.data.frame(res_de),
options = list(
scrollX = TRUE,
scrollY = "400px",
pageLength = 25,
columnDefs = list(
list(className = "dt-center", targets = "_all")
)
)
) %>%
formatRound(columns = c("log2FoldChange"), digits = 3) %>%
formatStyle(
"log2FoldChange",
background = styleColorBar_divergent(as.data.frame(res_de)$log2FoldChange,
scales::alpha("navyblue", 0.4),
scales::alpha("darkred", 0.4)),
backgroundSize = "100% 90%",
backgroundRepeat = "no-repeat",
backgroundPosition = "center"
)
})
output$overview_res_enrich <- DT::renderDataTable({
DT::datatable(
res_enrich,
options = list(scrollX = TRUE, scrollY = "400px")
)
})
output$overview_annotation <- DT::renderDataTable({
DT::datatable(
annotation_obj,
options = list(scrollX = TRUE, scrollY = "400px")
)
})
output$ui_infoboxes <- renderUI({
tagList(
fluidRow(
column(
width = 12,
bs4ValueBoxOutput("infobox_dds"),
bs4ValueBoxOutput("infobox_resde"),
bs4ValueBoxOutput("infobox_resenrich"),
bs4ValueBoxOutput("infobox_annotation")
)
# ,
# column(
# width = 6,
# img(src = "GeneTonic/GeneTonic.png", height = "350px")
# )
)
)
})
output$infobox_dds <- renderbs4ValueBox({
bs4ValueBox(
value = paste0(nrow(dds), " genes x ", ncol(dds), " samples"),
subtitle = "dds object",
icon = "table",
status = "danger",
width = NULL
)
})
output$infobox_resde <- renderbs4ValueBox({
bs4ValueBox(
value = paste0(
nrow(deseqresult2df(res_de, FDR = input$de_fdr)),
" DE genes"
),
subtitle = "res object",
icon = "vial",
status = "warning",
width = NULL
)
})
output$infobox_resenrich <- renderbs4ValueBox({
bs4ValueBox(
value = paste0(
nrow(res_enrich),
" functional categories"
),
subtitle = "func enrich object",
icon = "share-alt",
status = "success",
width = NULL
)
})
output$infobox_annotation <- renderbs4ValueBox({
bs4ValueBox(
value = paste0(ncol(annotation_obj), " feature identifiers for ", nrow(dds), " features"),
subtitle = "annotation object",
icon = "table",
status = "info",
width = NULL
)
})
# panel GeneSet-Gene ------------------------------------------------------
reactive_values$ggs_graph <- reactive({
g <- ggs_graph(
res_enrich = res_enrich,
res_de = res_de,
annotation_obj = annotation_obj,
n_gs = input$n_genesets,
prettify = TRUE,
geneset_graph_color = "gold"
)
# rank_gs <- rank(V(g)$name[V(g)$nodetype == "GeneSet"])
# rank_feats <- rank(V(g)$name[V(g)$nodetype == "Feature"]) +
# length(rank_gs) # to keep the GeneSets first
# g <- permute.vertices(g, c(rank_gs, rank_feats))
# return(g)
})
output$ggsnetwork <- renderVisNetwork({
# minimal example
visNetwork::visIgraph(reactive_values$ggs_graph()) %>%
visOptions(highlightNearest = list(enabled = TRUE,
degree = 1,
hover = TRUE),
nodesIdSelection = TRUE) %>%
visExport(name = "ggs_network",
type = "png",
label = "Save ggs graph")
})
output$netnode <- renderPrint({
g <- reactive_values$ggs_graph()
cur_sel <- input$ggsnetwork_selected
cur_node <- match(cur_sel, V(g)$name)
cur_nodetype <- V(g)$nodetype[cur_node]
cur_gsid <- res_enrich$gs_id[match(cur_sel, res_enrich$gs_description)]
paste0("I'm selecting ", input$ggsnetwork_selected, ", which has index ", cur_node, " and is of type ", cur_nodetype, "this is from set", cur_gsid)
})
output$ui_ggs_genesetbox <- renderUI({
tagList(
# verbatimTextOutput("netnode"),
plotOutput("net_sigheatplot"),
uiOutput("ggs_geneset_info")
)
})
output$net_sigheatplot <- renderPlot({
g <- reactive_values$ggs_graph()
cur_sel <- input$ggsnetwork_selected
cur_node <- match(cur_sel, V(g)$name)
cur_nodetype <- V(g)$nodetype[cur_node]
validate(need(cur_nodetype == "GeneSet",
message = "Please select a gene set from the Gene-Geneset Graph."
))
cur_gsid <- res_enrich$gs_id[match(input$ggsnetwork_selected, res_enrich$gs_description)]
if (!is.null(input$exp_condition)) {
gs_heatmap(
myvst,
res_de,
res_enrich,
annotation_obj = annotation_obj,
geneset_id = cur_gsid,
FDR = input$de_fdr,
de_only = FALSE,
cluster_rows = TRUE,
cluster_columns = TRUE,
center_mean = TRUE,
scale_row = TRUE,
anno_col_info = input$exp_condition
)
} else {
gs_heatmap(
myvst,
res_de,
res_enrich,
annotation_obj = annotation_obj,
geneset_id = cur_gsid,
FDR = input$de_fdr,
de_only = FALSE,
cluster_rows = TRUE,
cluster_columns = TRUE,
center_mean = TRUE,
scale_row = TRUE
)
}
})
output$ggs_geneset_info <- renderUI({
g <- reactive_values$ggs_graph()
cur_sel <- input$ggsnetwork_selected
cur_node <- match(cur_sel, V(g)$name)
cur_nodetype <- V(g)$nodetype[cur_node]
validate(need(cur_nodetype == "GeneSet",
message = "" # "Please select a gene set."
))
cur_gsid <- res_enrich$gs_id[match(input$ggsnetwork_selected, res_enrich$gs_description)]
go_2_html(cur_gsid, res_enrich)
})
output$ui_ggs_genebox <- renderUI({
tagList(
uiOutput("ggs_gene_info"),
plotOutput("ggs_geneplot")
)
})
output$ggs_gene_info <- renderUI({
g <- reactive_values$ggs_graph()
cur_sel <- input$ggsnetwork_selected
cur_node <- match(cur_sel, V(g)$name)
cur_nodetype <- V(g)$nodetype[cur_node]
validate(need(cur_nodetype == "Feature",
message = "Please select a gene/feature."
))
cur_geneid <- annotation_obj$gene_id[match(cur_sel, annotation_obj$gene_name)]
# mycontent <- HTML(paste0(
# cur_geneid, "<br>", "<b>", cur_sel, "</b>"
# ))
geneinfo_2_html(cur_sel, res_de)
})
output$ggs_geneplot <- renderPlot({
g <- reactive_values$ggs_graph()
cur_sel <- input$ggsnetwork_selected
cur_node <- match(cur_sel, V(g)$name)
cur_nodetype <- V(g)$nodetype[cur_node]
validate(need(cur_nodetype == "Feature",
message = "" # "Please select a gene/feature."
))
validate(need(input$exp_condition != "",
message = "Please select a group for the experimental condition."
))
cur_geneid <- annotation_obj$gene_id[match(cur_sel, annotation_obj$gene_name)]
gene_plot(dds,
gene = cur_geneid,
intgroup = input$exp_condition,
annotation_obj = annotation_obj
)
})
# panel EnrichmentMap -----------------------------------------------------
emap_graph <- reactive({
emg <- enrichment_map(
res_enrich = res_enrich,
res_de = res_de,
annotation_obj = annotation_obj,
n_gs = input$n_genesets,
overlap_threshold = 0.1,
scale_edges_width = 200,
color_by = input$emap_colorby
)
# rank_gs <- rank(V(emg)$name)
# emg <- permute.vertices(emg, rank_gs)
return(emg)
})
output$emap_visnet <- renderVisNetwork({
visNetwork::visIgraph(emap_graph()) %>%
visOptions(highlightNearest = list(enabled = TRUE,
degree = 1,
hover = TRUE),
nodesIdSelection = TRUE) %>%
visExport(name = "emap_network",
type = "png",
label = "Save enrichment map")
})
output$ui_emap_sidecontent <- renderUI({
tagList(
plotOutput("emap_sigheatplot"),
uiOutput("emap_geneset_info")
)
})
output$emap_geneset_info <- renderUI({
cur_gsid <- res_enrich$gs_id[match(input$emap_visnet_selected, res_enrich$gs_description)]
validate(need(!is.na(cur_gsid),
message = ""))
# message(cur_gsid)
# GOTERM[[cur_gsid]]
go_2_html(cur_gsid, res_enrich)
})
output$emap_sigheatplot <- renderPlot({
# g <- reactive_values$emap_graph()
# cur_sel <- input$emap_visnet_selected
# cur_node <- match(cur_sel,V(g)$name)
# cur_nodetype <- V(g)$nodetype[cur_node]
# validate(need(cur_nodetype == "GeneSet",
# message = "Please select a gene set."
# ))
cur_gsid <- res_enrich$gs_id[match(input$emap_visnet_selected, res_enrich$gs_description)]
validate(need(!is.na(cur_gsid),
message = "Please select a gene set from the Enrichment Map."
))
if (!is.null(input$exp_condition)) {
# message(cur_gsid)
gs_heatmap(
myvst,
res_de,
res_enrich,
annotation_obj = annotation_obj,
geneset_id = cur_gsid,
FDR = input$de_fdr,
de_only = FALSE,
cluster_rows = TRUE,
cluster_columns = TRUE,
center_mean = TRUE,
scale_row = TRUE,
anno_col_info = input$exp_condition
)
} else {
gs_heatmap(
myvst,
res_de,
res_enrich,
annotation_obj = annotation_obj,
geneset_id = cur_gsid,
FDR = input$de_fdr,
de_only = FALSE,
cluster_rows = TRUE,
cluster_columns = TRUE,
center_mean = TRUE,
scale_row = TRUE
)
}
})
# geneset distillery
reactive_values$distillat <- reactive({
distillat <- distill_enrichment(
res_enrich = res_enrich,
res_de = res_de,
annotation_obj = annotation_obj,
n_gs = input$n_genesets_distill)
return(distillat)
})
output$dt_distill <- DT::renderDataTable({
dist_table <- reactive_values$distillat()$distilled_table
# TODO: reorder the columns from the distilled table
DT::datatable(
dist_table[,1:4],
selection = "single",
rownames = FALSE,
options = list(
pageLength = 50,
scrollX = TRUE,
scrollY = "400px")
)
})
output$ui_metags_sidecontent <- renderUI({
tagList(
plotOutput("distill_heatmap"),
uiOutput("distill_info")
)
})
output$distill_info <- renderUI({
"haha"
# TODO: structure up the content, a la gene2html
})
output$distill_launch <- renderUI({
tagList(
actionButton(
inputId = "btn_show_emap_distilled",
icon = icon("hubspot"),
label = "Distill emap", style = .actionbutton_biocstyle
)
)
})
output$distill_heatmap <- renderPlot({
dist_table <- reactive_values$distillat()$distilled_table
s <- input$dt_distill_rows_selected
validate(need(length(s) > 0,
message = "Please select a meta-geneset from the table"
))
selrow <- dist_table[s,]$metags_msgs
sel_genes <- strsplit(dist_table[s,]$metags_genes, ",")[[1]]
# message(length(sel_genes))
sel_genes_id <- annotation_obj$gene_id[match(sel_genes, annotation_obj$gene_name)]
# message(length(sel_genes_id))
if (!is.null(input$exp_condition)) {
gs_heatmap(
myvst,
res_de,
res_enrich,
annotation_obj = annotation_obj,
genelist = sel_genes_id,
FDR = input$de_fdr,
de_only = FALSE,
cluster_rows = TRUE,
cluster_columns = TRUE,
center_mean = TRUE,
scale_row = TRUE,
anno_col_info = input$exp_condition,
plot_title = selrow
)
} else {
gs_heatmap(
myvst,
res_de,
res_enrich,
annotation_obj = annotation_obj,
genelist = sel_genes_id,
FDR = input$de_fdr,
de_only = FALSE,
cluster_rows = TRUE,
cluster_columns = TRUE,
center_mean = TRUE,
scale_row = TRUE,
plot_title = selrow
)
}
})
# output$distill_graph <- renderPlot({
# plot(reactive_values$distillat()$distilled_em)
# })
output$distill_graph <- renderVisNetwork({
ig <- reactive_values$distillat()$distilled_em
# TODO: define color palette
colpal <- colorspace::rainbow_hcl(length(unique(V(ig)$color)))[V(ig)$color]
V(ig)$color.background <- scales::alpha(colpal, alpha = 0.8)
V(ig)$color.highlight <- scales::alpha(colpal, alpha = 1)
V(ig)$color.hover <- scales::alpha(colpal, alpha = 0.5)
V(ig)$color.border <- "black"
visNetwork::visIgraph(ig) %>%
visOptions(highlightNearest = list(enabled = TRUE,
degree = 1,
hover = TRUE),
nodesIdSelection = TRUE,
selectedBy = "membership")
})
# panel Overview ------------------------------------------------------------
output$enriched_funcres <- renderPlot({
enhance_table(res_enrich, res_de,
annotation_obj = annotation_obj,
n_gs = input$n_genesets)
})
output$gs_volcano <- renderPlot({
gs_volcano(
get_aggrscores(res_enrich,
res_de,
annotation_obj = annotation_obj),
volcano_labels = input$n_genesets
)
})
output$gs_volcano_simplified <- renderPlot({
gs_volcano(
get_aggrscores(gs_simplify(res_enrich, gs_overlap = input$gs_overlap),
res_de,
annotation_obj = annotation_obj),
volcano_labels = input$n_genesets
)
})
output$enriched_funcres_plotly <- renderPlotly({
ggplotly(enhance_table(res_enrich,
res_de,
annotation_obj = annotation_obj,
n_gs = input$n_genesets))
})
# panel GSViz -----------------------------------------------------
gss_mat <- reactive({
gs_scores(se = myvst,
res_de = res_de,
res_enrich = res_enrich,
annotation_obj = annotation_obj)
})
output$gsscores_heatmap <- renderPlot({
gs_scoresheat(
gss_mat(),
n_gs = input$n_genesets)
})
output$alluvial_genesets <- renderPlotly({
gs_alluvial(res_enrich, res_de, annotation_obj, n_gs = input$n_genesets)
})
output$mds_genesets <- renderPlot({
gs_mds(res_enrich, res_de, annotation_obj, mds_colorby = "z_score",
mds_labels = input$n_genesets)
})
output$gs_summaryheat <- renderPlot({
gs_summary_heat(res_enrich, res_de, annotation_obj,
n_gs = input$n_genesets)
})
output$gs_summaryoverview <- renderPlot({
gs_summary_overview(res_enrich = res_enhanced,
n_gs = input$n_genesets)
})
output$gs_summaryoverview_pair <- renderPlot({
gs_summary_overview_pair(res_enrich = res_enhanced,
n_gs = input$n_genesets)
})
output$gs_summaryhorizon <- renderPlot({
gs_horizon(res_enrich = res_enhanced,
n_gs = input$n_genesets)
})
output$gs_summaryradar <- renderPlotly({
gs_radar(res_enrich = res_enhanced,
n_gs = input$n_genesets)
})
output$gs_dendro <- renderPlot({
gs_dendro(res_enrich = res_enhanced,
n_gs = input$n_genesets)
})
# panel Bookmarks ---------------------------------------------------------
output$ui_bookmarks <- renderUI({
tagList(
fluidRow(
column(
width = 6,
bs4InfoBoxOutput("infobox_book_genes"),
h5("Bookmarked genes"),
DT::dataTableOutput("bookmarks_genes"),
downloadButton("btn_export_genes", label = "", class = "biocdlbutton")
# ideally completed by a function/param to upload them
),
column(
width = 6,
bs4InfoBoxOutput("infobox_book_genesets"),
h5("Bookmarked genesets"),
DT::dataTableOutput("bookmarks_genesets"),
downloadButton("btn_export_genesets", label = "", class = "biocdlbutton")
)
)
)
})
output$infobox_book_genes <- renderbs4InfoBox({
bs4InfoBox(
title = "Bookmarked genes",
value = length(reactive_values$mygenes),
icon = "bookmark",
status = "info",
width = 12
)
})
output$infobox_book_genesets <- renderbs4InfoBox({
bs4InfoBox(
title = "Bookmarked genesets",
value = length(reactive_values$mygenesets),
icon = "bookmark",
status = "success",
width = 12
)
})
output$bookmarks_genes <- DT::renderDataTable({
book_df_genes <- annotation_obj[reactive_values$mygenes, ]
datatable(book_df_genes, rownames = FALSE)
})
output$bookmarks_genesets <- DT::renderDataTable({
book_df_genesets <- res_enrich[reactive_values$mygenesets, c("gs_id", "gs_description")]
datatable(book_df_genesets, rownames = FALSE)
})
output$btn_export_genes <- downloadHandler(
filename = function() {
paste0("GeneTonicBookmarks_genes_", project_id, "_", gsub(" ", "_", gsub("-", "", gsub(":", "-", as.character(Sys.time())))), ".txt")
}, content = function(file) {
writeLines(text = reactive_values$mygenes,
con = file)
}
)
output$btn_export_genesets <- downloadHandler(
filename = function() {
paste0("GeneTonicBookmarks_genesets_", project_id, "_", gsub(" ", "_", gsub("-", "", gsub(":", "-", as.character(Sys.time())))), ".txt")
}, content = function(file) {
writeLines(text = reactive_values$mygenesets,
con = file)
}
)
output$start_happyhour <- downloadHandler(
filename = paste0(
Sys.Date(),
"_", round(runif(1) * 100), # for not having all w the same name
"_GeneTonicReport.html"),
content = function(file) {
# temporarily switch to the temp dir, in case you do not have write permission to the current working directory
owd <- setwd(tempdir())
on.exit(setwd(owd))
# cat(tmp_content,file="GeneTonic_tempreport.Rmd",sep="\n")
withProgress(rmarkdown::render(
input = system.file("extdata", "cocktail_recipe.Rmd", package = "GeneTonic"),
output_file = file,
# fragment.only = TRUE,
quiet = TRUE),
message = "Generating the html report",
detail = "This can take some time")
}
)
output$button_iSEEexport <- downloadHandler(
filename = function() {
input$se_export_name
}, content = function(file) {
se <- export_for_iSEE(dds, res_de)
saveRDS(se, file = file)
}
)
output$sessioninfo <- renderPrint({
sessionInfo()
})
# observers ---------------------------------------------------------------
observeEvent(input$tour_firststeps, {
tour <- read.delim(system.file("extdata", "tour_welcome.txt", package = "GeneTonic"),
sep = ";", stringsAsFactors = FALSE,
row.names = NULL, quote = "")
rintrojs::introjs(session, options = list(steps = tour))
})
observeEvent(input$tour_ggs, {
tour <- read.delim(system.file("extdata", "tour_ggs.txt", package = "GeneTonic"),
sep = ";", stringsAsFactors = FALSE,
row.names = NULL, quote = "")
rintrojs::introjs(session, options = list(steps = tour))
})
observeEvent(input$tour_emap, {
tour <- read.delim(system.file("extdata", "tour_emap.txt", package = "GeneTonic"),
sep = ";", stringsAsFactors = FALSE,
row.names = NULL, quote = "")
rintrojs::introjs(session, options = list(steps = tour))
})
observeEvent(input$tour_overview, {
tour <- read.delim(system.file("extdata", "tour_overview.txt", package = "GeneTonic"),
sep = ";", stringsAsFactors = FALSE,
row.names = NULL, quote = "")
rintrojs::introjs(session, options = list(steps = tour))
})
observeEvent(input$tour_gsviz, {
tour <- read.delim(system.file("extdata", "tour_gsviz.txt", package = "GeneTonic"),
sep = ";", stringsAsFactors = FALSE,
row.names = NULL, quote = "")
rintrojs::introjs(session, options = list(steps = tour))
})
observeEvent(input$tour_bookmarks, {
tour <- read.delim(system.file("extdata", "tour_bookmarks.txt", package = "GeneTonic"),
sep = ";", stringsAsFactors = FALSE,
row.names = NULL, quote = "")
rintrojs::introjs(session, options = list(steps = tour))
})
# observe({
# print(input$gt_tabs)
# })
observeEvent(input$btn_first_help, {
showModal(
modalDialog(
title = "First Help Info", size = "l", fade = TRUE,
footer = NULL, easyClose = TRUE,
tagList(
includeMarkdown(system.file("extdata", "GeneTonic101.md", package = "GeneTonic")),
)
)
)
})
observeEvent(input$btn_docs_vignette, {
path <- system.file("doc", "GeneTonic_manual.html", package = "GeneTonic")
if (path == "") {
showNotification("This vignette has not been built on this system - Opening the online documentation. Please note that the versions might not be coincident!", type = "warning")
} else {
browseURL(path)
}
})
observeEvent(input$btn_info_session, {
showModal(
modalDialog(
title = "Session information", size = "l", fade = TRUE,
footer = NULL, easyClose = TRUE,
tagList(
tags$code("> sessionInfo()"),
renderPrint({
sessionInfo()
})
)
)
)
})
observeEvent(input$btn_info_genetonic, {
showModal(
modalDialog(
title = "About GeneTonic", size = "l", fade = TRUE,
footer = NULL, easyClose = TRUE,
tagList(
includeMarkdown(system.file("extdata", "about.md", package = "GeneTonic")),
renderPrint({
citation("GeneTonic")
})
)
)
)
})
observeEvent(input$btn_show_emap_distilled, {
showModal(
modalDialog(
title = "distillery", size = "l", fade = TRUE,
footer = NULL, easyClose = TRUE,
visNetworkOutput("distill_graph")
)
)
})
# bookmarker --------------------------------------------------------------
observeEvent(input$bookmarker, {
if (input$gt_tabs == "tab_welcome")
showNotification("Welcome to GeneTonic!")
else if (input$gt_tabs == "tab_ggs") {
g <- reactive_values$ggs_graph()
cur_sel <- input$ggsnetwork_selected
if (cur_sel == "") {
showNotification("Select a node in the network to bookmark it", type = "warning")
} else {
cur_node <- match(cur_sel, V(g)$name)
cur_nodetype <- V(g)$nodetype[cur_node]
if (cur_nodetype == "Feature") {
cur_sel_id <- annotation_obj$gene_id[match(cur_sel, annotation_obj$gene_name)]
if (cur_sel_id %in% reactive_values$mygenes) {
showNotification(sprintf("The selected gene %s (%s) is already in the set of the bookmarked genes.", cur_sel, cur_sel_id), type = "default")
} else {
reactive_values$mygenes <- unique(c(reactive_values$mygenes, cur_sel_id))
# message("there go your genes... ", reactive_values$mygenes)
showNotification(sprintf("Added %s (%s) to the bookmarked genes. The list contains now %d elements", cur_sel, cur_sel_id, length(reactive_values$mygenes)), type = "message")
}
} else if (cur_nodetype == "GeneSet") {
cur_sel_id <- res_enrich$gs_id[match(cur_sel, res_enrich$gs_description)]
if (cur_sel_id %in% reactive_values$mygenesets) {
showNotification(sprintf("The selected gene set %s (%s) is already in the set of the bookmarked genesets.", cur_sel, cur_sel_id), type = "default")
} else {
reactive_values$mygenesets <- unique(c(reactive_values$mygenesets, cur_sel_id))
# message("here are your genesets... ", reactive_values$mygenesets)
showNotification(sprintf("Added %s (%s) to the bookmarked genesets. The list contains now %d elements", cur_sel, cur_sel_id, length(reactive_values$mygenesets)), type = "message")
}
} else {
message("bleeee")
}
}
}
else if (input$gt_tabs == "tab_emap") {
g <- reactive_values$ggs_graph()
cur_sel <- input$emap_visnet_selected
cur_sel_id <- res_enrich$gs_id[match(cur_sel, res_enrich$gs_description)]
if (cur_sel == "") {
showNotification("Select a node in the network to bookmark it", type = "warning")
} else {
if (cur_sel_id %in% reactive_values$mygenesets) {
showNotification(sprintf("The selected gene set %s (%s) is already in the set of the bookmarked genesets.", cur_sel, cur_sel_id), type = "default")
} else {
reactive_values$mygenesets <- unique(c(reactive_values$mygenesets, cur_sel_id))
message("here are your genesets... ", reactive_values$mygenesets)
showNotification(sprintf("Added %s (%s) to the bookmarked genesets. The list contains now %d elements", cur_sel, cur_sel_id, length(reactive_values$mygenesets)), type = "message")
}
}
}
else if (input$gt_tabs == "tab_bookmarks")
showNotification("You are already in the Bookmarks tab...")
})
# observeEvent(input$start_happyhour, {
# showNotification("The happy hour is on! Please wait for the report to be fully compiled",
# type = "message")
# })
}
#nocov end
shinyApp(ui = genetonic_ui, server = genetonic_server)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.