Compare commits

..

6 Commits

5 changed files with 291 additions and 16 deletions
+3
View File
@@ -1,2 +1,5 @@
# scMonitor # scMonitor
scMonitor is a shinny application writen in R that allows to easily explore already processed scRNAseq seurat objects.
You can find a video explanation [here](https://ratg.cat/tutos/scMonitor.html).
+109
View File
@@ -0,0 +1,109 @@
WEBVTT
00:00.700 --> 00:02.600
In this video, I will present you
00:02.600 --> 00:05.500
the shinny application scMonitor, which is
00:05.500 --> 00:08.200
oriented to easily explore
00:08.200 --> 00:10.300
a previously processed seurat object.
00:11.600 --> 00:13.800
Firstly, you should select the file
00:13.800 --> 00:16.800
containing the seurat object.
00:16.800 --> 00:19.000
For now, the file format must be RDS.
00:19.700 --> 00:21.600
Depending on the object size and
00:21.600 --> 00:23.800
computer potency the loading
00:23.800 --> 00:25.000
will take more or less time.
00:26.200 --> 00:28.200
UMAP distribution that generates
00:28.400 --> 00:30.000
is the same that shows as default,
00:30.400 --> 00:33.400
usually clusters identified by seurat itself.
00:33.400 --> 00:37.200
We can group colors by any
00:37.200 --> 00:39.300
other variable that we have included in the
00:39.300 --> 00:42.600
metadata from the object specifying it in "GroupBy".
00:43.200 --> 00:45.500
Tipically, the sample origin or
00:45.500 --> 00:46.300
a manual annotation
00:46.300 --> 00:47.700
from the cell type.
00:48.800 --> 00:51.400
Distribution can also be divided by
00:51.400 --> 00:54.500
another variable selecting in "FacetBy".
00:54.500 --> 00:57.300
In this case, we are looking at
00:57.300 --> 00:59.900
the distribution of cell type
00:59.900 --> 01:01.000
by the sample origin.
01:02.800 --> 01:05.800
Another available visualization is to show expression
01:05.800 --> 01:08.100
for a group of genes separated by a white space
01:08.100 --> 01:10.400
over UMAP distribution.
01:11.300 --> 01:13.500
With the "Height" bar we can adjust
01:13.500 --> 01:15.500
the size in order to feel comfortable.
01:18.900 --> 01:22.700
Finally, we can create signatures in order to visualize
01:22.800 --> 01:25.200
their score from cells.
01:25.200 --> 01:27.300
One must indicate the signature name and
01:27.300 --> 01:29.800
on the box below specify the genes
01:29.800 --> 01:32.600
that are included. Once added, you can
01:32.600 --> 01:34.700
specify its name in the
01:34.700 --> 01:35.500
signatures box.
+109
View File
@@ -0,0 +1,109 @@
WEBVTT
00:00.700 --> 00:02.600
En este vídeo os voy a presentar
00:02.600 --> 00:05.500
la aplicación "shinny" scMonitor, que está
00:05.500 --> 00:08.200
orientada a explorar de forma sencilla un
00:08.200 --> 00:10.300
objeto seurat previamente procesado.
00:11.600 --> 00:13.800
Lo primero es seleccionar el fichero que
00:13.800 --> 00:16.800
contiene ese objeto seurat. Por ahora,
00:16.800 --> 00:19.000
el formato del fichero debe RDS.
00:19.700 --> 00:21.600
En función del tamaño del objeto y
00:21.600 --> 00:23.800
de la potencia del ordenador la carga
00:23.800 --> 00:25.000
tardará más o menos.
00:26.200 --> 00:28.200
La distribución UMAP que se genera
00:28.400 --> 00:30.000
es la que se muestra por defecto,
00:30.400 --> 00:33.400
normalmente los "clusters" identificados por el propio seurat.
00:33.400 --> 00:37.200
Podemos agrupar los colores por cualquier
00:37.200 --> 00:39.300
otra variable que hayamos incluido en los
00:39.300 --> 00:42.600
metadatos del objeto especificándolo en "GroupBy".
00:43.200 --> 00:45.500
Típicamente, el origen de la muestra o
00:45.500 --> 00:46.300
una anotación
00:46.300 --> 00:47.700
manual de tipo celular.
00:48.800 --> 00:51.400
También se puede dividir la distribución en
00:51.400 --> 00:54.500
función de una variable seleccionándolo en "FacetBy".
00:54.500 --> 00:57.300
En este caso estamos viendo la
00:57.300 --> 00:59.900
distribución de los tipos celulares en función
00:59.900 --> 01:01.000
del origen de la muestra.
01:02.800 --> 01:05.800
Otra visualización disponible es mostrar la expresión
01:05.800 --> 01:08.100
de conjuntos de genes separados por un
01:08.100 --> 01:10.400
espacio sobre la distribución UMAP.
01:11.300 --> 01:13.500
Con la barra de altura podemos ajustar
01:13.500 --> 01:15.500
el tamaño para que nos sea cómodo.
01:18.900 --> 01:22.700
Finalmente, podemos crear signaturas para luego visualizar
01:22.800 --> 01:25.200
el "score" de las células.
01:25.200 --> 01:27.300
Hay que indicar el nombre de la signatura y
01:27.300 --> 01:29.800
en la casilla inferior especificar los genes
01:29.800 --> 01:32.600
que incluye. Una vez añadida se puede
01:32.600 --> 01:34.700
especificar su nombre en la casilla de
01:34.700 --> 01:35.500
signaturas.
BIN
View File
Binary file not shown.
+68 -14
View File
@@ -2,6 +2,7 @@ library(shiny)
library(Seurat) library(Seurat)
library(shinyFiles) library(shinyFiles)
library(ggplot2) library(ggplot2)
library(ggpubr)
# Define UI for application # Define UI for application
ui <- fluidPage( ui <- fluidPage(
@@ -15,8 +16,13 @@ ui <- fluidPage(
uiOutput('groupby'), uiOutput('groupby'),
uiOutput('facetby'), uiOutput('facetby'),
textInput('features', label = "Genes"), textInput('features', label = "Genes"),
textInput('mods', label = "Signatures"),
actionButton("goButton", "Query"), actionButton("goButton", "Query"),
sliderInput("height", "Altura", min=1000, max=20000, step=1000, value=6000) sliderInput("height", "Altura", min=1000, max=20000, step=1000, value=6000),
h3("Add Signature"),
textInput('mod_name', label = "Name"),
textInput('mod_feat', label = "Genes"),
actionButton("modButton", "Add Signature")
), ),
mainPanel( mainPanel(
@@ -26,11 +32,15 @@ ui <- fluidPage(
) )
) )
# Define server logic required to draw a histogram # Define server logic
server <- function(input, output) { server <- function(input, output) {
## Defining reactive values
dades<-reactiveValues() dades<-reactiveValues()
dades$seu<-NULL dades$seu<-NULL
dades$mods<-NULL
## Conecting with file location and entering Seurat object
volumes <- c(Home = fs::path_home(), "R Installation" = R.home(), getVolumes()()) volumes <- c(Home = fs::path_home(), "R Installation" = R.home(), getVolumes()())
shinyFileChoose(input, 'file', roots=volumes) shinyFileChoose(input, 'file', roots=volumes)
@@ -40,6 +50,7 @@ server <- function(input, output) {
} }
}) })
## Rendering UI depending on seu meta.data
output$groupby<-renderUI({ output$groupby<-renderUI({
if (!is.null(dades$seu)){ if (!is.null(dades$seu)){
selectInput("groupby", "GroupBy", c("Default", colnames(dades$seu@meta.data))) selectInput("groupby", "GroupBy", c("Default", colnames(dades$seu@meta.data)))
@@ -52,10 +63,7 @@ server <- function(input, output) {
} }
}) })
query<-eventReactive(input$goButton,{ ## Render DimPlot
dades$fet_query<-strsplit(input$features, " ")[[1]]
})
output$umapPlot <- renderPlot({ output$umapPlot <- renderPlot({
observeEvent(dades$seu, {}) observeEvent(dades$seu, {})
if (!is.null(dades$seu)){ if (!is.null(dades$seu)){
@@ -68,6 +76,21 @@ server <- function(input, output) {
} }
}) })
## Signature - Module Definition
observeEvent(input$modButton, {
if (input$modButton > 0){
mod_list<-strsplit(input$mod_feat, " ")[[1]]
mod_list<-mod_list[mod_list %in% rownames(dades$seu)]
dades$seu<-AddModuleScore(dades$seu,list(mod_list),
name=input$mod_name)
}
})
## FeaturePlot construction
query<-eventReactive(input$goButton,{
dades$fet_query<-strsplit(input$features, " ")[[1]]
})
output$featPlotUI<- renderUI({ output$featPlotUI<- renderUI({
observeEvent(dades$fet_query, {}) observeEvent(dades$fet_query, {})
if (!is.null(dades$seu)){ if (!is.null(dades$seu)){
@@ -76,16 +99,47 @@ server <- function(input, output) {
} }
}) })
output$featPlot<-renderPlot({ ## ModulePlot/SigPlot construction
observeEvent(dades$seu, {}) query_mod<-eventReactive(input$goButton,{
if (!is.null(dades$seu)){ if (length(strsplit(input$mods, " ")[[1]]) > 0){
query() dades$mods<-paste(strsplit(input$mods, " ")[[1]], "1", sep="")
}else{
FeaturePlot(dades$seu, dades$mods<-NULL
split.by=if(input$facetby != "None"){input$facetby}else{NULL},
features = dades$fet_query)&theme(aspect.ratio = 1)
} }
}) })
output$modPlotUI<- renderUI({
observeEvent(dades$mod_name, {})
if (!is.null(dades$mod_name)){
plotOutput("modPlot",
height = paste0(input$height/10,"px"))
}
})
## Feature/Mod plot rendering
output$featPlot<-renderPlot({
observeEvent(input$goButton, {})
if (!is.null(dades$seu)){
query()
plot<-list()
print(dades$fet_query)
if (length(dades$fet_query) > 0){
plot[["Genes"]]<-FeaturePlot(dades$seu,
split.by=if(input$facetby != "None"){input$facetby}else{NULL},
features = dades$fet_query)&theme(aspect.ratio = 1)
}
query_mod()
print(dades$mods)
if (length(dades$mods) > 0){
plot[["Mods"]]<-FeaturePlot(dades$seu,
split.by=if(input$facetby != "None"){input$facetby}else{NULL},
features = dades$mods)&theme(aspect.ratio = 1)&scale_color_viridis_c()
}
do.call(ggarrange, c(plot, ncol=1))
}
})
} }
# Run the application # Run the application