├── ClusterProfShinyORA.Rproj
├── README.md
├── intro.Rmd
├── server-enrichGo.R
├── server-inputData.R
├── server-plots.R
├── server.R
├── ui-tab-enrichGo.R
├── ui-tab-enrichKegg.R
├── ui-tab-goplots.R
├── ui-tab-inputdata.R
├── ui-tab-intro.R
├── ui-tab-keggplots.R
├── ui-tab-pathview.R
├── ui-tab-wordcloud.R
├── ui.R
└── www
├── barplot.png
├── cnetplot.png
├── custom.css
├── custom.js
├── dotplot.png
├── exampleData
├── SRX003935_vs_SRX003924.csv
└── drosphila_example_de.csv
├── goplot.png
├── imgModal.js
├── pathview.png
├── plotsAll.jpg
├── sampleTable.png
├── seuratWorkflow.png
└── wordcloud.png
/ClusterProfShinyORA.Rproj:
--------------------------------------------------------------------------------
1 | Version: 1.0
2 |
3 | RestoreWorkspace: Default
4 | SaveWorkspace: Default
5 | AlwaysSaveHistory: Default
6 |
7 | EnableCodeIndexing: Yes
8 | UseSpacesForTab: Yes
9 | NumSpacesForTab: 2
10 | Encoding: UTF-8
11 |
12 | RnwWeave: Sweave
13 | LaTeX: pdfLaTeX
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ClusterProfShinyORA
2 | - clusterProfiler Over-representation analysis R shiny
3 | - This is part of the NASQAR toolbox
4 | - Pre-print: [NASQAR: A web-based platform for High-throughput sequencing data analysis and visualization](https://doi.org/10.1101/709980)
5 |
6 | ---
7 |
8 | This is a web-based interactive application that wraps the popular clusterProfiler package which implements methods to analyze and visualize functional profiles of genomic coordinates, gene and gene clusters.
9 |
10 | Users can upload their own differential gene expression (DGE) data from DESeq2 or import data from the upstream Deseq2Shiny app.
11 |
12 | This app allows for quick and easy **Over-representation analysis (ORA)** of GO-Terms and KEGG pathways.
13 |
14 | It is meant to provide an intuitive interface for researchers to easily **upload, analyze, visualize, and explore single-cell RNA-seq data** interactively with no prior programming knowledge in R.
15 |
16 | Visuals produced include dot plots, wordclouds, category net plots, enrichment map plots, GO induced graphs, gsea plots, and enriched KEGG pathway plots using the Pathview package.
17 |
18 | The application follows this tutorial
19 |
20 | See below for example output plots.
21 |
22 |
23 |
24 |
25 |
A .csv/.txt file that contains a table of differential gene expression (DGE) data
Eg. the output of DESeq2
The file can be either comma or tab delimited
The required columns are Gene name/id, Log2 Fold Change, p-adjusted values
You will have to select the column names that match the above required columns
For a sample file, click here
Figure 2: Eg. DGE data file
57 |Figure 1: Example plots
29 |A .csv/.txt file that contains a table of differential gene expression (DGE) data
Eg. the output of DESeq2
The file can be either comma or tab delimited
The required columns are Gene name/id, Log2 Fold Change, p-adjusted values
You will have to select the column names that match the above required columns
For a sample file, click here
Figure 2: Eg. DGE data file
139 |",outputText,"
") 254 | }) 255 | 256 | observeEvent(input$gotoGoPlots, { 257 | GotoTab('goplotsTab') 258 | }) 259 | 260 | observeEvent(input$gotoKeggPlots, { 261 | GotoTab('keggPlotsTab') 262 | }) 263 | 264 | observeEvent(input$gotoPathview, { 265 | GotoTab('pathviewTab') 266 | }) 267 | 268 | observeEvent(input$gotoWordcloud, { 269 | GotoTab('wordcloudTab') 270 | }) 271 | 272 | observeEvent(input$gotoWordcloud1, { 273 | GotoTab('wordcloudTab') 274 | }) -------------------------------------------------------------------------------- /server-inputData.R: -------------------------------------------------------------------------------- 1 | 2 | observe({ 3 | 4 | shinyjs::hide(selector = "a[data-value=\"enrichGoTab\"]") 5 | shinyjs::hide(selector = "a[data-value=\"enrichKeggTab\"]") 6 | shinyjs::hide(selector = "a[data-value=\"goplotsTab\"]") 7 | shinyjs::hide(selector = "a[data-value=\"keggPlotsTab\"]") 8 | shinyjs::hide(selector = "a[data-value=\"pathviewTab\"]") 9 | shinyjs::hide(selector = "a[data-value=\"wordcloudTab\"]") 10 | 11 | inputDataReactive() 12 | 13 | 14 | }) 15 | 16 | inputDataReactive <- reactive({ 17 | 18 | print("inputting data") 19 | 20 | query <- parseQueryString(session$clientData$url_search) 21 | 22 | # Check if example selected, or if not then ask to upload a file. 23 | shiny:: validate( 24 | need( identical(input$data_file_type,"examplecounts")|(!is.null(input$datafile)), 25 | message = "Please select a file") 26 | ) 27 | 28 | if (!is.null(query[['countsdata']]) ) { 29 | inFile = decryptUrlParam(query[['countsdata']]) 30 | 31 | shinyjs::show(selector = "a[data-value=\"datainput\"]") 32 | shinyjs::disable("data_file_type") 33 | shinyjs::disable("datafile") 34 | #js$collapse("uploadbox") 35 | 36 | } 37 | else 38 | { 39 | inFile <- input$datafile 40 | # if (is.null(inFile)) 41 | # return(NULL) 42 | # 43 | # inFile = inFile$datapath 44 | } 45 | 46 | #inFile <- input$datafile 47 | js$addStatusIcon("datainput","loading") 48 | 49 | if (!is.null(inFile)) { 50 | seqdata <- read.csv(inFile$datapath, header=TRUE, sep=",") 51 | print('uploaded seqdata') 52 | if(ncol(seqdata)==1) { # if file appears not to work as csv try tsv 53 | seqdata <- read.tsv(inFile$datapath, header=TRUE) 54 | print('changed to tsv, uploaded seqdata') 55 | } 56 | shiny::validate(need(ncol(seqdata)>1, 57 | message="File appears to be one column. Check that it is a comma or tab delimited (.csv) file.")) 58 | 59 | js$addStatusIcon("datainput","done") 60 | js$collapse("uploadbox") 61 | 62 | return(list('data'=seqdata)) 63 | } 64 | else{ 65 | if(input$data_file_type=="examplecounts") 66 | { 67 | js$addStatusIcon("datainput","loading") 68 | #pbmc.data <- Read10X(data.dir = "www/hg19/") 69 | 70 | #data = read.csv("www/exampleData/SRX003935_vs_SRX003924.csv") 71 | 72 | data = read.csv("www/exampleData/drosphila_example_de.csv") 73 | 74 | 75 | 76 | js$addStatusIcon("datainput","done") 77 | js$collapse("uploadbox") 78 | return(list('data'=data)) 79 | } 80 | return(NULL) 81 | } 82 | }) 83 | 84 | 85 | output$countdataDT <- renderDataTable({ 86 | tmp <- inputDataReactive() 87 | 88 | if(!is.null(tmp)) 89 | { 90 | tmp$data 91 | } 92 | 93 | }, 94 | options = list(scrollX = TRUE)) 95 | 96 | # check if a file has been uploaded and create output variable to report this 97 | output$fileUploaded <- reactive({ 98 | 99 | 100 | if(!is.null(inputDataReactive())) 101 | { 102 | updateSelectInput(session, "geneColumn", choices = names(inputDataReactive()$data)) 103 | updateSelectInput(session, "log2fcColumn", choices = names(inputDataReactive()$data)) 104 | updateSelectInput(session, "padjColumn", choices = names(inputDataReactive()$data)) 105 | 106 | if(input$data_file_type=="examplecounts") 107 | { 108 | updateSelectInput(session, "geneColumn", selected = "X") 109 | updateSelectInput(session, "log2fcColumn", selected = "log2FoldChange") 110 | updateSelectInput(session, "padjColumn", selected = "padj") 111 | } 112 | 113 | return(T) 114 | } 115 | 116 | return(F) 117 | 118 | }) 119 | outputOptions(output, 'fileUploaded', suspendWhenHidden=FALSE) 120 | 121 | 122 | observeEvent(input$nextInitParams,{ 123 | 124 | js$collapse("iParamsbox") 125 | 126 | organismsDbChoices = c("Human (org.Hs.eg.db)"="org.Hs.eg.db","Mouse (org.Mm.eg.db)"="org.Mm.eg.db","Rat (org.Rn.eg.db)"="org.Rn.eg.db", 127 | "Yeast (org.Sc.sgd.db)"="org.Sc.sgd.db","Fly (org.Dm.eg.db)"="org.Dm.eg.db","Arabidopsis (org.At.tair.db)"="org.At.tair.db", 128 | "Zebrafish (org.Dr.eg.db)"="org.Dr.eg.db","Bovine (org.Bt.eg.db)"="org.Bt.eg.db","Worm (org.Ce.eg.db)"="org.Ce.eg.db", 129 | "Chicken (org.Gg.eg.db)"="org.Gg.eg.db","Canine (org.Cf.eg.db)"="org.Cf.eg.db","Pig (org.Ss.eg.db)"="org.Ss.eg.db", 130 | "Rhesus (org.Mmu.eg.db)"="org.Mmu.eg.db","E coli strain K12 (org.EcK12.eg.db)"="org.EcK12.eg.db","Xenopus (org.Xl.eg.db)"="org.Xl.eg.db", 131 | "Chimp (org.Pt.eg.db)"="org.Pt.eg.db","Anopheles (org.Ag.eg.db)"="org.Ag.eg.db","Malaria (org.Pf.plasmo.db)"="org.Pf.plasmo.db", 132 | "E coli strain Sakai (org.EcSakai.eg.db)"="org.EcSakai.eg.db") 133 | 134 | updateSelectInput(session, "organismDb", choices = organismsDbChoices) 135 | 136 | if(input$data_file_type=="examplecounts") 137 | updateSelectInput(session, "organismDb", selected = "org.Dm.eg.db") 138 | 139 | 140 | js$collapse("createGoBox") 141 | 142 | }) 143 | 144 | 145 | observeEvent(input$organismDb,{ 146 | if(input$organismDb == "") 147 | return(NULL) 148 | 149 | library(input$organismDb, character.only = T) 150 | 151 | annDb = eval(parse(text = input$organismDb)) 152 | keytypes = keytypes(annDb) 153 | updateSelectInput(session, "keytype", choices = keytypes, selected = "ENSEMBL") 154 | 155 | }) 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /server-plots.R: -------------------------------------------------------------------------------- 1 | output$upsetPlot = renderPlot({ 2 | withProgress(message = "Plotting upsetplot ...",{ 3 | go_enrich = enrichGoReactive()$go_enrich 4 | 5 | upsetplot(go_enrich, 6 | n = input$showCategory_upset) 7 | }) 8 | 9 | }) 10 | 11 | output$barPlot = renderPlot({ 12 | withProgress(message = "Plotting barplot ...",{ 13 | go_enrich = enrichGoReactive()$go_enrich 14 | 15 | barplot(go_enrich, 16 | drop = TRUE, 17 | showCategory = input$showCategory_bar, 18 | title = "GO Biological Pathways", 19 | font.size = 8) 20 | }) 21 | 22 | }) 23 | 24 | 25 | output$dotPlot = renderPlot({ 26 | withProgress(message = "Plotting dotplot ...",{ 27 | go_enrich = enrichGoReactive()$go_enrich 28 | 29 | dotplot(go_enrich, 30 | #drop = TRUE, 31 | showCategory = input$showCategory_dot, 32 | #title = "GO Biological Pathways", 33 | font.size = 8) 34 | }) 35 | 36 | }) 37 | 38 | output$enrichPlotMap = renderPlot({ 39 | withProgress(message = "Plotting enrichment map ...",{ 40 | go_enrich = enrichGoReactive()$go_enrich 41 | 42 | emapplot(go_enrich, showCategory = input$showCategory_enrichmap) 43 | }) 44 | 45 | }) 46 | 47 | 48 | output$goInducedGraph = renderPlot({ 49 | withProgress(message = "Plotting induced GO DAG ...",{ 50 | 51 | go_enrich = enrichGoReactive()$go_enrich 52 | 53 | goplot(go_enrich, showCategory = input$showCategory_goplot) 54 | 55 | }) 56 | 57 | }) 58 | 59 | 60 | output$cnetplot = renderPlot({ 61 | 62 | withProgress(message = "Plotting Gene-Concept Network ...",{ 63 | go_enrich = enrichGoReactive()$go_enrich 64 | 65 | cnetplot(go_enrich, categorySize="pvalue", foldChange=myValues$gene_list, showCategory = input$showCategory_cnet) 66 | }) 67 | 68 | }) 69 | 70 | output$wordcloud = renderWordcloud2({ 71 | withProgress(message = "Plotting Wordcloud ...",{ 72 | 73 | if(input$plotWordcloud) 74 | { 75 | isolate({ 76 | if(input$wordcloudGoOrKegg == "enrichGo") 77 | { 78 | go_enrich = enrichGoReactive()$go_enrich 79 | } 80 | else 81 | { 82 | go_enrich = enrichGoReactive()$kegg_enrich 83 | } 84 | 85 | wcdf<-read.table(text=go_enrich$GeneRatio, sep = "/")[1] 86 | wcdf$term<-go_enrich[,2] 87 | # wc = wordcloud(words = wcdf$term, freq = wcdf$V1, scale=(c(2, .5)), colors=brewer.pal(8, "Dark2"), max.words = input$maxWords) 88 | 89 | wordsDF = data.frame(word=go_enrich[,2], freq=wcdf$V1) 90 | 91 | wordsDF = wordsDF[order(-wordsDF$freq),] 92 | 93 | wordsDF = head(wordsDF, input$maxWords) 94 | 95 | wordcloud2(wordsDF, color = input$wordsColor, shape = input$wordShape, size = 0.1) 96 | }) 97 | 98 | } 99 | 100 | 101 | }) 102 | 103 | }) 104 | 105 | 106 | ### KEGG 107 | 108 | output$barPlot_kegg = renderPlot({ 109 | withProgress(message = "Plotting barplot ...",{ 110 | kegg_enrich = enrichGoReactive()$kegg_enrich 111 | 112 | barplot(kegg_enrich, 113 | drop = TRUE, 114 | showCategory = input$showCategory_bar_kegg, 115 | title = "Enriched Pathways", 116 | font.size = 8) 117 | }) 118 | 119 | }) 120 | 121 | 122 | output$dotPlot_kegg = renderPlot({ 123 | withProgress(message = "Plotting dotplot ...",{ 124 | kegg_enrich = enrichGoReactive()$kegg_enrich 125 | 126 | dotplot(kegg_enrich, 127 | #drop = TRUE, 128 | showCategory = input$showCategory_dot_kegg, 129 | title = "Enriched Pathways", 130 | font.size = 8) 131 | }) 132 | 133 | }) 134 | 135 | output$enrichPlotMap_kegg = renderPlot({ 136 | withProgress(message = "Plotting Enrichment Map ...",{ 137 | kegg_enrich = enrichGoReactive()$kegg_enrich 138 | 139 | emapplot(kegg_enrich, showCategory = input$showCategory_enrichmap_kegg) 140 | 141 | }) 142 | 143 | }) 144 | 145 | 146 | output$cnetplot_kegg = renderPlot({ 147 | 148 | withProgress(message = "Plotting Gene-Concept Network ...",{ 149 | kegg_enrich = enrichGoReactive()$kegg_enrich 150 | 151 | cnetplot(kegg_enrich, categorySize="pvalue", foldChange=myValues$kegg_gene_list, showCategory = input$showCategory_cnet_kegg) 152 | }) 153 | 154 | }) 155 | 156 | 157 | pathviewReactive = eventReactive(input$generatePathview,{ 158 | withProgress(message = 'Plotting Pathview ...', { 159 | 160 | isolate({ 161 | kegg_enrich = enrichGoReactive()$kegg_enrich 162 | 163 | setProgress(value = 0.3, detail = paste0("Pathview ID ",input$pathwayIds," ...")) 164 | dme <- pathview(gene.data=myValues$gene_list, pathway.id=input$pathwayIds, species = myValues$organismKegg, gene.idtype=input$geneid_type) 165 | file.copy(paste0(input$pathwayIds,".pathview.png"),paste0("testimage")) 166 | 167 | setProgress(value = 0.7, detail = paste0("Pathview ID ",input$pathwayIds," generating pdf ...")) 168 | dmePdf <- pathview(gene.data=myValues$gene_list, pathway.id=input$pathwayIds, species = myValues$organismKegg, gene.idtype=input$geneid_type,kegg.native = F) 169 | 170 | myValues$imagePath = paste0(input$pathwayIds,".pathview.") 171 | return(list( 172 | src = paste0("testimage"), 173 | filetype = "image/png", 174 | alt = "pathview image" 175 | )) 176 | }) 177 | 178 | }) 179 | }) 180 | 181 | output$pathview_plot = renderImage({ 182 | 183 | return(pathviewReactive()) 184 | 185 | }) 186 | 187 | output$pathviewPlotsAvailable <- 188 | reactive({ 189 | return(!is.null(pathviewReactive())) 190 | }) 191 | outputOptions(output, 'pathviewPlotsAvailable', suspendWhenHidden=FALSE) 192 | 193 | output$downloadPathviewPng <- downloadHandler( 194 | filename = function() {paste0(myValues$imagePath,"png")}, 195 | content = function(file) { 196 | file.copy(paste0(getwd(),'/',myValues$imagePath,"png"), file) 197 | } 198 | ) 199 | 200 | output$downloadPathviewPdf <- downloadHandler( 201 | filename = function() {paste0(myValues$imagePath,"pdf")}, 202 | content = function(file) { 203 | file.copy(paste0(getwd(),'/',myValues$imagePath,"pdf"), file) 204 | } 205 | ) 206 | 207 | output$wordcloud_kegg = renderWordcloud2({ 208 | withProgress(message = "Plotting Wordcloud ...",{ 209 | kegg_enrich = enrichGoReactive()$kegg_enrich 210 | 211 | wcdf<-read.table(text=kegg_enrich$GeneRatio, sep = "/")[1] 212 | wcdf$term<-kegg_enrich[,2] 213 | # wc = wordcloud(words = wcdf$term, freq = wcdf$V1, scale=(c(2, .5)), colors=brewer.pal(8, "Dark2"), max.words = input$maxWords) 214 | 215 | wordsDF = data.frame(word=kegg_enrich[,2], freq=wcdf$V1) 216 | 217 | wordsDF = wordsDF[order(-wordsDF$freq),] 218 | 219 | wordsDF = head(wordsDF, input$maxWords_kegg) 220 | #browser() 221 | wordcloud2(wordsDF, color = input$wordsColor_kegg, shape = input$wordShape_kegg, size = 0.1) 222 | }) 223 | 224 | }) 225 | -------------------------------------------------------------------------------- /server.R: -------------------------------------------------------------------------------- 1 | 2 | # Max upload size 3 | options(shiny.maxRequestSize = 60*1024^2) 4 | 5 | # Define server 6 | server <- function(input, output, session) { 7 | 8 | source("server-inputData.R",local = TRUE) 9 | # 10 | source("server-enrichGo.R",local = TRUE) 11 | # 12 | source("server-plots.R",local = TRUE) 13 | 14 | 15 | GotoTab <- function(name){ 16 | #updateTabItems(session, "tabs", name) 17 | 18 | shinyjs::show(selector = paste0("a[data-value=\"",name,"\"]")) 19 | 20 | shinyjs::runjs("window.scrollTo(0, 0)") 21 | } 22 | } -------------------------------------------------------------------------------- /ui-tab-enrichGo.R: -------------------------------------------------------------------------------- 1 | tabItem(tabName = "enrichGoTab", 2 | 3 | conditionalPanel("output.enrichGoAvailable", 4 | 5 | column(2, 6 | h3(strong("enrichGo Results")), 7 | hr(), 8 | checkboxInput("showGeneidGo","Show geneID column", value = F), 9 | downloadButton('downloadEnrichGoCSV','Save Results as CSV File', class = "btn btn-info", style="margin: 7px;"), 10 | actionButton("gotoGoPlots","enrichGo Plots",class = "btn btn-warning",icon = icon("chart-area"), style="margin: 7px;"), 11 | actionButton("gotoWordcloud","Word Cloud",class = "btn btn-warning",icon = icon("chart-area"), style="margin: 7px;") 12 | ), 13 | column(10, 14 | tags$div(class = "BoxArea2", 15 | withSpinner(dataTableOutput('enrichGoTable')) 16 | ), 17 | tags$div(class = "clearBoth") 18 | ), 19 | tags$div(class = "clearBoth") 20 | 21 | ) 22 | ) -------------------------------------------------------------------------------- /ui-tab-enrichKegg.R: -------------------------------------------------------------------------------- 1 | tabItem(tabName = "enrichKeggTab", 2 | 3 | conditionalPanel("output.enrichKEGGAvailable", 4 | 5 | column(2, 6 | h3(strong("enrichKEGG Results")), 7 | hr(), 8 | checkboxInput("showGeneidKegg","Show geneID column", value = F), 9 | downloadButton('downloadEnrichKEGGCSV','Save Results as CSV File', class = "btn btn-info", style="margin: 7px;"), 10 | actionButton("gotoKeggPlots","enrichKEGG Plots",class = "btn btn-warning",icon = icon("chart-area"), style="margin: 7px;"), 11 | actionButton("gotoPathview","Generate Pathview Plot",class = "btn btn-warning",icon = icon("chart-area"), style="margin: 7px;"), 12 | actionButton("gotoWordcloud1","Word Cloud",class = "btn btn-warning",icon = icon("chart-area"), style="margin: 7px;"), 13 | 14 | wellPanel(h4(strong("Output warning:"), tags$a(href = "#", bubbletooltip = "Description ...",icon("info-circle"))), 15 | htmlOutput("warningText"), style = "background-color: #f9d8d3;") 16 | 17 | ), 18 | column(10, 19 | tags$div(class = "BoxArea2", 20 | withSpinner(dataTableOutput('enrichKEGGTable')) 21 | ), 22 | tags$div(class = "clearBoth") 23 | ), 24 | tags$div(class = "clearBoth") 25 | 26 | ) 27 | ) -------------------------------------------------------------------------------- /ui-tab-goplots.R: -------------------------------------------------------------------------------- 1 | tabItem(tabName = "goplotsTab", 2 | h2(strong("GO Plots")), 3 | tags$div( 4 | box(title = "Upset Plot", solidHeader = T, status = "danger", width = 12, collapsible = T,id = "barplot", 5 | fluidRow( 6 | column(3, 7 | wellPanel( 8 | numericInput("showCategory_upset", "number of categories to show", value = 10) 9 | ) 10 | ), 11 | column(9, 12 | wellPanel( 13 | withSpinner(plotOutput(outputId = "upsetPlot"),type = 8) 14 | ) 15 | ) 16 | ) 17 | ), 18 | box(title = "Bar Plot", solidHeader = T, status = "danger", width = 12, collapsible = T,id = "barplot", 19 | fluidRow( 20 | column(3, 21 | wellPanel( 22 | numericInput("showCategory_bar", "number of categories to show", value = 10) 23 | ) 24 | ), 25 | column(9, 26 | wellPanel( 27 | withSpinner(plotOutput(outputId = "barPlot"),type = 8) 28 | ) 29 | ) 30 | ) 31 | ), 32 | box(title = "Dot Plot", solidHeader = T, status = "danger", width = 12, collapsible = T,id = "dotplot", 33 | fluidRow( 34 | column(3, 35 | wellPanel( 36 | numericInput("showCategory_dot", "number of categories to show", value = 10) 37 | ) 38 | ), 39 | column(9, 40 | wellPanel( 41 | withSpinner(plotOutput(outputId = "dotPlot"),type = 8) 42 | ) 43 | 44 | ) 45 | ) 46 | ), 47 | box(title = "Encrichment plot map", solidHeader = T, status = "danger", width = 12, collapsible = T,id = "enrichPlotMap", 48 | fluidRow( 49 | column(3, 50 | wellPanel( 51 | numericInput("showCategory_enrichmap", "number of categories to show", value = 5) 52 | ) 53 | ) 54 | , 55 | column(9, 56 | wellPanel( 57 | plotOutput(outputId = "enrichPlotMap") 58 | ) 59 | ) 60 | ) 61 | ), 62 | box(title = "Category Netplot", solidHeader = T, status = "danger", width = 12, collapsible = T,id = "goInducedGraph", 63 | fluidRow( 64 | column(12, 65 | wellPanel( 66 | numericInput("showCategory_goplot", "number of categories to show", value = 5) 67 | ) 68 | ) 69 | , 70 | column(12, 71 | wellPanel( 72 | plotOutput(outputId = "goInducedGraph") 73 | ) 74 | ) 75 | ) 76 | ), 77 | box(title = "Enriched GO induced graph (cnetplot)", solidHeader = T, status = "danger", width = 12, collapsible = T,id = "cnetplot", 78 | fluidRow( 79 | column(12, 80 | wellPanel( 81 | numericInput("showCategory_cnet", "number of categories to show", value = 5) 82 | ) 83 | ), 84 | column(12, 85 | wellPanel( 86 | plotOutput(outputId = "cnetplot",width = "100%", height = "400px") 87 | ) 88 | ) 89 | ) 90 | ) 91 | 92 | , style = "display:table;") 93 | ) -------------------------------------------------------------------------------- /ui-tab-inputdata.R: -------------------------------------------------------------------------------- 1 | tabItem(tabName = "datainput", 2 | hr(), 3 | fluidRow(column(6, 4 | box(title = "Upload Data", solidHeader = T, status = "success", width = 12, collapsible = T,id = "uploadbox", 5 | 6 | #downloadLink("instructionspdf",label="Download Instructions (pdf)"), 7 | radioButtons('data_file_type','Use example file or upload your own data', 8 | c( 9 | 'Upload .CSV'="csvfile", 10 | 'Example Data'="examplecounts" 11 | ),selected = "csvfile"), 12 | 13 | conditionalPanel(condition="input.data_file_type=='csvfile'", 14 | p("CSV counts file") 15 | 16 | ), 17 | conditionalPanel(condition = "input.data_file_type=='csvfile'", 18 | fileInput('datafile', 'Choose File(s) Containing Data', multiple = TRUE) 19 | ) 20 | 21 | ), 22 | conditionalPanel("output.fileUploaded", 23 | box(title = "Initialize Parameters", solidHeader = T, status = "primary", width = 12, collapsible = T,id = "iParamsbox", 24 | 25 | wellPanel( 26 | column( 27 | 4, 28 | selectInput("geneColumn","Select Genes column:", choices = c("sdfs","dfs")) 29 | ), 30 | column(4, 31 | selectInput("log2fcColumn","Select Log2FC column:", choices = c("sdfs","dfs")) 32 | ), 33 | column(4, 34 | selectInput("padjColumn","Select padj column:", choices = c("sdfs","dfs")) 35 | ), 36 | column(6, 37 | numericInput("padjCutoff","padj cutoff:", value = 0.05) 38 | ), 39 | column(6, 40 | numericInput("logfcCuttoff","min log2 fold change :", value = 2) 41 | ), 42 | tags$div(class = "clearBoth") 43 | ), 44 | actionButton("nextInitParams","Next", class = "btn-info", style = "width: 100%") 45 | 46 | ), 47 | 48 | 49 | box(title = "EnrichGO object Parameters", solidHeader = T, status = "primary", width = 12, collapsible = T,id = "createGoBox", collapsed = T, 50 | wellPanel( 51 | column(6, 52 | selectInput("organismDb","Organism:", choices = NULL, selected = NULL) 53 | ), 54 | column(6, 55 | selectInput("keytype","Keytype:", choices = c(""), selected = NULL) 56 | ), 57 | column(6, 58 | selectInput("ontology","Ontology:", choices = c("MF", "BP", "CC"), selected = "BP") 59 | ), 60 | column(4, 61 | numericInput("minGSSize","minGSSize:", value = 5) 62 | ), 63 | column(4, 64 | numericInput("maxGSSize","maxGSSize:", value = 500) 65 | ), 66 | column(6, 67 | numericInput("pvalCuttoff","P-Value Cutoff:", value = 0.05) 68 | ), 69 | column(6, 70 | numericInput("qvalCuttoff","Q-Value Cutoff:", value = 0.1) 71 | ), 72 | column(6, 73 | selectInput("pAdjustMethod","pAdjustMethod:", choices = c("holm", "hochberg", "hommel", "bonferroni", "BH", "BY", "fdr", "none"), selected = "none") 74 | ), 75 | tags$div(class = "clearBoth") 76 | ), 77 | actionButton("initGo","Create EnrichGO Object", class = "btn-info", style = "width: 100%") 78 | ) 79 | ) 80 | ),#column 81 | column(6, 82 | bsCollapse(id="input_collapse_panel",open="data_panel",multiple = FALSE, 83 | bsCollapsePanel(title="Data Contents Table:",value="data_panel", 84 | p("Note: if there are more than 20 columns, only the first 20 will show here"), 85 | textOutput("inputInfo"), 86 | withSpinner(dataTableOutput('countdataDT')) 87 | ) 88 | )#bscollapse 89 | )#column 90 | )#fluidrow 91 | )#tabpanel 92 | -------------------------------------------------------------------------------- /ui-tab-intro.R: -------------------------------------------------------------------------------- 1 | tabItem(tabName = "introTab", 2 | fluidRow( 3 | 4 | box(title = "User Guide", width = 11, solidHeader = T, status = "primary", 5 | column(12, 6 | includeMarkdown("intro.Rmd") 7 | ) 8 | ) 9 | ) 10 | ) 11 | -------------------------------------------------------------------------------- /ui-tab-keggplots.R: -------------------------------------------------------------------------------- 1 | tabItem(tabName = "keggPlotsTab", 2 | h2(strong("KEGG Plots")), 3 | tags$div( 4 | box(title = "Bar Plot", solidHeader = T, status = "danger", width = 12, collapsible = T,id = "barplot", 5 | fluidRow( 6 | column(3, 7 | wellPanel( 8 | numericInput("showCategory_bar_kegg", "number of categories to show", value = 10) 9 | ) 10 | ), 11 | column(9, 12 | wellPanel( 13 | withSpinner(plotOutput(outputId = "barPlot_kegg"),type = 8) 14 | ) 15 | ) 16 | ) 17 | ), 18 | box(title = "Dot Plot", solidHeader = T, status = "danger", width = 12, collapsible = T,id = "dotplot", 19 | fluidRow( 20 | column(3, 21 | wellPanel( 22 | numericInput("showCategory_dot_kegg", "number of categories to show", value = 10) 23 | ) 24 | ), 25 | column(9, 26 | wellPanel( 27 | withSpinner(plotOutput(outputId = "dotPlot_kegg"),type = 8) 28 | ) 29 | ) 30 | ) 31 | ), 32 | box(title = "Encrichment plot map", solidHeader = T, status = "danger", width = 12, collapsible = T,id = "enrichPlotMap_kegg", 33 | fluidRow( 34 | column(3, 35 | wellPanel( 36 | numericInput("showCategory_enrichmap_kegg", "number of categories to show", value = 5) 37 | ) 38 | ) 39 | , 40 | column(9, 41 | wellPanel( 42 | plotOutput(outputId = "enrichPlotMap_kegg") 43 | ) 44 | ) 45 | ) 46 | ), 47 | box(title = "Category Netplot", solidHeader = T, status = "danger", width = 12, collapsible = T,id = "cnetplot", 48 | fluidRow( 49 | column(12, 50 | wellPanel( 51 | numericInput("showCategory_cnet_kegg", "number of categories to show", value = 5) 52 | ) 53 | ), 54 | column(12, 55 | wellPanel( 56 | plotOutput(outputId = "cnetplot_kegg",width = "100%", height = "400px") 57 | ) 58 | ) 59 | ) 60 | ) 61 | 62 | , style = "display:table;") 63 | ) -------------------------------------------------------------------------------- /ui-tab-pathview.R: -------------------------------------------------------------------------------- 1 | tabItem(tabName = "pathviewTab", 2 | h2(strong("Pathview Plot")), 3 | wellPanel( 4 | column(6, 5 | 6 | selectizeInput("pathwayIds", label="Select Pathway ID", 7 | choices=NULL, 8 | multiple=F, 9 | options = list( 10 | placeholder = 11 | 'Start typing pathway id' 12 | ) 13 | ) 14 | 15 | ) 16 | , 17 | column(6, 18 | selectInput("geneid_type","Gene ID type:", choices = c(""), selected = NULL) 19 | ), 20 | column(6, 21 | actionButton("generatePathview", "Generate Pathview", class = "btn btn-info") 22 | ), 23 | conditionalPanel("output.pathviewPlotsAvailable", 24 | column(3, 25 | downloadButton('downloadPathviewPng','Download .png', class = "btn btn-warning", style="margin: 7px;") 26 | ), 27 | column(3, 28 | downloadButton('downloadPathviewPdf','Download .pdf', class = "btn btn-warning", style="margin: 7px;") 29 | ) 30 | ) 31 | , 32 | tags$div(class = "clearBoth") 33 | 34 | ), 35 | withSpinner(imageOutput(outputId = "pathview_plot", inline = T),type = 8) 36 | 37 | 38 | ) -------------------------------------------------------------------------------- /ui-tab-wordcloud.R: -------------------------------------------------------------------------------- 1 | tabItem(tabName = "wordcloudTab", 2 | h2(strong("GO Plots")), 3 | box(title = "Word Cloud", solidHeader = T, status = "danger", width = 12, collapsible = T,id = "wordcloud", 4 | fluidRow( 5 | column(3, 6 | wellPanel( 7 | numericInput("maxWords", "Max. Words", value = 25), 8 | radioButtons("wordsColor","Color theme:", c("Light"="random-light", "Dark"="random-dark")), 9 | selectizeInput("wordShape","Shape:", c("circle","cardioid","diamond","triangle-forward","triangle","triangle","star")), 10 | radioButtons("wordcloudGoOrKegg","Type:", choices = c("enrichGo","enrichKEGG")), 11 | actionButton("plotWordcloud","Plot Word Cloud", class = "btn btn-info") 12 | ) 13 | ), 14 | column(9, 15 | wellPanel( 16 | wordcloud2Output(outputId = "wordcloud") 17 | ) 18 | 19 | ) 20 | ) 21 | ) 22 | # , 23 | 24 | # box(title = "Word Cloud", solidHeader = T, status = "danger", width = 12, collapsible = T,id = "wordcloud_kegg", 25 | # fluidRow( 26 | # column(3, 27 | # wellPanel( 28 | # numericInput("maxWords_kegg", "Max. Words", value = 25), 29 | # radioButtons("wordsColor_kegg","Color theme:", c("Light"="random-light", "Dark"="random-dark")), 30 | # selectizeInput("wordShape_kegg","Shape:", c("circle","cardioid","diamond","triangle-forward","triangle","triangle","star")) 31 | # ) 32 | # ), 33 | # column(9, 34 | # wellPanel( 35 | # wordcloud2Output(outputId = "wordcloud_kegg") 36 | # ) 37 | # 38 | # ) 39 | # ) 40 | # ) 41 | 42 | ) -------------------------------------------------------------------------------- /ui.R: -------------------------------------------------------------------------------- 1 | require(shinydashboard) 2 | require(shinyjs) 3 | require(shinyBS) 4 | require(shinycssloaders) 5 | require(DT) 6 | require(shiny) 7 | 8 | 9 | library(clusterProfiler) 10 | library(DOSE) 11 | library(GOplot) 12 | library(enrichplot) 13 | library(pathview) 14 | library(wordcloud2) 15 | 16 | # BiocInstaller::biocLite(c("org.Hs.eg.db","org.Mm.eg.db","org.Rn.eg.db","org.Sc.sgd.db","org.Dm.eg.db","org.At.tair.db","org.Dr.eg.db","org.Bt.eg.db","org.Ce.eg.db","org.Gg.eg.db","org.Cf.eg.db","org.Ss.eg.db","org.Mmu.eg.db","org.EcK12.eg.db","org.Xl.eg.db","org.Pt.eg.db","org.Ag.eg.db","org.Pf.plasmo.db","org.EcSakai.eg.db")) 17 | 18 | 19 | ui <- tagList( 20 | dashboardPage( 21 | skin = "purple", 22 | dashboardHeader(title = "ClusterProfShiny (ORA)"), 23 | dashboardSidebar( 24 | sidebarMenu( 25 | id = "tabs", 26 | menuItem("User Guide", tabName = "introTab", icon = icon("info-circle")), 27 | menuItem("Input Data", tabName = "datainput", icon = icon("upload")), 28 | menuItem("enrichGo", tabName = "enrichGoTab", icon = icon("th")), 29 | menuItem("enrichKegg", tabName = "enrichKeggTab", icon = icon("th")), 30 | menuItem("Go Plots", tabName = "goplotsTab", icon = icon("bar-chart")), 31 | menuItem("KEGG Plots", tabName = "keggPlotsTab", icon = icon("bar-chart")), 32 | menuItem("Pathview Plots", tabName = "pathviewTab", icon = icon("bar-chart")), 33 | menuItem("Word Clouds", tabName = "wordcloudTab", icon = icon("bar-chart")) 34 | ) 35 | ), 36 | dashboardBody( 37 | shinyjs::useShinyjs(), 38 | extendShinyjs(script = "www/custom.js"), 39 | tags$head( 40 | tags$style(HTML( 41 | " .shiny-output-error-validation {color: darkred; }" 42 | )), 43 | tags$style( 44 | type="text/css", 45 | "#pathview_plot img {max-width: 100%; width: 100%; height: auto}"), 46 | tags$link(rel = "stylesheet", type = "text/css", href = "custom.css") 47 | ), 48 | tabItems( 49 | source("ui-tab-intro.R", local = TRUE)$value, 50 | source("ui-tab-inputdata.R", local = TRUE)$value, 51 | source("ui-tab-enrichGo.R", local = TRUE)$value, 52 | source("ui-tab-enrichKegg.R", local = TRUE)$value, 53 | source("ui-tab-goplots.R", local = TRUE)$value, 54 | source("ui-tab-keggplots.R", local = TRUE)$value, 55 | source("ui-tab-pathview.R", local = TRUE)$value, 56 | source("ui-tab-wordcloud.R", local = TRUE)$value 57 | ) 58 | 59 | ) 60 | 61 | ), 62 | tags$footer( 63 | wellPanel( 64 | HTML( 65 | ' 66 |Core Bioinformatics, Center for Genomics and Systems Biology, NYU Abu Dhabi
67 |Github: https://github.com/nasqar/ClusterProfShiny/
68 |Maintained by: Ayman Yousif
69 |Using ClusterProfiler
70 |Acknowledgements:
71 |1) GuangchuangYu/clusterProfiler
72 |2) Mohammed Khalfan - Over Representation Analysis Tutorial
73 |Copyright (C) 2019, code licensed under GPLv3
' 74 | ) 75 | ), 76 | tags$script(src = "imgModal.js") 77 | ) 78 | ) -------------------------------------------------------------------------------- /www/barplot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasqar/ClusterProfShinyORA/756a9fc317fa36419d05601f72c9e62001fbbfa5/www/barplot.png -------------------------------------------------------------------------------- /www/cnetplot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nasqar/ClusterProfShinyORA/756a9fc317fa36419d05601f72c9e62001fbbfa5/www/cnetplot.png -------------------------------------------------------------------------------- /www/custom.css: -------------------------------------------------------------------------------- 1 | #loading-bar-spinner.spinner { 2 | left: 50%; 3 | margin-left: -20px; 4 | top: 50%; 5 | z-index: 19 !important; 6 | animation: loading-bar-spinner 1000ms linear infinite; 7 | float: right; 8 | } 9 | 10 | #loading-bar-spinner.spinner .spinner-icon { 11 | width: 20px; 12 | height: 20px; 13 | border: solid 4px transparent; 14 | border-top-color: #00C8B1 !important; 15 | border-left-color: #00C8B1 !important; 16 | border-radius: 50%; 17 | } 18 | 19 | @keyframes loading-bar-spinner { 20 | 0% { transform: rotate(0deg); transform: rotate(0deg); } 21 | 100% { transform: rotate(360deg); transform: rotate(360deg); } 22 | } 23 | 24 | 25 | 26 | hr { 27 | border-top: 1px solid #bbb8b8; 28 | } 29 | 30 | body { 31 | font-size: 16px; 32 | } 33 | 34 | 35 | .checkmark__circle { 36 | stroke-dasharray: 166; 37 | stroke-dashoffset: 166; 38 | stroke-width: 2; 39 | stroke-miterlimit: 10; 40 | stroke: #7ac142; 41 | fill: none; 42 | animation: stroke 0.6s cubic-bezier(0.65, 0, 0.45, 1) forwards; 43 | } 44 | 45 | .checkmark { 46 | width: 20px; 47 | height: 20px; 48 | border-radius: 50%; 49 | display: block; 50 | stroke-width: 6; 51 | stroke: #fff; 52 | stroke-miterlimit: 10; 53 | box-shadow: inset 0px 0px 0px #7ac142; 54 | animation: fill .4s ease-in-out .4s forwards, scale .3s ease-in-out .9s both; 55 | } 56 | 57 | .checkmark__check { 58 | transform-origin: 50% 50%; 59 | stroke-dasharray: 48; 60 | stroke-dashoffset: 48; 61 | animation: stroke 0.3s cubic-bezier(0.65, 0, 0.45, 1) 0.8s forwards; 62 | } 63 | 64 | @keyframes stroke { 65 | 100% { 66 | stroke-dashoffset: 0; 67 | } 68 | } 69 | @keyframes scale { 70 | 0%, 100% { 71 | transform: none; 72 | } 73 | 50% { 74 | transform: scale3d(1.1, 1.1, 1); 75 | } 76 | } 77 | @keyframes fill { 78 | 100% { 79 | box-shadow: inset 0px 0px 0px 30px #7ac142; 80 | } 81 | } 82 | 83 | 84 | 85 | 86 | /* Fix indent icon on side bar*/ 87 | .sidebar-menu>li .badge,.sidebar-menu>li .label { 88 | margin-right: 0; 89 | } 90 | 91 | 92 | 93 | 94 | .mybuttonclass{background-color:#CD0000;} .mybuttonclass{color: #fff;} .mybuttonclass{border-color: #9E0000;} 95 | 96 | .BoxArea2 { padding:19px; margin: 5px; border-radius:10px; background-color: #e8e6f5;} 97 | 98 | .BoxArea { padding:19px; margin: 5px; border: 3px solid; border-color:rgba(24, 188, 156, 1); border-radius:10px; background-color:#fdfdfd; opacity: 0.90;} 99 | 100 | .BoxArea4 { padding:14px; margin: 5px; border: 3px solid; border-color:rgb(214, 226, 232); border-radius:5px; background-color:white;} 101 | 102 | .clearBoth{ clear:both; } 103 | 104 | a > .highlight { background-color:#fdfdfd;} 105 | 106 | .modal-dialog { width: 50%;} 107 | 108 | .dangerColor { 109 | background-color: #f5705f!important; 110 | color:white; 111 | } 112 | 113 | .content-wrapper, .right-side { 114 | background-color: #f3faff !important 115 | } 116 | 117 | 118 | .well { 119 | word-wrap: break-word; 120 | } 121 | 122 | a[bubbletooltip]:link, a[bubbletooltip]:visited 123 | { 124 | text-decoration: none; 125 | position: relative; 126 | } 127 | 128 | a[bubbletooltip]:before 129 | { 130 | content: ""; 131 | position: absolute; 132 | border-top: 26px solid #292f45; 133 | border-left: 26px solid transparent; 134 | border-right: 26px solid transparent; 135 | visibility: hidden; 136 | top: -20px; 137 | left: -12px; 138 | } 139 | 140 | a[bubbletooltip]:after 141 | { 142 | position: absolute; 143 | content: attr(bubbletooltip); 144 | top: -35px; 145 | left: -26px; 146 | background: #292f45; 147 | color: #FFFFFF; 148 | padding: 5px 10px; 149 | -moz-border-radius: 6px; 150 | -webkit-border-radius:6px; 151 | -khtml-border-radius:6px; 152 | border-radius: 6px; 153 | white-space: nowrap; 154 | visibility: hidden; 155 | z-index:999; 156 | } 157 | 158 | a[bubbletooltip]:hover:before, a[bubbletooltip]:hover:after 159 | { 160 | visibility: visible; 161 | -moz-transition: visibility 0s linear .3s; 162 | } 163 | -------------------------------------------------------------------------------- /www/custom.js: -------------------------------------------------------------------------------- 1 | shinyjs.addStatusIcon = function(params) 2 | { 3 | var tabname = params[0]; 4 | var status = params[1]; 5 | 6 | var menuitem = $('.sidebar-menu > li > a[data-value="' + tabname +'"]'); 7 | 8 | menuitem.children('#loading-bar-spinner').remove(); 9 | menuitem.children('#checkmarkdone').remove(); 10 | menuitem.children('span.badge').remove(); 11 | 12 | 13 | switch(status) 14 | { 15 | case 'loading': 16 | $("button.btn").removeClass("button-3d"); 17 | $("button.btn").attr("disabled", "disabled"); 18 | 19 | $("a.btn").addClass("hidden"); 20 | menuitem.append('