From 545dd275abe5e7eab3b59ffa9974ea8f4f455257 Mon Sep 17 00:00:00 2001 From: Elias Projahn Date: Thu, 25 Apr 2024 22:09:25 +0200 Subject: [PATCH 1/8] Add citation --- R/app.R | 10 ++++++++++ README.md | 11 +++++++++++ inst/CITATION | 11 +++++++++++ inst/content/manual.md | 8 ++++++-- inst/misc/style.css | 6 ++++++ 5 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 inst/CITATION diff --git a/R/app.R b/R/app.R index 415f576..34c9a93 100644 --- a/R/app.R +++ b/R/app.R @@ -85,6 +85,16 @@ ui <- function(options) { ) ) ) + ), + div( + class = "footer", + HTML(glue::glue( + "geposanui version {packageVersion(\"geposanui\")}
", + "GitHub: johrpan/geposan
", + "Citation: 10.1093/nargab/lqae037" + )) ) ) } diff --git a/README.md b/README.md index 5d97094..c8091e4 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,17 @@ This will run the application which you can reach using your favorite browser. For more information on the options provided by the function, take a look at the built-in documentation (`?geposanui::run_app`). +## Publication + +This method and its implementation have been peer-reviewed and published in +NAR Genomics and Bioinformatics. If you use the package in your research or +would like to refer to our methodology, please cite the following paper: + +Elias F Projahn, Georg Fuellen, Michael Walter, Steffen Möller, Proposing +candidate genes under telomeric control based on cross-species position data, +NAR Genomics and Bioinformatics, Volume 6, Issue 2, June 2024, lqae037, +https://doi.org/10.1093/nargab/lqae037 + ## License This program is free software: you can redistribute it and/or modify it under diff --git a/inst/CITATION b/inst/CITATION new file mode 100644 index 0000000..17d6334 --- /dev/null +++ b/inst/CITATION @@ -0,0 +1,11 @@ +bibentry( + bibtype = "Article", + title = "Proposing candidate genes under telomeric control based on cross-species position data", + author = "Elias F Projahn, Georg Fuellen, Michael Walter, Steffen Möller", + journal = "NAR Genomics and Bioinformatics", + year = 2024, + volume = 6, + number = 2, + pages = "lqae037", + doi = "10.1093/nargab/lqae037" +) diff --git a/inst/content/manual.md b/inst/content/manual.md index 1e82a99..43616cd 100644 --- a/inst/content/manual.md +++ b/inst/content/manual.md @@ -2,10 +2,12 @@ This web interface provides an interactive tool to analyze genes based on their position across species. Specifically, it can be used to investigate the effect of telomere length on gene regulation. Telomeres are repetitive DNA sequences at the end of chromosomes that shorten with every cell division. The regulation of a number of genes has been reported to depend on the length of telomeres. Gene positions across species can be a valuable dataset for analyzing effects like this because genes that are regulated by position effects may exhibit patterns in the position of their orthologs. -It is possible to use this tool to analyze any set of reference genes. Most likely, you are currently visiting [tpe-old.uni-rostock.de](https://tpe-old.uni-rostock.de/), which is preconfigured based on genes affected by TPE-OLD (telomere position effect over long distances). This is a specific way in which telomeres can influence gene expression by forming long-distance loops. +It is possible to use this tool to analyze any set of reference genes. Most likely, you are currently visiting tpe-old.uni-rostock.de, which is preconfigured based on genes affected by TPE-OLD (telomere position effect over long distances). This is a specific way in which telomeres can influence gene expression by forming long-distance loops. Information on TPE-OLD is still limited. By providing this tool, we hope to direct the community towards genes that may be more likely than others to experience a controlled telomeric interaction, based on patterns in their chromosomal position across species. Comparing your genes of interest with the reference ranking may unveil new candidates for TPE-OLD that could be a valuable target for further experimental investigation. +For more information on the methodology behind this tool, please see our publication in NAR Genomics and Bioinformatics. + ## Overview These are the five most important things in the user interface: @@ -111,7 +113,9 @@ The reference genes are the main input to the computation. Some of the individua ## References -A paper accompanying this web interface and the underlying methods is currently under peer review. +This method and its implementation have been peer-reviewed and published in NAR Genomics and Bioinformatics. If you use this tool in your research or would like to refer to our methodology, please cite the following paper: + +Elias F Projahn, Georg Fuellen, Michael Walter, Steffen Möller, Proposing candidate genes under telomeric control based on cross-species position data, NAR Genomics and Bioinformatics, Volume 6, Issue 2, June 2024, lqae037, https://doi.org/10.1093/nargab/lqae037 This project is based on data from [Ensembl](https://www.ensembl.org/index.html). diff --git a/inst/misc/style.css b/inst/misc/style.css index 704bec2..01a7613 100644 --- a/inst/misc/style.css +++ b/inst/misc/style.css @@ -70,4 +70,10 @@ h5 { height: auto; border-radius: 0.5rem; filter: drop-shadow(0 0 5px rgba(0,0,0,0.5)); +} + +.footer { + margin: 32px 24px; + font-size: small; + color: grey; } \ No newline at end of file From 6a7ae42c1cb788969c5d5057ed0471fb02395b25 Mon Sep 17 00:00:00 2001 From: Elias Projahn Date: Thu, 25 Apr 2024 22:09:33 +0200 Subject: [PATCH 2/8] Version 1.0.1 --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 26ca22f..815597d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: geposanui Title: Graphical user interface for geposan -Version: 1.0.0 +Version: 1.0.1 Authors@R: person( "Elias", From e40b2151feb4f2c78880017a92ba48a507e41912 Mon Sep 17 00:00:00 2001 From: Elias Projahn Date: Thu, 25 Apr 2024 22:29:33 +0200 Subject: [PATCH 3/8] Update link to README --- R/preset_editor.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/preset_editor.R b/R/preset_editor.R index 2ddfdf9..c2b4630 100644 --- a/R/preset_editor.R +++ b/R/preset_editor.R @@ -102,8 +102,8 @@ preset_editor_ui <- function(id, options) { "reference genes to find patterns in their ", "chromosomal positions. If you would like to apply ", "this method for your own research, see ", - "this page for ", + "this page for ", "more information." )) } From 2464240d99aa1515c65b1b2016008e8e5cefc135 Mon Sep 17 00:00:00 2001 From: Elias Projahn Date: Fri, 26 Apr 2024 19:15:44 +0200 Subject: [PATCH 4/8] Fix typo in footer --- R/app.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/app.R b/R/app.R index 34c9a93..2940d81 100644 --- a/R/app.R +++ b/R/app.R @@ -91,7 +91,7 @@ ui <- function(options) { HTML(glue::glue( "geposanui version {packageVersion(\"geposanui\")}
", "GitHub: johrpan/geposan
", + "target=\"blank\">johrpan/geposanui
", "Citation: 10.1093/nargab/lqae037" )) From e0694b71d0e014422b585259ec423326a57c43e3 Mon Sep 17 00:00:00 2001 From: Elias Projahn Date: Fri, 14 Feb 2025 16:08:13 +0100 Subject: [PATCH 5/8] Fix navbar color --- inst/misc/style.css | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/inst/misc/style.css b/inst/misc/style.css index 01a7613..31a7b55 100644 --- a/inst/misc/style.css +++ b/inst/misc/style.css @@ -28,6 +28,16 @@ h5 { font-weight: normal; } +.navbar[data-bs-theme="light"] { + --bslib-navbar-light-bg: #1964BF; + --bs-navbar-color: rgba(255, 255, 255, 0.65); + --bs-navbar-hover-color: rgba(255, 255, 255, 0.8); + --bs-navbar-disabled-color: rgba(255, 255, 255, 0.3); + --bs-navbar-active-color: #fff; + --bs-navbar-brand-color: #fff; + --bs-navbar-brand-hover-color: #fff; +} + /* Fix slider inputs floating above dropdown menu */ .irs--shiny .irs-bar { z-index: 1; From b3b492172a9562c4aa8d7d5bde47967805724752 Mon Sep 17 00:00:00 2001 From: Elias Projahn Date: Sun, 23 Feb 2025 15:51:30 +0100 Subject: [PATCH 6/8] Add warnings for excluded comparison genes --- R/comparison_editor.R | 76 ++++++++++++++++++++++++++++++++++++++++--- R/preset_editor.R | 1 - 2 files changed, 71 insertions(+), 6 deletions(-) diff --git a/R/comparison_editor.R b/R/comparison_editor.R index 5dafa0a..21e7b8f 100644 --- a/R/comparison_editor.R +++ b/R/comparison_editor.R @@ -32,6 +32,18 @@ comparison_editor_ui <- function(id, options) { NS(id, "comparison_genes") ), gene_selector_ui(NS(id, "custom_genes")) + ), + tabsetPanel( + id = NS(id, "warning_panel"), + type = "hidden", + tabPanelBody(value = "hide"), + tabPanelBody( + value = "show", + div( + style = "color: orange; margin-bottom: 16px;", + htmlOutput(NS(id, "warnings")) + ) + ) ) ) } @@ -49,18 +61,72 @@ comparison_editor_server <- function(id, preset, options) { moduleServer(id, function(input, output, session) { custom_gene_ids <- gene_selector_server("custom_genes") + comparison_warnings <- reactiveVal(character()) + output$warnings <- renderUI({ + HTML(paste(comparison_warnings(), collapse = "
")) + }) + + observe({ + updateTabsetPanel( + session, + "warning_panel", + selected = if (is.null(comparison_warnings())) "hide" else "show" + ) + }) + reactive({ - if (input$comparison_genes == "Random genes") { - preset <- preset() - gene_pool <- preset$gene_ids - reference_gene_ids <- preset$reference_gene_ids - gene_pool <- gene_pool[!gene_pool %chin% reference_gene_ids] + new_warnings <- character() + + preset <- preset() + gene_pool <- preset$gene_ids + reference_gene_ids <- preset$reference_gene_ids + gene_pool <- gene_pool[!gene_pool %chin% reference_gene_ids] + + gene_ids <- if (input$comparison_genes == "Random genes") { gene_pool[sample(length(gene_pool), length(reference_gene_ids))] } else if (input$comparison_genes == "Your genes") { custom_gene_ids() } else { options$comparison_gene_sets[[input$comparison_genes]] } + + excluded_reference_gene_ids <- + gene_ids[gene_ids %chin% reference_gene_ids] + + if (length(excluded_reference_gene_ids) > 0) { + excluded_reference_genes <- + geposan::genes[id %chin% excluded_reference_gene_ids] + excluded_reference_genes[is.na(name), name := id] + + new_warnings <- c(new_warnings, paste0( + "The following genes have been excluded because they are already ", + "part of the reference genes: ", + paste( + excluded_reference_genes$name, + collapse = ", " + ) + )) + } + + excluded_gene_ids <- gene_ids[!gene_ids %chin% gene_pool] + + if (length(excluded_gene_ids) > 0) { + excluded_genes <- + geposan::genes[id %chin% excluded_gene_ids] + excluded_genes[is.na(name), name := id] + + new_warnings <- c(new_warnings, paste0( + "The following genes are not present in the results: ", + paste( + excluded_genes$name, + collapse = ", " + ) + )) + } + + comparison_warnings(new_warnings) + + gene_ids[!gene_ids %chin% reference_gene_ids & gene_ids %chin% gene_pool] }) }) } diff --git a/R/preset_editor.R b/R/preset_editor.R index c2b4630..1489118 100644 --- a/R/preset_editor.R +++ b/R/preset_editor.R @@ -196,7 +196,6 @@ preset_editor_server <- function(id, options) { ), warning = function(w) { new_warnings <<- c(new_warnings, w$message) - } ) From 7d615f1a9a66ada494d757848a521ebcf8a48274 Mon Sep 17 00:00:00 2001 From: Elias Projahn Date: Sun, 23 Feb 2025 15:51:45 +0100 Subject: [PATCH 7/8] Add comparison gene results to overview --- R/details.R | 13 -------- R/results.R | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 93 insertions(+), 15 deletions(-) diff --git a/R/details.R b/R/details.R index ddd0d87..2d4bc42 100644 --- a/R/details.R +++ b/R/details.R @@ -86,19 +86,6 @@ details_server <- function(id, options, results) { "Percentile" ) - output_data <- reactive({ - filtered_results()[, ..columns][ - , - distance := paste0( - format( - round(distance / 1000000, digits = 2), - nsmall = 2, - ), - " Mbp" - ) - ] - }) - output$download <- downloadHandler( filename = "geposan_filtered_results.csv", content = \(file) fwrite(filtered_results()[, ..columns], file = file), diff --git a/R/results.R b/R/results.R index d5d5c01..d6a8d44 100644 --- a/R/results.R +++ b/R/results.R @@ -32,7 +32,31 @@ results_ui <- function(id, options) { plotly::plotlyOutput( NS(id, "rank_plot"), width = "100%", - height = "600px" + height = "500px" + ) + ), + tabsetPanel( + id = NS(id, "comparison_results_panel"), + type = "hidden", + tabPanelBody(value = "hide"), + tabPanelBody( + value = "show", + div( + style = paste0( + "display: flex; gap: 16px; align-items: center; ", + "margin-top: 16px" + ), + div("Detailed results for the selected comparison genes"), + downloadButton( + NS(id, "download_comparison_results"), + "Download CSV", + class = "btn-outline-primary" + ) + ), + div( + style = "margin-top: 16px; margin-bottom: 8px;", + DT::DTOutput(NS(id, "comparison_results")) + ) ) ) ), @@ -245,6 +269,73 @@ results_server <- function(id, options, analysis) { geposan::plot_scores(ranking(), gene_sets = gene_sets) }) + observe({ + updateTabsetPanel( + session, + "comparison_results_panel", + selected = if (length(comparison_gene_ids()) > 0) "show" else "hide" + ) + }) + + methods <- options$methods + method_ids <- sapply(methods, function(method) method$id) + method_names <- sapply(methods, function(method) method$name) + + columns <- c( + "rank", + "gene", + "name", + "chromosome", + "distance", + method_ids, + "score", + "percentile" + ) + + column_names <- c( + "", + "Gene", + "", + "Chr.", + "Distance", + method_names, + "Score", + "Percentile" + ) + + results_filtered_comparison <- reactive({ + results()[gene %chin% comparison_gene_ids()] + }) + + output$download_comparison_results <- downloadHandler( + filename = "geposan_results_custom.csv", + content = \(file) fwrite( + results_filtered_comparison()[, ..columns], + file = file + ), + contentType = "text/csv" + ) + + output$comparison_results <- DT::renderDT({ + data <- results_filtered_comparison()[, ..columns] + data[, distance := glue::glue( + "{format(round(distance / 1000000, digits = 2), nsmall = 2)} Mbp" + )] + + DT::datatable( + data, + rownames = FALSE, + colnames = column_names, + options = list( + rowCallback = js_link(), + columnDefs = list(list(visible = FALSE, targets = 2)), + pageLength = 25 + ) + ) |> + DT::formatRound(c(method_ids, "score"), digits = 4) |> + DT::formatPercentage("percentile", digits = 2) + }) + output$rankings_plot <- plotly::renderPlotly({ preset <- preset() @@ -360,7 +451,7 @@ results_server <- function(id, options, analysis) { preset()$reference_gene_ids ) - comparison <- if (!is.null(comparison_gene_ids())) { + comparison <- if (length(comparison_gene_ids()) > 0) { geposan::compare(ranking(), comparison_gene_ids()) } From 7b0b8bc8c14ddf043badc03932d2973b8b88d013 Mon Sep 17 00:00:00 2001 From: Elias Projahn Date: Sun, 23 Feb 2025 16:06:12 +0100 Subject: [PATCH 8/8] Version 1.1.0 --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 815597d..63bd4d5 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: geposanui Title: Graphical user interface for geposan -Version: 1.0.1 +Version: 1.1.0 Authors@R: person( "Elias",