From 90c9d18f261b3ffe4d4a4c14ec23ec677cb79174 Mon Sep 17 00:00:00 2001 From: Elias Projahn Date: Thu, 2 Jun 2022 10:17:49 +0200 Subject: [PATCH] Add gprofiler integration --- DESCRIPTION | 1 + R/server.R | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++--- R/style.R | 9 ++++++- R/ui.R | 36 ++++++++++++++++++++++++++++ 4 files changed, 111 insertions(+), 4 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 12c3576..b7d0656 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -25,5 +25,6 @@ Imports: DT, plotly, glue, + gprofiler2, shiny, shinyvs diff --git a/R/server.R b/R/server.R index d5a8669..e637895 100644 --- a/R/server.R +++ b/R/server.R @@ -76,17 +76,80 @@ server <- function(input, output, session) { highlighted_genes = custom_genes() )) - output$selected_genes <- DT::renderDataTable({ + selected_genes <- reactive({ selected_points <- plotly::event_data("plotly_selected") + ranked_data()[rank %in% selected_points$x] + }) - data <- if (is.null(selected_points)) { + output$selected_genes <- DT::renderDataTable({ + data <- if (length(selected_genes()) > 0) { ranked_data() } else { - ranked_data()[rank %in% selected_points$x] + selected_genes() } genes_table(data) }) + + gsea_genes <- reactive({ + sort(if (input$gsea_set == "top") { + ranked_data()[rank >= input$gsea_ranks, gene] + } else if (input$gsea_set == "selected") { + selected_genes()[, gene] + } else { + custom_genes() + }) + }) + + gsea_result <- reactive({ + withProgress( + message = "Querying g:Profiler", + value = 0.0, + { # nolint + setProgress(0.2) + gprofiler2::gost(gsea_genes()) + } + ) + }) |> + bindCache(gsea_genes()) |> + bindEvent(input$gsea_run, ignoreNULL = FALSE) + + output$gsea_plot <- plotly::renderPlotly({ + gprofiler2::gostplot(gsea_result(), interactive = TRUE) + }) + + output$gsea_details <- DT::renderDT({ + data <- data.table(gsea_result()$result) + setorder(data, p_value) + + data[, total_ratio := term_size / effective_domain_size] + data[, query_ratio := intersection_size / query_size] + + data <- data[, .( + source, + term_name, + total_ratio, + query_ratio, + p_value + )] + + DT::datatable( + data, + rownames = FALSE, + colnames = c( + "Source", + "Term", + "Total ratio", + "Query ratio", + "p-value" + ), + options = list( + pageLength = 25 + ) + ) |> + DT::formatRound("p_value", digits = 4) |> + DT::formatPercentage(c("total_ratio", "query_ratio"), digits = 1) + }) } #' Create a displayable data table from the gene results data. diff --git a/R/style.R b/R/style.R index 2bf4c58..5eabdeb 100644 --- a/R/style.R +++ b/R/style.R @@ -2,6 +2,13 @@ #' @noRd custom_css <- function() { tags$head( - tags$style(".nav-hidden { height: 0 }") + tags$style(HTML( + ".nav-hidden { height: 0 }", + ".flow-layout > div {", + "display: inline-block;", + "vertical-align: top;", + "margin-right: 12px;", + "}" + )) ) } diff --git a/R/ui.R b/R/ui.R index f87a655..0294337 100644 --- a/R/ui.R +++ b/R/ui.R @@ -81,6 +81,42 @@ ui <- function() { )), div(class = "p-1"), DT::dataTableOutput("selected_genes") + ), + tabPanel( + "GSEA", + value = "gsea", + div( + class = "flow-layout", + selectInput( + "gsea_set", + label = NULL, + list( + "Top genes" = "top", + "Selected genes" = "selected", + "Your genes" = "custom" + ) + ), + conditionalPanel( + "input.gsea_set == 'top'", + sliderInput( + "gsea_ranks", + label = NULL, + min = 10, + max = 1000, + value = 100, + step = 10, + ticks = FALSE + ) + ), + actionButton( + "gsea_run", + "Update analysis", + class = "btn-primary" + ) + ), + plotly::plotlyOutput("gsea_plot"), + div(class = "p-2"), + DT::dataTableOutput("gsea_details") ) ) )