Skip to content

Commit e4cd933

Browse files
committed
add rshiny app
1 parent c3a6541 commit e4cd933

File tree

7 files changed

+641
-24
lines changed

7 files changed

+641
-24
lines changed

DESCRIPTION

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ Suggests:
6969
MCPcounter (>= 1.2.0),
7070
knitr,
7171
matlib,
72-
rmarkdown
72+
rmarkdown,
73+
shiny,
74+
pkgload
7375
LazyData: true
7476
LazyDataCompression: bzip2
7577
Config/testthat/edition: 3

R/cell_deconvolution.R

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ standardize_celltype_colnames <- function(mat) {
121121

122122
## CD4 and subtypes
123123
lower <- stringr::str_to_lower(colnames(mat))
124-
is_cd4 <- grepl("\\bcd4\\b", lower)
124+
is_cd4 <- grepl("\\bcd4\\b|reg|regulatory", lower)
125125
is_tcell_variant <- grepl("(^|[^a-z0-9])(t|tcell|t\\.cells|t_cells|t cells)([^a-z0-9]|$)", lower, perl = TRUE)
126126
is_memory <- grepl("memory", lower)
127127
cd4_idx <- which(is_cd4 | (is_tcell_variant & is_memory))
@@ -170,15 +170,15 @@ standardize_celltype_colnames <- function(mat) {
170170
colnames(blocks$CD4.non.regulatory) <- stringr::str_replace(
171171
colnames(blocks$CD4.non.regulatory),
172172
"(?i)^(.*?)(?:_)?(T[_\\.-]?cell[_\\.-]?CD4[_\\.-]?.*non[._-]?regulatory.*|T[_\\.-]?cells?[_\\.-]?.*non[._-]?regulatory.*|CD4[_\\.-]?non[._-]?regulatory.*|T\\.cells\\.non\\.regulatory|T_cells_non_regulatory|nonregulatory|non[\\W_]?reg)$",
173-
"\\1_CD4.non.regulatory"
173+
"CD4.non.regulatory"
174174
)
175175
}
176176
if (ncol(blocks$CD4.regulatory)){
177177
mat <- mat[, !colnames(mat) %in% colnames(blocks$CD4.regulatory), drop = FALSE]
178178
colnames(blocks$CD4.regulatory) <- stringr::str_replace(
179179
colnames(blocks$CD4.regulatory),
180180
"(?i)^(.*?)(?:_)?(T[_\\.-]?cell[_\\.-]?regulatory.*|T[_\\.-]?cells?[_\\.-]?regulatory.*|T\\.cells\\.regulatory.*|tregs?\\.?$|tregulatory.*|regulatory.*)$",
181-
"\\1_CD4.regulatory"
181+
"CD4.regulatory"
182182
)
183183
}
184184

@@ -2987,6 +2987,21 @@ create_gsea_signature <- function(gene_scores,
29872987
pos <- fg %>%
29882988
dplyr::filter(!is.na(NES) & NES > 0) %>% # Keep positive NES
29892989
dplyr::arrange(dplyr::desc(NES)) # Arrange by descending NES
2990+
2991+
#fg_top <- fg %>%
2992+
# dplyr::filter(!is.na(NES)) %>%
2993+
# dplyr::arrange(dplyr::desc(dplyr::abs(NES))) %>%
2994+
# dplyr::slice_head(n = 20) %>%
2995+
# dplyr::mutate(pathway = factor(pathway, levels = rev(pathway)),
2996+
# sig = -log10(padj + 1e-300))
2997+
2998+
#ggplot(fg_top, aes(x = NES, y = pathway, size = size, color = sig)) +
2999+
# geom_point() +
3000+
# scale_color_viridis_c(name = "-log10(padj)") +
3001+
# scale_size_continuous(name = "pathway size") +
3002+
# labs(title = "FGSEA — top 20 pathways", x = "NES", y = NULL) +
3003+
# theme_minimal(base_size = 12)
3004+
29903005
if (nrow(pos) == 0) stop("No pathways with NES > 0 found")
29913006
first_pathway <- as.character(pos$pathway[1])
29923007
suffix <- stringr::str_replace_all(first_pathway, "[^A-Za-z0-9]+", "_") # Replace non-alphanumeric characters with underscores
@@ -3009,7 +3024,7 @@ expand_subgroup_members <- function(subgroup, subgroup_map) {
30093024
}
30103025

30113026

3012-
compute_deconvolution_dictionary <- function(subgroups, expr) {
3027+
compute_deconvolution_dictionary <- function(subgroups, expr, pathways = NULL) {
30133028

30143029
subgroup_map <- subgroups[["Deconvolution subgroups composition"]]
30153030
deconv_mat = subgroups[["Deconvolution matrix"]]
@@ -3029,7 +3044,7 @@ compute_deconvolution_dictionary <- function(subgroups, expr) {
30293044
deconv = deconv_mat,
30303045
subgroup = sub_name) # Compute correlation rankings for the subgroup
30313046

3032-
sig_out <- create_gsea_signature(ranked, sub_name) # create pathwyas signature
3047+
sig_out <- create_gsea_signature(ranked, sub_name, pathways) # create pathwyas signature
30333048
if (is.null(sig_out)) next # No enrichment found, skip to next subgroup
30343049
new_label <- sig_out[[1]]
30353050
idx <- which(colnames(deconv_mat) == sub_name) # replace column name in deconv_mat if present
@@ -3047,21 +3062,3 @@ compute_deconvolution_dictionary <- function(subgroups, expr) {
30473062

30483063
return(subgroups)
30493064
}
3050-
3051-
library(ggplot2)
3052-
library(dplyr)
3053-
library(viridis)
3054-
# FGSEA dotplot (top 20 by |NES|)
3055-
fg_top <- fgseaRes |>
3056-
filter(!is.na(NES)) |>
3057-
arrange(desc(abs(NES))) |>
3058-
slice_head(n = 20) |>
3059-
mutate(pathway = factor(pathway, levels = rev(pathway)),
3060-
sig = -log10(padj + 1e-300))
3061-
3062-
ggplot(fg_top, aes(x = NES, y = pathway, size = size, color = sig)) +
3063-
geom_point() +
3064-
scale_color_viridis_c(name = "-log10(padj)") +
3065-
scale_size_continuous(name = "pathway size") +
3066-
labs(title = "FGSEA — top 20 pathways", x = "NES", y = NULL) +
3067-
theme_minimal(base_size = 12)

README.Rmd

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,33 @@ Users can also compute second-generation deconvolution methods using their singl
9090
deconv_sc = compute_sc_deconvolution_methods(raw_counts, sc_object, sc_metadata, cell_annotations, samples_ids, name_object, normalized = T, n_cores = 4, cbsx_name = "XXX", cbsx_token = "XXX")
9191
```
9292

93+
## Shiny app
94+
95+
`multideconv` includes an interactive Shiny app for non-coding users with four tabs: **Welcome**, **Deconvolution**, **Analysis**, and **Benchmark**.
96+
97+
From the repository root, run:
98+
99+
``` bash
100+
Rscript -e "shiny::runApp('inst/shiny', host='127.0.0.1', port=3838, launch.browser=TRUE)"
101+
```
102+
103+
Or from an R session:
104+
105+
``` r
106+
setwd("~/path/to/multideconv")
107+
shiny::runApp("inst/shiny", host = "127.0.0.1", port = 3838, launch.browser = TRUE)
108+
```
109+
110+
If port `3838` is already in use, choose another one (for example `3840`) and open:
111+
112+
`http://127.0.0.1:3840`
113+
114+
You can stop old Shiny processes with:
115+
116+
``` bash
117+
pkill -f "shiny::runApp\\('inst/shiny'"
118+
```
119+
93120
## Cell types nomenclature
94121

95122
`multideconv` works based on established cell naming conventions (Figure 2) to simplify analysis and processing. Thus, if you would like to use your own deconvolution results or signatures, please make sure to follow these formats.

README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,36 @@ already included in `compute.deconvolution` when setting
106106
deconv_sc = compute_sc_deconvolution_methods(raw_counts, sc_object, sc_metadata, cell_annotations, samples_ids, name_object, normalized = T, n_cores = 4, cbsx_name = "XXX", cbsx_token = "XXX")
107107
```
108108

109+
## Shiny app
110+
111+
`multideconv` includes an interactive Shiny app for non-coding users with
112+
four tabs: **Welcome**, **Deconvolution**, **Analysis**, and
113+
**Benchmark**.
114+
115+
From the repository root, run:
116+
117+
``` bash
118+
Rscript -e "shiny::runApp('inst/shiny', host='127.0.0.1', port=3838, launch.browser=TRUE)"
119+
```
120+
121+
Or from an R session:
122+
123+
``` r
124+
setwd("~/path/to/multideconv")
125+
shiny::runApp("inst/shiny", host = "127.0.0.1", port = 3838, launch.browser = TRUE)
126+
```
127+
128+
If port `3838` is already in use, choose another one (for example
129+
`3840`) and open:
130+
131+
`http://127.0.0.1:3840`
132+
133+
You can stop old Shiny processes with:
134+
135+
``` bash
136+
pkill -f "shiny::runApp\\('inst/shiny'"
137+
```
138+
109139
## Cell types nomenclature
110140

111141
`multideconv` works based on established cell naming conventions (Figure

inst/shiny/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# multideconv Shiny app
2+
3+
This app exposes the main multideconv workflows from the package source and vignette:
4+
5+
1. `compute.deconvolution`
6+
2. `compute.deconvolution.analysis`
7+
3. `compute.benchmark`
8+
9+
It includes built-in example datasets and file upload options.
10+
11+
## Run
12+
13+
From the repository root:
14+
15+
```r
16+
shiny::runApp("inst/shiny")
17+
```
18+
19+
If `multideconv` is not installed, the app tries to load the package from source using `pkgload::load_all()`.

0 commit comments

Comments
 (0)