ubigen/R/server.R

125 lines
3.3 KiB
R
Raw Normal View History

2022-05-07 17:54:23 +02:00
#' Server implementing the main user interface.
#' @noRd
server <- function(input, output) {
2022-05-12 12:16:48 +02:00
ranked_data <- reactive({
total_weight <- abs(input$above_median) +
abs(input$mean_expression) +
abs(input$sd_expression)
data <- data.table::copy(ubigen::genes)
data[, score :=
(input$above_median * above_median +
input$mean_expression * mean_expression_normalized +
input$sd_expression * sd_expression_normalized) /
total_weight]
data.table::setorder(data, -score)
data[, rank := .I]
2022-05-12 12:17:18 +02:00
data[, percentile := 1 - rank / max(rank)]
2022-05-12 12:16:48 +02:00
data
})
2022-05-12 12:21:09 +02:00
output$scores_plot <- plotly::renderPlotly(scores_plot(ranked_data()))
output$selected_genes <- DT::renderDataTable({
selected_points <- plotly::event_data("plotly_selected")
data <- if (is.null(selected_points)) {
ranked_data()
} else {
ranked_data()[rank %in% selected_points$x]
}
genes_table(data)
})
}
2022-05-07 17:54:23 +02:00
2022-05-12 12:21:09 +02:00
#' Create plot showing the distribution of scores using `plotly`.
#'
#' @param ranked_data Data on genes with precomputed ranks.
#' @param ranks How may ranks the x-axis should include. If this parameter is
#' `NULL`, all ranks will be shown.
#'
#' @return A `plotly` figure for rendering.
#' @noRd
scores_plot <- function(ranked_data, ranks = 1000) {
data <- if (is.null(ranks)) {
ranked_data
} else {
ranked_data[1:ranks]
}
ranks_label <- if (is.null(ranks)) {
"Ranks"
} else {
glue::glue("Ranks (1 to {ranks})")
}
plotly::plot_ly() |>
plotly::add_markers(
data = data,
x = ~rank,
y = ~score,
text = ~hgnc_name,
customdata = ~percentile,
hovertemplate = paste0(
"<b>%{text}</b><br>",
"Rank: %{x}<br>",
"Score: %{y:.2}<br>",
"Percentile: %{customdata:.2%}",
"<extra></extra>"
)
) |>
plotly::layout(
xaxis = list(title = ranks_label),
yaxis = list(title = "Score"),
clickmode = "event+select",
dragmode = "select"
2022-05-12 12:21:09 +02:00
)
}
#' Create a displayable data table from the gene results data.
#' @noRd
genes_table <- function(data) {
data <- data[, .(
"Gene" = glue::glue_data(
2022-05-07 17:54:23 +02:00
data,
"<a href=\"https://www.ensembl.org/Homo_sapiens/Gene/Summary",
"?db=core;g={gene}\" target=\"_blank\">{hgnc_name}</a>"
),
"Rank" = rank,
2022-05-12 12:17:18 +02:00
"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
)]
DT::datatable(
data,
options = list(pageLength = 100),
rownames = FALSE,
escape = FALSE
) |>
DT::formatPercentage(
c(
2022-05-12 12:17:18 +02:00
"Percentile",
2022-05-07 17:54:23 +02:00
"Score",
"Expressed",
"Above median",
"Above 95%"
),
digits = 2,
) |>
DT::formatRound(c(
"Median",
"Mean",
"Standard deviation"
))
2022-05-07 17:54:23 +02:00
}