Commit 63c73f90 authored by Bagueneau Mathias's avatar Bagueneau Mathias
Browse files

- Optimisations

parent a59f91a6
......@@ -26,6 +26,7 @@ library(PANTHER.db)
library(topGO)
library(ggpubr)
library(colourpicker)
library(shinyjqui)
source("utils.R")
source("config.R")
......@@ -33,7 +34,7 @@ source("config.R")
### ----------------------------- User interface --------------------------------------------------
## HEADER --------
useShinyjs()
header <- dashboardHeader(tags$li(class="dropdown",
header <- dashboardHeader(tags$li(class="dropdown", # Text for every tabs
conditionalPanel(condition="input.tabs == 'visu_item'",
tags$p(style="color:white;font-size:25px;margin-right:20px","- Visualization -")),
conditionalPanel(condition="input.tabs == 'heatmap_item'",
......@@ -46,12 +47,13 @@ source("config.R")
tags$p(style="color:white;font-size:25px;margin-right:20px","- Pipeline -")),
conditionalPanel(condition="input.tabs == 'grid_item'",
tags$p(style="color:white;font-size:25px;margin-right:20px","- Grid -")),
tags$head(HTML("<link rel='icon' href='min.png'>"))
tags$head(HTML("<link rel='icon' href='min.png'>")
)
))
anchor <- tags$a(tags$img(src='logo.png', height='30', width='20'),'Shiny SChnurR', style="color: white")
anchor <- tags$a(tags$img(src='logo.png', height='30', width='20'),'Shiny SChnurR', style="color: white") # Logo & Title
header$children[[2]]$children <- tags$div(tags$head(tags$style(HTML(".name { background-color: transparent } .content-wrapper, .right-side {background-color: white}"))),anchor)
header[["children"]][[2]][["children"]][["name"]] <- "Shiny SChnurR"
## SIDEBAR --------
sidebar <- dashboardSidebar(
tags$style(type="text/css",
......@@ -59,7 +61,7 @@ source("config.R")
".shiny-output-error:before { visibility: hidden; }"),
br(),
# Menu -------
sidebarMenu(id="tabs",
sidebarMenu(id="tabs", # The tabs are define here (icon + title)
menuItem("Visualization", tabName="visu_item", icon=icon("area-chart"), selected = TRUE),
menuItem("Heatmap", tabName = "heatmap_item", icon=icon("fas fa-align-justify")),
menuItem("Genes", tabName = "genes_item", icon=icon("dna")),
......@@ -85,9 +87,6 @@ source("config.R")
radioButtons(inputId="graph_visu",
label= "Choose the graph mode :", c("t-SNE" = "tsne", "UMAP" = "umap"),
selected = "umap"),
checkboxInput(inputId="show_clusters_visu",
label="Clusters information",
value=FALSE),
sliderInput(inputId="ptsize_visu",
label="Point size :",
min=0.1, max=2,
......@@ -165,10 +164,7 @@ source("config.R")
step=0.1, value = 0.6,
ticks = FALSE),
conditionalPanel(condition = "input.choice_compare == 'class_compare'",
ColorPalettes("color_palettes_compare"), # Go into config.R to custom the available color palette !
checkboxInput(inputId="show_clusters_compare",
label="Clusters information",
value=FALSE)),
ColorPalettes("color_palettes_compare")), # Go into config.R to custom the available color palette !
radioButtons("ontology_compare",
label="Choose an ontology :",
choices=c("Biological Process"="BP", "Molecular Function"="MF", "Cellular Component" = "CC")))))
......@@ -224,23 +220,26 @@ source("config.R")
br(),
htmlOutput(outputId = "file_infos_visu"),
br(),
checkboxInput(inputId="show_clusters_visu",
label="Clusters information",
value=FALSE),
uiOutput(outputId = "clusters_infos_visu"),
verbatimTextOutput(outputId = "select_infos_visu"),
br(),
fluidRow(column(align="center",
width = 6,
plotlyOutput("classplot_visu",
jqui_resizable(plotlyOutput("classplot_visu", # Remove jqui_resizable for better perfs
width='500px',
height='500px'),
height='500px')),
ColorPalettes("color_palettes_visu"), # Go into config.R to custom the available color palette !
uiOutput("class_choice_visu"),
downloadButton("dlclassplot_visu",
label="Export Plot")),
column(align="center",
width = 6,
plotlyOutput("featureplot_visu",
jqui_resizable(plotlyOutput("featureplot_visu",
width='500px',
height='500px'),
height='500px')),
# colourInput("featureplot_color_visu", # Color picker
# label = "Choose a color :",
# value = "blue",
......@@ -292,6 +291,9 @@ source("config.R")
tabItem(tabName="compare_item", align="center",
br(),
verbatimTextOutput(outputId = "select_infos_compare"),
checkboxInput(inputId="show_clusters_compare",
label="Clusters information",
value=FALSE),
uiOutput(outputId = "clusters_infos_compare"),
br(),
conditionalPanel(condition="output.fileUploaded",
......@@ -633,7 +635,7 @@ server <- function(input, output, session) {
output$genes_number_heatmap <- renderUI ({
sliderInput("top_genes_number_heatmap", label="Choose the number of top genes :", min=1, max=10, step=1, value=3)
})
observeEvent({list(input$class_selector_heatmap,input$top_genes_number_heatmap)},
observeEvent({list(input$class_selector_heatmap,input$top_genes_number_heatmap)}, # Changing on of these inputs will update the text and announce that recalculation is needed.
{req(input$go_heatmap)
output$status_heatmap <- renderText({"Needs recalculation"})})
......@@ -658,7 +660,7 @@ server <- function(input, output, session) {
topgenes <- filedata$data@misc$markers[[input$class_selector_heatmap]] %>% group_by(cluster) %>% top_n(n = input$top_genes_number_heatmap, wt = avg_logFC)
datascale <- withProgress(ScaleData(object = filedata$data,
features = topgenes$gene), message = "Scaling data...", value=1)
}
} # Heatmap generation
heatmap_Data <- withProgress(DoHeatmap(object = datascale,
features = topgenes$gene,
group.by=input$class_selector_heatmap), message = "Heatmap Generation", value=1) +
......@@ -688,7 +690,7 @@ server <- function(input, output, session) {
})
## Genes Page --------
observeEvent({list(input$class_selector_genes,input$group_selector_genes,input$gograph_genes,input$ontology_genes)},
observeEvent({list(input$class_selector_genes,input$group_selector_genes,input$gograph_genes,input$ontology_genes)}, # Changing on of these inputs will update the text and announce that recalculation is needed.
{req(input$go_go)
output$status_genes <- renderText({"Needs recalculation"})})
......@@ -804,9 +806,9 @@ server <- function(input, output, session) {
})
## Compare Page 1 - Graphs generations, outputs and downloads --------
observeEvent({list(input$group_selector1_compare,input$group_selector2_compare,input$addgroup_selector1_compare,input$addgroup_selector2_compare,
observeEvent({list(input$group_selector1_compare,input$group_selector2_compare,input$addgroup_selector1_compare,input$addgroup_selector2_compare,
input$class_selector_compare,input$add_class_selector_compare,input$graph_compare,input$ptsize_compare, input$color_palettes_compare,
input$choice_compare,input$feature_selector_compare,input$qv_selector_compare,input$genes_list_compare)},
input$choice_compare,input$feature_selector_compare,input$qv_selector_compare,input$genes_list_compare)}, # Changing on of these inputs will update the text and announce that recalculation is needed.
{req(input$go_plots_compare)
output$status_plots_compare <- renderText({"Needs recalculation"})})
......@@ -1102,7 +1104,7 @@ server <- function(input, output, session) {
})
observeEvent({list(input$group_selector1_compare,input$group_selector2_compare,input$addgroup_selector1_compare,input$addgroup_selector2_compare,
input$class_selector_compare,input$add_class_selector_compare)},
input$class_selector_compare,input$add_class_selector_compare)}, # Changing on of these inputs will update the text and announce that recalculation is needed.
{ req(input$findmarkers)
output$status_markers_compare <- renderText({"Needs recalculation"})})
......@@ -1124,7 +1126,7 @@ server <- function(input, output, session) {
} else {
tempdata <- filedata$data # Tempfile for FindMarkers : allows to change Idents() with no bug ( using Idents(filedata$data) <<- ... was tested but is buggy)
Idents(object=tempdata) <- as.factor(paste0(eval(parse(text=paste0("filedata$data@meta.data$",input$class_selector_compare))), eval(parse(text=paste0("filedata$data@meta.data$",input$add_class_selector_compare)))))
findmarkers_compare_results <- FindMakersCompare(tempdata, input$group_selector1_compare, input$group_selector2_compare, input$addgroup_selector1_compare, input$addgroup_selector2_compare, input$class_selector_compare, "in")
findmarkers_compare_results <- FindMarkersCompare(tempdata, input$group_selector1_compare, input$group_selector2_compare, input$addgroup_selector1_compare, input$addgroup_selector2_compare, input$class_selector_compare, "in")
tempdata <- NULL
}
}
......@@ -1137,7 +1139,7 @@ server <- function(input, output, session) {
} else {
tempdata <- filedata$data # Tempfile for FindMarkers : allows to change Idents() with no bug ( using Idents(filedata$data) <<- ... was tested but is buggy)
Idents(object=tempdata) <- input$class_selector_compare
findmarkers_compare_results <- FindMakersCompare(tempdata, input$group_selector1_compare, input$group_selector2_compare, "", "", input$class_selector_compare, "")
findmarkers_compare_results <- FindMarkersCompare(tempdata, input$group_selector1_compare, input$group_selector2_compare, "", "", input$class_selector_compare, "")
tempdata <- NULL
}
}
......@@ -1150,24 +1152,24 @@ server <- function(input, output, session) {
filter="top",
caption = "Table : Significant markers of your query | Test used : MAST" ), message = "Render DataTable", value=1) %>% formatRound(columns=c(1,2,3,4), digits=3) %>% formatSignif(columns=c(6,5), digits=3)
})
output$topgenes1_compare <- renderUI ({
output$topgenes1_compare <- renderUI ({ # Genes List for Ontology
textAreaInput("toplist1_compare",
"Top 30 upregulated left genes",
"Data Summary",
width = "100px", height = "620px",
value = paste(sapply(findmarkers_compare_results$leftgenes_compare$Gene, paste, collapse=""), collapse="\n"))
})
output$topgenes2_compare <- renderUI ({
output$topgenes2_compare <- renderUI ({# Genes List for Ontology (right)
textAreaInput("toplist2_compare",
"Top 30 upregulated right genes",
"Data Summary",
width = "100px", height = "620px",
value = paste(sapply(findmarkers_compare_results$rightgenes_compare$Gene, paste, collapse=""), collapse="\n"))
})
output$dlmarkbutton_compare <- renderUI ({
output$dlmarkbutton_compare <- renderUI ({ # Markers table
downloadButton("dlmarkers_compare", label="Export Table")
})
output$dlmarkers_compare <- downloadHandler(
output$dlmarkers_compare <- downloadHandler( # Dl markers table
filename = function() {
paste0(file_path_sans_ext(filedata$name),"_markers_",names(findmarkers_compare_results$findmarkers_compareData)[[7]],".csv")
},
......@@ -1179,7 +1181,7 @@ server <- function(input, output, session) {
## Compare Page 3 - FindOntology --------
observeEvent({list(input$findmarkers, input$group_selector1_compare,input$group_selector2_compare,input$addgroup_selector1_compare,input$addgroup_selector2_compare,
input$class_selector_compare,input$add_class_selector_compare,input$ontology_compare,input$toplist1_compare,input$toplist2_compare)},
input$class_selector_compare,input$add_class_selector_compare,input$ontology_compare,input$toplist1_compare,input$toplist2_compare)}, # Changing on of these inputs will update the text and announce that recalculation is needed.
{req(input$go_ontology_compare)
output$status_markers_onto <- renderText({"Needs recalculation (maybe after computing another 'Find Markers')"})})
......@@ -1194,7 +1196,7 @@ server <- function(input, output, session) {
if (is.null(input$toplist1_compare) || is.null(input$toplist2_compare)) {
showModal(modalDialog("At least one of the text area is empty !", title=strong("Warning !"), easyClose=TRUE, footer = NULL ))
} else {
} else { # Ontology
GOleft_compareData <- FindOntologyCompare(input$toplist1_compare, input$ontology_compare)
GOright_compareData <- FindOntologyCompare(input$toplist2_compare, input$ontology_compare)
......@@ -1209,7 +1211,7 @@ server <- function(input, output, session) {
downloadButton("dlonto1_compare", label="Export Table")
})
output$dlonto1_compare <- downloadHandler(
output$dlonto1_compare <- downloadHandler( # Dl Ontology table (left)
filename = function() {
paste0(file_path_sans_ext(filedata$name),"_onto_",input$ontology_compare,"_datatable_",input$class_selector_compare,".csv")
},
......@@ -1227,7 +1229,7 @@ server <- function(input, output, session) {
downloadButton("dlonto2_compare", label="Export Table")
})
output$dlonto2_compare <- downloadHandler(
output$dlonto2_compare <- downloadHandler( # Dl Ontology table (right)
filename = function() {
paste0(file_path_sans_ext(filedata$name),"_onto_",input$ontology_compare,"_datatable_",input$class_selector_compare,".csv")
},
......@@ -1239,7 +1241,7 @@ server <- function(input, output, session) {
})
## Grid Page --------
observeEvent({list(input$ptsize_grid, input$graph_grid, input$genes_list_grid, input$ncolumns_grid)},
observeEvent({list(input$ptsize_grid, input$graph_grid, input$genes_list_grid, input$ncolumns_grid)}, # Changing on of these inputs will update the text and announce that recalculation is needed.
{req(input$gridgraphs)
output$status_grid <- renderText({"Needs recalculation"})})
......@@ -1351,7 +1353,7 @@ server <- function(input, output, session) {
observeEvent (input$help_genes, {showModal(modalDialog(HelptextGenes(), title=strong("Genes page Help"), easyClose=TRUE, footer = NULL))})
observeEvent (input$help_compare, {showModal(modalDialog(HelptextCompare(), title=strong("Compare page Help"), easyClose=TRUE, footer = NULL))})
observeEvent (input$help_grid, {showModal(modalDialog(HelptextGrid(), title=strong("Grid page Help"), easyClose=TRUE, footer = NULL))})
# Go to config.R to update the help messages !
}
### ----------------------------- Run the app -----------------------------------------------------
......
......@@ -6,6 +6,7 @@
## Visualization page : file information text ----
# -> filename : the name of your uploaded file, obj : the file you uploaded
FileInformation <- function(filename, obj) {
az <- paste(strong("Filename :"), filename)
er <- paste(strong("Genes number :"), length(rownames(obj)), " | ",strong("Cells number :"), length(Cells(obj)), " | ",strong("Median genes/cell :"), median(obj@meta.data$nFeature_SCT))
......@@ -14,6 +15,7 @@ FileInformation <- function(filename, obj) {
}
## Editable Help Texts ----
# Here you just have to customize the help texts
# Visualization Page :
HelptextVisu <- function () {
......@@ -26,7 +28,7 @@ A data table with some pre-calculated markers.
The first plot allows you to visualise by all the class (resolution, idents, ...) of your file.
The second one is for the features or quantitative variables (all the genes repartitions, scores, ...).
The two graphs could be controlled with the panel made for. You have two graph modes : t-SNE or UMAP, and clusters information for every factors.
On the plots, you could also select some cells, and have the percentage of your selection by the total cell number.
On the plots, you could also select some cells, and have the percentage of your selection by the total cell number. The graphs colors are also editable.
The data table under the graphs is pre-calculated depending the selected class.
It shows all significant markers, calculated with the test MAST. You could affine your marker research with the filters.
All of the outputs are exportable : in .svg for the plots and in .csv for the table.")}
......@@ -79,6 +81,7 @@ selectInput(inputId = "presets_grid",
}
# Then : add and/or edit the genes lists here :
# -> shiny_session : shiny_session : the session of your Shiny app (named "session" most of the time), input.presets : the preset choice
PresetsListgenesGrid <- function(shiny_session, input.presets) {
if (input.presets == "plasmacells") {
updateSelectizeInput(shiny_session, "genes_list_grid", selected=c("IRF4","XBP1","PRDM1","IGKC","IGLC2","IGLC3","IGHM","IGHG1","IGHG2","IGHG3","IGHG4", "IGHA1","IGHE","IGHD","SDC1","CD38","CD19","MS4A1","SLAMF7","TNFRSF17"))
......@@ -90,6 +93,7 @@ PresetsListgenesGrid <- function(shiny_session, input.presets) {
}
## Color palettes ----
# -> inputname : the name of the Shiny input object
ColorPalettes <- function(inputname) {
selectInput(inputId = as.character(inputname),
label="Choose a color palette :",
......
......@@ -21,6 +21,7 @@ install.packages("devtools")
install.packages("BiocManager")
install.packages("ggpubr")
install.packages("colourpicker")
install.packages('shinyjqui')
BiocManager::install("clusterProfiler")
BiocManager::install("MAST")
BiocManager::install("org.Hs.eg.db")
......
......@@ -6,6 +6,7 @@
## AssignColors function ----
# -> obj : the file you uploaded, ident : every class of the object, palette : the color palette you want
AssignColors <- function(obj, ident, palette){
ident <- as.factor(ident)
nr.groups <- length(levels(ident))
......@@ -15,6 +16,7 @@ AssignColors <- function(obj, ident, palette){
}
## Function which use assign.colors to give a color for each group of each class ----
# -> obj : the file you uploaded, palette : the color palette you want
AllClassColors <- function(obj, palette) {
coldf <- lapply(obj@meta.data[,sapply(obj@meta.data, class) %in% c("factor","character")],
AssignColors,
......@@ -24,13 +26,15 @@ return(coldf)
}
## Update Gene lists function ----
# -> obj : the file you uploaded, shiny_session : the session of your Shiny app (named "session" most of the time), genes_list : list of the genes (typically the rownames of your object)
# -> inputname : the name of the Shiny input object, selected_choice : the gene selected when launching the app
UpdateGeneslist <- function(obj, shiny_session, genes_list, inputname, selected_choice = "IGKC") {
genesList <- rownames(obj)
updateSelectizeInput(shiny_session, as.character(inputname), choices = genes_list, selected = selected_choice)
}
## Scale X and Scale Y functions ----
# -> obj : the file you uploaded, reduction : the graph mode (t-SNR or UMAP)
Scalex <- function(obj, reduction) {
x <- scale_x_continuous(limits = c(min(obj@reductions[[reduction]]@cell.embeddings[,1]), max(obj@reductions[[reduction]]@cell.embeddings[,1])))
}
......@@ -39,19 +43,20 @@ Scaley <- function(obj, reduction ) {
y <- scale_y_continuous(limits = c(min(obj@reductions[[reduction]]@cell.embeddings[,2]), max(obj@reductions[[reduction]]@cell.embeddings[,2])))
}
## NoFile texts function ----
# -> file1 : file uploaded with the box, file2 : file uploaded with the list
NoFile <- function(file1, file2) {
if ((is.null(file1)) && (file2 =="")) {print("Please upload or choose a file")}
}
## Class choices function ----
# -> inputname : the name of the Shiny input object, obj : the file you uploaded, selected_choice : the resolution selected when launching the app
ClassChoices <- function(inputname, obj, selected_choice = "integrated_snn_res.0.4") {
selectizeInput(as.character(inputname), "Choose a Class :", choices = names(rapply(obj@meta.data, class=c("factor","character"), f=class)), selected = as.character(selected_choice))
}
## Link class choices function ----
# -> shiny_session : the session of your Shiny app, cl_selX : the class selectors to link with each others, cl_selected : the class selector selected when launching the app
LinkClassChoices <- function(shiny_session, cl_sel1, cl_sel2, cl_sel3, cl_selected) {
updateSelectizeInput(shiny_session, as.character(cl_sel1), selected = cl_selected)
updateSelectizeInput(shiny_session, as.character(cl_sel2), selected = cl_selected)
......@@ -59,14 +64,15 @@ LinkClassChoices <- function(shiny_session, cl_sel1, cl_sel2, cl_sel3, cl_select
}
## Filter by groups function----
# -> obj : the file you uploaded, input_class_selector : the selected class (from the class selector), inputname : the name of the Shiny input object
GroupChoices <- function(obj, input_class_selector, inputname) {
choice <- unique(eval(parse(text=paste0("obj@meta.data$",input_class_selector))))
if(!is.na(choice)) {
selectInput(as.character(inputname), "Choose a group :", multiple = TRUE, choices = choice[order(choice)]) }
}
## Genes or Quantitative variable choice function ----
# -> inputname : the name of the Shiny input object, g : choices for the genes, d : choice for the other data (quantitative variables)
GenesOrQv <- function(inputname, g, d) {
selectInput(as.character(inputname),
"Choose a Feature :",
......@@ -75,26 +81,31 @@ GenesOrQv <- function(inputname, g, d) {
}
## Qv choices function ----
# -> obj : the file you uploaded, inputname : the name of the Shiny input object
QvChoices <- function(inputname, obj) {
selectInput(as.character(inputname),
"Choose a Quantitative variable :",
choices = names(rapply(obj@meta.data, class=c("numeric","integer"), f=class)),
selected = names(rapply(obj@meta.data, class=c("numeric","integer"), f=class)))
}
## Clusters information function ----
# -> obj : the file you uploaded, input_class_selector : the selected class (from the class selector)
ClustersInformation <- function(obj, input_class_selector) {
clusters_infos_Data <- data.table("Cluster" = levels(as.factor(obj@meta.data[[input_class_selector]])), "Cells_nb" = as.vector(summary(as.factor(obj@meta.data[[input_class_selector]]))), "Percentage" =formatC(((as.vector(summary(as.factor(obj@meta.data[[input_class_selector]])))/length(as.factor(obj@meta.data[[input_class_selector]])))*100),digits=2, format ="f" ))
t(head(clusters_infos_Data, n=999 ))
}
## Cell selection information text function ----
# -> obj : the file you uploaded, input_class_selector : the selected class (from the class selector)
SelectionInformation <- function(obj, input_class_selector) {
select_infos_Data <- paste0("Your selection : Cells nb : ", nrow(event_data("plotly_selected")), " | % : ", formatC(((nrow(event_data("plotly_selected"))/length(obj@meta.data[[input_class_selector]]))*100),digits=2, format ="f" ) )
if (is.null(nrow(event_data("plotly_selected")))) "Please select some cells" else select_infos_Data
}
## Compare page : Data for the plots function ----
# -> obj : the file you uploaded, class : the selected class, group : the chosen group from the class (ex : cluster 0 from res0.4)
# -> add : the button (+) for adding a class, addclass : the added class, addgroup : the chosen group from the added class
CellsToPlot <- function(obj, class, group, add, addclass, addgroup) {
data <- SubsetData(object = obj,
cells=rownames(obj@meta.data)[which(eval(parse(text=paste0("obj@meta.data$",class))) %in% group)] )
......@@ -104,12 +115,16 @@ CellsToPlot <- function(obj, class, group, add, addclass, addgroup) {
}
return(data)
}
## Compare page : Meta.data for csv export function ----
# -> cells : the subset of the selected cells, obj : the file you uploaded
MetaData <- function(cells, obj) {
data <- data.frame(FetchData(cells,
names(rapply(obj@meta.data, class=c("factor","character","numeric","integer"), f=class))))
}
## Compare page : Scale color for feature plots ----
# -> obj : the file you uploaded, var : the selected variable (genes or qv), cells : the subset of the selected cells,
ScaleColors <- function(obj, var, cells) {
palette.full <- c("lightgrey", plasma(200))
data.max.global <- max(FetchData(obj, var))
......@@ -117,8 +132,11 @@ ScaleColors <- function(obj, var, cells) {
palette.local <- palette.full[1:ceiling(length(palette.full) * data.max.local / data.max.global)]
return(palette.local)
}
## Compare page : Custom FindMarkers function ----
FindMakersCompare <- function(tempdata, group1, group2, addgroup1, addgroup2, class, word) {
# -> tempdata : the tempdata object (created with the data from the uploaded file), groupX : the two chosen groups from the class, addgroupX : the two added groups if a second class is added
# -> class : the selected class, word : for the name of a column , link word when two classes are chosen
FindMarkersCompare <- function(tempdata, group1, group2, addgroup1, addgroup2, class, word) {
df <- withProgress(data.frame(FindMarkers(tempdata,
paste0(group1, addgroup1),
paste0(group2, addgroup2),
......@@ -136,8 +154,9 @@ FindMakersCompare <- function(tempdata, group1, group2, addgroup1, addgroup2, cl
}
## Compare page : Gene Ontology function ----
FindOntologyCompare <- function(gene_list, ontology_mode) {
gene_chain <- strsplit(gene_list, "\n")
# -> genes_list : list of the genes from the text area, ontology_mode : the chosen ontology (BP, MF ou CC)
FindOntologyCompare <- function(genes_list, ontology_mode) {
gene_chain <- strsplit(genes_list, "\n")
genes <- bitr(gene_chain[[1]],
fromType = "SYMBOL",
toType = "ENTREZID",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment