ubigen/R/server.R

224 lines
5.6 KiB
R
Raw Normal View History

2022-05-07 17:54:23 +02:00
#' Server implementing the main user interface.
#' @noRd
2022-05-30 21:59:40 +02:00
server <- function(input, output, session) {
2022-05-30 19:32:19 +02:00
ranked_data <- reactive({
rank_genes(
cross_sample_metric = input$cross_sample_metric,
cross_sample_weight = input$cross_sample_weight,
mean_expression_weight = input$mean_expression,
sd_expression_weight = input$sd_expression
)
2022-05-30 19:32:19 +02:00
})
2022-06-14 13:50:25 +02:00
custom_genes <- gene_selector_server("custom_genes") |> debounce(500)
2022-05-30 21:27:18 +02:00
output$overview_plot <- plotly::renderPlotly(overview_plot(
ranked_data(),
highlighted_genes = custom_genes()
))
2022-05-30 21:59:40 +02:00
observeEvent(custom_genes(),
{ # nolint
if (length(custom_genes()) > 0) {
2022-06-02 09:14:34 +02:00
updateTabsetPanel(session, "results_panel", selected = "custom_genes")
} else if (input$results_panel == "custom_genes") {
updateTabsetPanel(session, "results_panel", selected = "top_genes")
2022-05-30 21:59:40 +02:00
}
},
ignoreNULL = FALSE
)
output$custom_genes_synopsis <- renderText({
comparison_gene_ids <- custom_genes()
if (length(comparison_gene_ids) > 1) {
reference <- ranked_data()[!gene %chin% comparison_gene_ids, score]
comparison <- ranked_data()[gene %chin% comparison_gene_ids, score]
reference_median <- format(
round(stats::median(reference), digits = 3),
nsmall = 3
)
comparison_median <- format(
round(stats::median(comparison), digits = 3),
nsmall = 3
)
test_result <- stats::wilcox.test(
2022-05-30 21:59:40 +02:00
x = comparison,
y = reference,
alternative = "greater",
conf.int = TRUE
)
p_value <- format(
round(test_result$p.value, digits = 4),
nsmall = 4,
scientific = FALSE
)
2022-05-30 21:59:40 +02:00
lower <- format(round(test_result$conf.int[1], digits = 3), nsmall = 3)
upper <- format(round(test_result$conf.int[2], digits = 3), nsmall = 3)
2022-05-30 21:59:40 +02:00
HTML(glue::glue(
"The p-value with the alternative hypothesis that your genes have ",
"higher scores than other genes is <b>{p_value}</b>. This value ",
"was computed using a Wilcoxon rank sum test. Based on a 95% ",
"confidence, the difference in scores is between <b>{lower}</b> and ",
"<b>{upper}</b>. The median score of your genes is ",
"<b>{comparison_median}</b> compared to a median score of ",
"<b>{reference_median}</b> of the other genes."
2022-05-30 21:59:40 +02:00
))
}
})
output$custom_genes_boxplot <- plotly::renderPlotly(
box_plot(ranked_data(), custom_genes())
)
2022-06-22 12:39:26 +02:00
output$custom_genes_details <- DT::renderDT({
genes_table(ranked_data()[gene %chin% custom_genes()])
})
2022-05-30 21:27:18 +02:00
output$scores_plot <- plotly::renderPlotly(scores_plot(
ranked_data(),
highlighted_genes = custom_genes()
))
2022-06-02 10:17:49 +02:00
selected_genes <- reactive({
2022-05-30 19:32:19 +02:00
selected_points <- plotly::event_data("plotly_selected")
2022-06-02 10:17:49 +02:00
ranked_data()[rank %in% selected_points$x]
})
2022-06-02 10:17:49 +02:00
output$selected_genes <- DT::renderDataTable({
2022-06-14 14:04:39 +02:00
data <- if (nrow(selected_genes()) > 0) {
2022-06-02 10:17:49 +02:00
selected_genes()
2022-06-14 14:04:39 +02:00
} else {
ranked_data()
2022-05-30 19:32:19 +02:00
}
2022-05-30 19:32:19 +02:00
genes_table(data)
})
2022-06-02 10:17:49 +02:00
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)
})
2022-06-22 19:34:39 +02:00
output$gsea_plot_ranking <- plotly::renderPlotly(gsea_plot_ranking)
}
2022-05-07 17:54:23 +02:00
#' Create a displayable data table from the gene results data.
#' @noRd
genes_table <- function(data) {
2022-05-30 19:32:19 +02:00
data <- data[, .(
"Gene" = glue::glue_data(
data,
2022-06-02 09:23:01 +02:00
"<a href=\"https://gtexportal.org/home/gene/{hgnc_name}\" ",
"target=\"_blank\">{hgnc_name}</a>"
2022-05-30 19:32:19 +02:00
),
"Rank" = rank,
"Percentile" = percentile,
"Score" = score,
"Median" = median_expression,
"Mean" = mean_expression,
"Standard deviation" = sd_expression,
"Expressed" = above_zero,
"Above median" = above_median,
"Above 95%" = above_95
)]
2022-05-30 19:32:19 +02:00
DT::datatable(
data,
options = list(
buttons = list(
list(
extend = "copy",
text = "Copy to clipboard"
2022-05-12 13:24:27 +02:00
),
2022-05-30 19:32:19 +02:00
list(
extend = "csv",
text = "Download CSV"
)
),
dom = "fBrtip",
pageLength = 100
),
rownames = FALSE,
escape = FALSE,
selection = "none",
extensions = "Buttons"
) |>
DT::formatPercentage(
c(
"Percentile",
"Score",
"Expressed",
"Above median",
"Above 95%"
),
digits = 2,
) |>
2022-05-30 19:32:19 +02:00
DT::formatRound(c(
"Median",
"Mean",
"Standard deviation"
))
2022-05-07 17:54:23 +02:00
}