| Title: | Interactive Exploration & Management of RNA-Seq Analyses |
|---|---|
| Description: | Highly interactive & modular shiny app to explore three facets of RNA-Seq analysis: differential expression (DE), functional enrichment and pattern analysis. Several visualizations are implemented to provide a wide-ranging view of data sets. For DE analysis, we provide PCA plot, MA plot, Upset plot & heatmaps, in addition to a highly customizable gene plot. Seven different visualizations are available for functional enrichment analysis, and we also support gene pattern analysis. Genes of interest can be tracked across all modules using the gene scratchpad. In addition, carnation provides an integrated platform to manage multiple projects and user access that can be run on a central server to share with collaborators. |
| Authors: | Apratim Mitra [aut, cre] (ORCID: <https://orcid.org/0000-0003-3279-0054>), Matthew Tyler Menold [ctb] (ORCID: <https://orcid.org/0009-0007-4728-2470>), Ryan Dale [fnd] (ORCID: <https://orcid.org/0000-0003-2664-3744>) |
| Maintainer: | Apratim Mitra <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 1.1.0 |
| Built: | 2026-06-02 08:41:12 UTC |
| Source: | https://github.com/bioc/carnation |
Add metadata to counts data frame
add_metadata(df, coldata, exclude.intgroups)add_metadata(df, coldata, exclude.intgroups)
df |
data.frame with gene counts |
coldata |
data.frame with metadata |
exclude.intgroups |
metadata columns to ignore |
counts data frame with added metadata
library(DESeq2) # make example DESeq data set dds <- makeExampleDESeqDataSet() # extract counts and metadata df <- assay(dds) coldata <- colData(dds) # get gene counts df counts_df <- get_gene_counts(dds, paste0('gene', seq_len(10))) # add metadata counts_df <- add_metadata(counts_df, coldata, exclude.intgroups=NULL)library(DESeq2) # make example DESeq data set dds <- makeExampleDESeqDataSet() # extract counts and metadata df <- assay(dds) coldata <- colData(dds) # get gene counts df counts_df <- get_gene_counts(dds, paste0('gene', seq_len(10))) # add metadata counts_df <- add_metadata(counts_df, coldata, exclude.intgroups=NULL)
This function adds a column denoting set number to a matrix generated for an upset plot with fromList.with.names()
add.set.column(df)add.set.column(df)
df |
binary matrix where row = genes & columns are gene sets, with 1 indicating that a gene is present is that gene set and vice-versa |
data.frame with added set column
# list of genes lst <- list(group1 = c(a = "gene1", b = "gene2", c = "gene3", d = "gene4"), group2 = c(c = "gene3", d = "gene4")) # binarized matrix with group membership df <- fromList.with.names(lst) # matrix with added set column ldf <- add.set.column(df)# list of genes lst <- list(group1 = c(a = "gene1", b = "gene2", c = "gene3", d = "gene4"), group2 = c(c = "gene3", d = "gene4")) # binarized matrix with group membership df <- fromList.with.names(lst) # matrix with added set column ldf <- add.set.column(df)
UI & module to generate alluvial plots.
alluvialUI(id, panel) alluvialServer(id, obj, res_obj, config)alluvialUI(id, panel) alluvialServer(id, obj, res_obj, config)
id |
Module id |
panel |
string, can be 'sidebar' or 'main' |
obj |
reactiveValues object containing GeneTonic object |
res_obj |
reactive, dataframe containing enrichment results |
config |
reactive list with config settings |
UI returns tagList with plot UI server invisibly returns NULL (used for side effects)
library(shiny) # get DESeqResults object data(res_dex, package='carnation') # get enrichResult object data(eres_dex, package='carnation') # convert to GeneTonic object gt <- GeneTonic::shake_enrichResult(eres_dex) obj <- reactive({ list(l_gs = gt$l_gs, anno_df = gt$anno_df, label = 'comp1') }) res_obj <- reactive({ res }) config <- reactiveVal(get_config()) # run simple shiny app with plot if(interactive()){ shinyApp( ui = fluidPage( sidebarPanel(alluvialUI('p', 'sidebar')), mainPanel(alluvialUI('p', 'main')) ), server = function(input, output, session){ alluvialServer('p', obj, res_obj, config) } ) }library(shiny) # get DESeqResults object data(res_dex, package='carnation') # get enrichResult object data(eres_dex, package='carnation') # convert to GeneTonic object gt <- GeneTonic::shake_enrichResult(eres_dex) obj <- reactive({ list(l_gs = gt$l_gs, anno_df = gt$anno_df, label = 'comp1') }) res_obj <- reactive({ res }) config <- reactiveVal(get_config()) # run simple shiny app with plot if(interactive()){ shinyApp( ui = fluidPage( sidebarPanel(alluvialUI('p', 'sidebar')), mainPanel(alluvialUI('p', 'main')) ), server = function(input, output, session){ alluvialServer('p', obj, res_obj, config) } ) }
This function takes a username and returns a list with two elements:
check_user_access(al, u, admin = "admin")check_user_access(al, u, admin = "admin")
al |
list with access settings; should have two elements - user_group & data_area |
u |
user name |
admin |
Admin user group |
user_group: one element vector data_area: vector of data areas
list of user groups and data areas
# save access details to file home <- Sys.getenv('HOME') # create carnation data area if it doesn't exist carnation_home <- file.path(home, 'carnation/data') if(!dir.exists(carnation_home)) dir.create(carnation_home) create_access_yaml(user = 'admin', user_group = 'admin', data_area = carnation_home) # get current user access details al <- read_access_yaml() lst <- check_user_access(al, u='admin')# save access details to file home <- Sys.getenv('HOME') # create carnation data area if it doesn't exist carnation_home <- file.path(home, 'carnation/data') if(!dir.exists(carnation_home)) dir.create(carnation_home) create_access_yaml(user = 'admin', user_group = 'admin', data_area = carnation_home) # get current user access details al <- read_access_yaml() lst <- check_user_access(al, u='admin')
UI & module to generate Cnetplots.
cnetPlotUI(id, panel) cnetPlotServer(id, obj, config)cnetPlotUI(id, panel) cnetPlotServer(id, obj, config)
id |
Module id |
panel |
string, can be 'sidebar' or 'main' |
obj |
reactive, dataframe containing enrichment results |
config |
reactive list with config settings |
UI returns tagList with plot UI server invisibly returns NULL (used for side effects)
library(shiny) # get DESeqResults object data(res_dex, package='carnation') obj <- reactive({ res }) config <- reactiveVal(get_config()) # run simple shiny app with plot if(interactive()){ shinyApp( ui = fluidPage( sidebarPanel(cnetPlotUI('p', 'sidebar')), mainPanel(cnetPlotUI('p', 'main')) ), server = function(input, output, session){ cnetPlotServer('p', obj, config) } ) }library(shiny) # get DESeqResults object data(res_dex, package='carnation') obj <- reactive({ res }) config <- reactiveVal(get_config()) # run simple shiny app with plot if(interactive()){ shinyApp( ui = fluidPage( sidebarPanel(cnetPlotUI('p', 'sidebar')), mainPanel(cnetPlotUI('p', 'main')) ), server = function(input, output, session){ cnetPlotServer('p', obj, config) } ) }
This function creates an access yaml file. This is primarily intended for the first run.
create_access_yaml(user, user_group, data_area)create_access_yaml(user, user_group, data_area)
user |
User name |
user_group |
User group |
data_area |
Path to data area containing RDS files |
Invisibly returns NULL. This function is primarily used for
its side effect of saving a yaml file with access settings
# save access details to file home <- Sys.getenv('HOME') # create carnation data area if it doesn't exist carnation_home <- file.path(home, 'carnation/data') if(!dir.exists(carnation_home)) dir.create(carnation_home) create_access_yaml(user = 'admin', user_group = 'admin', data_area = carnation_home)# save access details to file home <- Sys.getenv('HOME') # create carnation data area if it doesn't exist carnation_home <- file.path(home, 'carnation/data') if(!dir.exists(carnation_home)) dir.create(carnation_home) create_access_yaml(user = 'admin', user_group = 'admin', data_area = carnation_home)
Module UI & server to generate pattern plots.
patternPlotUI(id, panel, tab) patternPlotServer(id, obj, coldata, gene_scratchpad, upset_data, config)patternPlotUI(id, panel, tab) patternPlotServer(id, obj, coldata, gene_scratchpad, upset_data, config)
id |
Module id |
panel |
string, can be 'sidebar' or 'main' |
tab |
string, if 'plot' show plot settings, if 'table' show table settings; if 'both', show settings for both. |
obj |
reactiveValues object containing carnation object |
coldata |
reactiveValues object containing object metadata |
gene_scratchpad |
reactive containing genes selected in scratchpad |
upset_data |
reactive containing list with data from upset plot module |
config |
reactive list with config settings |
UI returns tagList with module UI server returns reactive with selected genes for scratchpad updates
library(shiny) library(DESeq2) # Create reactive values to simulate app state oobj <- make_example_carnation_object() obj <- reactiveValues( dds = oobj$dds, rld = oobj$rld, res = oobj$res, all_dds = oobj$all_dds, all_rld = oobj$all_rld, dds_mapping = oobj$dds_mapping ) cdata <- lapply(oobj$rld, function(x) colData(x)) coldata <- reactiveValues( all=cdata, curr=cdata ) gene_scratchpad <- reactive({ c('gene1', 'gene2') }) upset_data <- reactive({ list(genes=NULL, labels=NULL) }) config <- reactiveVal(get_config()) shinyApp( ui = fluidPage( sidebarPanel( patternPlotUI('p', 'sidebar', 'both'), conditionalPanel(condition = "input.pattern_mode == 'Plot'", patternPlotUI('p', 'sidebar', 'plot') ), conditionalPanel(condition = "input.pattern_mode == 'Table'", patternPlotUI('p', 'sidebar', 'table') ) ), mainPanel( tabsetPanel(id='pattern_mode', tabPanel('Plot', patternPlotUI('p', 'plot') ), # tabPanel plot tabPanel('Cluster membership', patternPlotUI('p', 'table') ) # tabPanel cluster_membership ) # tabsetPanel pattern_mode ) # tabPanel pattern_analysis ), server = function(input, output, session){ patternPlotServer('deg_plot', obj, coldata, gene_scratchpad, upset_data, config) } )library(shiny) library(DESeq2) # Create reactive values to simulate app state oobj <- make_example_carnation_object() obj <- reactiveValues( dds = oobj$dds, rld = oobj$rld, res = oobj$res, all_dds = oobj$all_dds, all_rld = oobj$all_rld, dds_mapping = oobj$dds_mapping ) cdata <- lapply(oobj$rld, function(x) colData(x)) coldata <- reactiveValues( all=cdata, curr=cdata ) gene_scratchpad <- reactive({ c('gene1', 'gene2') }) upset_data <- reactive({ list(genes=NULL, labels=NULL) }) config <- reactiveVal(get_config()) shinyApp( ui = fluidPage( sidebarPanel( patternPlotUI('p', 'sidebar', 'both'), conditionalPanel(condition = "input.pattern_mode == 'Plot'", patternPlotUI('p', 'sidebar', 'plot') ), conditionalPanel(condition = "input.pattern_mode == 'Table'", patternPlotUI('p', 'sidebar', 'table') ) ), mainPanel( tabsetPanel(id='pattern_mode', tabPanel('Plot', patternPlotUI('p', 'plot') ), # tabPanel plot tabPanel('Cluster membership', patternPlotUI('p', 'table') ) # tabPanel cluster_membership ) # tabsetPanel pattern_mode ) # tabPanel pattern_analysis ), server = function(input, output, session){ patternPlotServer('deg_plot', obj, coldata, gene_scratchpad, upset_data, config) } )
degPatterns object for differentially expressed genes in the
dexamethasone treatment comparison.A degPatterns object for differentially expressed genes in the
dexamethasone treatment comparison.
A degPatterns object, generated with the degPatterns function
from the DEGreport package.
This degPatterns object was created to test for groups of
coexpressed genes in the top 100 differentially expressed genes from the
dexamethasone treatment comparison.
Details on how this object has been created are included in the
create_carnation_data.R script, included in the scripts folder of the
Carnation package.
Himes BE, Jiang X, Wagner P, Hu R, Wang Q, Klanderman B, Whitaker RM, Duan Q, Lasky-Su J, Nikolos C, Jester W, Johnson M, Panettieri R Jr, Tantisira KG, Weiss ST, Lu Q. “RNA-Seq Transcriptome Profiling Identifies CRISPLD2 as a Glucocorticoid Responsive Gene that Modulates Cytokine Function in Airway Smooth Muscle Cells.” PLoS One. 2014 Jun 13;9(6):e99625. PMID: 24926665. GEO: GSE52778
UI & module to generate dendrograms.
dendrogramUI(id, panel) dendrogramServer(id, obj, config)dendrogramUI(id, panel) dendrogramServer(id, obj, config)
id |
Module id |
panel |
string, can be 'sidebar' or 'main' |
obj |
reactiveValues object containing GeneTonic object |
config |
reactive list with config settings |
UI returns tagList with plot UI server invisibly returns NULL (used for side effects)
library(shiny) # get enrichResult object data(eres_dex, package='carnation') # convert to GeneTonic object gt <- GeneTonic::shake_enrichResult(eres_dex) obj <- reactive({ list(l_gs = gt$l_gs, anno_df = gt$anno_df, label = 'comp1') }) config <- reactiveVal(get_config()) # run simple shiny app with plot if(interactive()){ shinyApp( ui = fluidPage( sidebarPanel(dendrogramUI('p', 'sidebar')), mainPanel(dendrogramUI('p', 'main')) ), server = function(input, output, session){ dendrogramServer('p', obj, config) } ) }library(shiny) # get enrichResult object data(eres_dex, package='carnation') # convert to GeneTonic object gt <- GeneTonic::shake_enrichResult(eres_dex) obj <- reactive({ list(l_gs = gt$l_gs, anno_df = gt$anno_df, label = 'comp1') }) config <- reactiveVal(get_config()) # run simple shiny app with plot if(interactive()){ shinyApp( ui = fluidPage( sidebarPanel(dendrogramUI('p', 'sidebar')), mainPanel(dendrogramUI('p', 'main')) ), server = function(input, output, session){ dendrogramServer('p', obj, config) } ) }
UI & module to generate distill enrichment map plots.
distillPlotUI(id, panel) distillPlotServer(id, obj, args, config)distillPlotUI(id, panel) distillPlotServer(id, obj, args, config)
id |
Module id |
panel |
string, can be 'sidebar' or 'main' |
obj |
reactive containing 'distilled' enrichment results |
args |
reactive, list with plot arguments, 'numcat' (number of categories to plot) |
config |
reactive list with config settings |
UI returns tagList with plot UI server returns reactive with number of plotted terms
library(GeneTonic) library(shiny) # get DESeqResults object data(res_dex, package='carnation') # get enrichResult object data(eres_dex, package='carnation') # preprocess & convert to GeneTonic object eres2 <- GeneTonic::shake_enrichResult(eres_dex) gt <- enrich_to_genetonic(eres_dex, res_dex) # get distilled results df <- distill_enrichment( eres2, res_dex, gt$anno_df, n_gs = 10, cluster_fun = "cluster_markov" ) # number of plotted terms args <- reactive({ list(numcat=10) }) config <- reactiveVal(get_config()) # run simple shiny app with plot if(interactive()){ shinyApp( ui = fluidPage( sidebarPanel(distillPlotUI('p', 'sidebar')), mainPanel(distillPlotUI('p', 'main')) ), server = function(input, output, session){ numcat <- observe({ distillPlotServer('p', reactive({ df }), args, config) }) } ) }library(GeneTonic) library(shiny) # get DESeqResults object data(res_dex, package='carnation') # get enrichResult object data(eres_dex, package='carnation') # preprocess & convert to GeneTonic object eres2 <- GeneTonic::shake_enrichResult(eres_dex) gt <- enrich_to_genetonic(eres_dex, res_dex) # get distilled results df <- distill_enrichment( eres2, res_dex, gt$anno_df, n_gs = 10, cluster_fun = "cluster_markov" ) # number of plotted terms args <- reactive({ list(numcat=10) }) config <- reactiveVal(get_config()) # run simple shiny app with plot if(interactive()){ shinyApp( ui = fluidPage( sidebarPanel(distillPlotUI('p', 'sidebar')), mainPanel(distillPlotUI('p', 'main')) ), server = function(input, output, session){ numcat <- observe({ distillPlotServer('p', reactive({ df }), args, config) }) } ) }
Module UI & server for download buttons.
downloadButtonUI(id) downloadButtonServer(id, outplot, plot_type)downloadButtonUI(id) downloadButtonServer(id, outplot, plot_type)
id |
Module id |
outplot |
reactive plot handle |
plot_type |
reactive/static value used for output filename |
UI returns tagList with download button UI. Server invisibly returns NULL (used for side effects).
library(shiny) library(ggplot2) # get example object obj <- make_example_carnation_object() res <- as.data.frame(obj$res[[1]]) # make MA plot p <- ggplot(res, aes(x=baseMean, y=log2foldChange)) + geom_point(color='black', alpha=0.5) outplot <- reactive({ p }) # app with a single button to download a plot if(interactive()){ shinyApp( ui = fluidPage( downloadButtonUI('p') ), server = function(input, output, session){ downloadButtonServer('p', outplot, 'maplot') } ) }library(shiny) library(ggplot2) # get example object obj <- make_example_carnation_object() res <- as.data.frame(obj$res[[1]]) # make MA plot p <- ggplot(res, aes(x=baseMean, y=log2foldChange)) + geom_point(color='black', alpha=0.5) outplot <- reactive({ p }) # app with a single button to download a plot if(interactive()){ shinyApp( ui = fluidPage( downloadButtonUI('p') ), server = function(input, output, session){ downloadButtonServer('p', outplot, 'maplot') } ) }
Make dummy GeneTonic object
dummy_genetonic(eres)dummy_genetonic(eres)
eres |
enrichResult object |
GeneTonic object
UI & module to generate enrichment map plots.
enrichmapUI(id, panel) enrichmapServer(id, obj, res_obj, config)enrichmapUI(id, panel) enrichmapServer(id, obj, res_obj, config)
id |
Module id |
panel |
string, can be 'sidebar' or 'main' |
obj |
reactiveValues object containing GeneTonic object |
res_obj |
reactive, dataframe containing enrichment results |
config |
reactive list with config settings |
UI returns tagList with plot UI server invisibly returns NULL (used for side effects)
library(shiny) # get DESeqResults object data(res_dex, package='carnation') # get enrichResult object data(eres_dex, package='carnation') # convert to GeneTonic object gt <- GeneTonic::shake_enrichResult(eres_dex) obj <- reactive({ list(l_gs = gt$l_gs, anno_df = gt$anno_df, label = 'comp1') }) res_obj <- reactive({ res }) config <- reactiveVal(get_config()) # run simple shiny app with plot if(interactive()){ shinyApp( ui = fluidPage( sidebarPanel(enrichmapUI('p', 'sidebar')), mainPanel(enrichmapUI('p', 'main')) ), server = function(input, output, session){ enrichmapServer('p', obj, res_obj, config) } ) }library(shiny) # get DESeqResults object data(res_dex, package='carnation') # get enrichResult object data(eres_dex, package='carnation') # convert to GeneTonic object gt <- GeneTonic::shake_enrichResult(eres_dex) obj <- reactive({ list(l_gs = gt$l_gs, anno_df = gt$anno_df, label = 'comp1') }) res_obj <- reactive({ res }) config <- reactiveVal(get_config()) # run simple shiny app with plot if(interactive()){ shinyApp( ui = fluidPage( sidebarPanel(enrichmapUI('p', 'sidebar')), mainPanel(enrichmapUI('p', 'main')) ), server = function(input, output, session){ enrichmapServer('p', obj, res_obj, config) } ) }
This function takes an enrichResult object and DE analysis results and creates a GeneTonic object.
enrich_to_genetonic(enrich, res)enrich_to_genetonic(enrich, res)
enrich |
enrichResult object |
res |
data frame with DE analysis results |
GeneTonic object
# get enrich & res objects data(res_dex, package="carnation") data(eres_dex, package="carnation") # convert to GeneTonic object gt <- enrich_to_genetonic(eres_dex, res_dex)# get enrich & res objects data(res_dex, package="carnation") data(eres_dex, package="carnation") # convert to GeneTonic object gt <- enrich_to_genetonic(eres_dex, res_dex)
enrichResult object for differentially expressed genes in the
cell line comparison.An enrichResult object for differentially expressed genes in the
cell line comparison.
An enrichResult object, generated with the enrichGO function
from the clusterProfiler package.
This enrichResult object was created to test for functional
enrichment using the GO Biological Process (BP) ontology on the top
100 differentially expressed genes from the cell line
comparison.
Details on how this object has been created are included in the
create_carnation_data.R script, included in the scripts folder of the
Carnation package.
Himes BE, Jiang X, Wagner P, Hu R, Wang Q, Klanderman B, Whitaker RM, Duan Q, Lasky-Su J, Nikolos C, Jester W, Johnson M, Panettieri R Jr, Tantisira KG, Weiss ST, Lu Q. “RNA-Seq Transcriptome Profiling Identifies CRISPLD2 as a Glucocorticoid Responsive Gene that Modulates Cytokine Function in Airway Smooth Muscle Cells.” PLoS One. 2014 Jun 13;9(6):e99625. PMID: 24926665. GEO: GSE52778
enrichResult object for differentially expressed genes in the
dexamethasone treatment comparison.An enrichResult object for differentially expressed genes in the
dexamethasone treatment comparison.
An enrichResult object, generated with the enrichGO function
from the clusterProfiler package.
This enrichResult object was created to test for functional
enrichment using the GO Biological Process (BP) ontology on the top
100 differentially expressed genes from the dexamethasone treatment
comparison.
Details on how this object has been created are included in the
create_carnation_data.R script, included in the scripts folder of the
Carnation package.
Himes BE, Jiang X, Wagner P, Hu R, Wang Q, Klanderman B, Whitaker RM, Duan Q, Lasky-Su J, Nikolos C, Jester W, Johnson M, Panettieri R Jr, Tantisira KG, Weiss ST, Lu Q. “RNA-Seq Transcriptome Profiling Identifies CRISPLD2 as a Glucocorticoid Responsive Gene that Modulates Cytokine Function in Airway Smooth Muscle Cells.” PLoS One. 2014 Jun 13;9(6):e99625. PMID: 24926665. GEO: GSE52778
This function works by grouping long lists of genes into groups of a specified size. Each group is collapsed using commas, while groups are separated by spaces so that datatable formatting is tricked into separating space-separated groups and not comma-separated groups
format_genes(g, sep = "\\/", genes.per.line = 6)format_genes(g, sep = "\\/", genes.per.line = 6)
g |
vector of gene names |
sep |
gene name separator |
genes.per.line |
number of genes to show in a line |
vector of gene names prettified for data.table output
# string with genes separated by '/' g <- "gene1/gene2/gene3/gene4/gene5/gene6/gene7" gg <- format_genes(g, genes.per.line=3)# string with genes separated by '/' g <- "gene1/gene2/gene3/gene4/gene5/gene6/gene7" gg <- format_genes(g, genes.per.line=3)
Prepare list for UpSet plots, but include rownames
fromList.with.names(lst)fromList.with.names(lst)
lst |
List of sets to compare (same input as to UpSetR::fromList) |
data.frame of 1 and 0 showing which genes are in which sets
# list of genes lst <- list(group1 = c(a = "gene1", b = "gene2", c = "gene3", d = "gene4"), group2 = c(c = "gene3", d = "gene4")) # binarized matrix with group membership df <- fromList.with.names(lst)# list of genes lst <- list(group1 = c(a = "gene1", b = "gene2", c = "gene3", d = "gene4"), group2 = c(c = "gene3", d = "gene4")) # binarized matrix with group membership df <- fromList.with.names(lst)
UI & module to show functional enrichment tables & plots.
enrichUI(id, panel, tab = "none") enrichServer(id, obj, upset_table, gene_scratchpad, reset_genes, config)enrichUI(id, panel, tab = "none") enrichServer(id, obj, upset_table, gene_scratchpad, reset_genes, config)
id |
ID string used to match the ID used to call the module UI function |
panel |
string, can be 'sidebar' or 'main' |
tab |
string, if 'table' show table settings, if 'plots' show plot settings; if 'compare_results', show comparison settings. |
obj |
reactiveValues object containing carnation object |
upset_table |
reactive, data from upset plot module |
gene_scratchpad |
reactive, genes selected in gene scratchpad |
reset_genes |
reactive to reset genes in scratchpad |
config |
reactive list with config settings |
UI returns tagList with plot UI server returns reactive with gene selected from functional enrichment tables.
library(shiny) library(DESeq2) # Create reactive values to simulate app state oobj <- make_example_carnation_object() obj <- reactiveValues( dds = oobj$dds, rld = oobj$rld, res = oobj$res, all_dds = oobj$all_dds, all_rld = oobj$all_rld, dds_mapping = oobj$dds_mapping ) upset_table <- reactiveValues(tbl=NULL, intersections=NULL, set_labels=NULL) gene_scratchpad <- reactive({ c('gene1', 'gene2') }) config <- reactiveVal(get_config()) shinyApp( ui = fluidPage( sidebarPanel( conditionalPanel(condition = "input.func == 'Table'", enrichUI('p', 'sidebar', 'table') ), conditionalPanel(condition = "input.func == 'Plot'", enrichUI('p', 'sidebar', 'plot') ), conditionalPanel(condition = "input.func == 'Compare results'", enrichUI('p', 'sidebar', 'compare_results') ) ), mainPanel( tabsetPanel(id='func', tabPanel('Table', enrichUI('p', 'main', 'table') ), # tabPanel table tabPanel('Plot', enrichUI('p', 'main', 'plot') ), # tabPanel plot tabPanel('Compare results', enrichUI('p', 'main', 'compare_results') ) # tabPanel compare_results ) # tabsetPanel func ) # tabPanel ), server = function(input, output, session){ enrich_data <- enrichServer('p', obj, upset_table, gene_scratchpad, reactive({ FALSE }), config) } )library(shiny) library(DESeq2) # Create reactive values to simulate app state oobj <- make_example_carnation_object() obj <- reactiveValues( dds = oobj$dds, rld = oobj$rld, res = oobj$res, all_dds = oobj$all_dds, all_rld = oobj$all_rld, dds_mapping = oobj$dds_mapping ) upset_table <- reactiveValues(tbl=NULL, intersections=NULL, set_labels=NULL) gene_scratchpad <- reactive({ c('gene1', 'gene2') }) config <- reactiveVal(get_config()) shinyApp( ui = fluidPage( sidebarPanel( conditionalPanel(condition = "input.func == 'Table'", enrichUI('p', 'sidebar', 'table') ), conditionalPanel(condition = "input.func == 'Plot'", enrichUI('p', 'sidebar', 'plot') ), conditionalPanel(condition = "input.func == 'Compare results'", enrichUI('p', 'sidebar', 'compare_results') ) ), mainPanel( tabsetPanel(id='func', tabPanel('Table', enrichUI('p', 'main', 'table') ), # tabPanel table tabPanel('Plot', enrichUI('p', 'main', 'plot') ), # tabPanel plot tabPanel('Compare results', enrichUI('p', 'main', 'compare_results') ) # tabPanel compare_results ) # tabsetPanel func ) # tabPanel ), server = function(input, output, session){ enrich_data <- enrichServer('p', obj, upset_table, gene_scratchpad, reactive({ FALSE }), config) } )
UI & module to generate fuzzy enrichment map plots.
fuzzyPlotUI(id, panel) fuzzyPlotServer(id, obj, args, config)fuzzyPlotUI(id, panel) fuzzyPlotServer(id, obj, args, config)
id |
Module id |
panel |
string, can be 'sidebar' or 'main' |
obj |
reactive containing 'distilled' enrichment results |
args |
reactive, list with plot arguments, 'numcat' (number of categories to plot) |
config |
reactive list with config settings |
UI returns tagList with plot UI server returns reactive with number of plotted terms
library(shiny) # get enrichResult object data(eres_dex, package='carnation') # preprocess & convert to GeneTonic object gt <- GeneTonic::shake_enrichResult(eres_dex) # get distilled results df <- GeneTonic::gs_fuzzyclustering(gt[seq_len(10),], similarity_threshold = 0.35, fuzzy_seeding_initial_neighbors = 3, fuzzy_multilinkage_rule = 0.5) # number of plotted terms args <- reactive({ list(numcat=10) }) config <- reactiveVal(get_config()) # run simple shiny app with plot if(interactive()){ shinyApp( ui = fluidPage( sidebarPanel(fuzzyPlotUI('p', 'sidebar')), mainPanel(fuzzyPlotUI('p', 'main')) ), server = function(input, output, session){ numcat <- observe({ fuzzyPlotServer('p', reactive({ df }), args, config) }) } ) }library(shiny) # get enrichResult object data(eres_dex, package='carnation') # preprocess & convert to GeneTonic object gt <- GeneTonic::shake_enrichResult(eres_dex) # get distilled results df <- GeneTonic::gs_fuzzyclustering(gt[seq_len(10),], similarity_threshold = 0.35, fuzzy_seeding_initial_neighbors = 3, fuzzy_multilinkage_rule = 0.5) # number of plotted terms args <- reactive({ list(numcat=10) }) config <- reactiveVal(get_config()) # run simple shiny app with plot if(interactive()){ shinyApp( ui = fluidPage( sidebarPanel(fuzzyPlotUI('p', 'sidebar')), mainPanel(fuzzyPlotUI('p', 'main')) ), server = function(input, output, session){ numcat <- observe({ fuzzyPlotServer('p', reactive({ df }), args, config) }) } ) }
UI & server for module to create gene plot
genePlotUI(id, panel) genePlotServer(id, obj, coldata, plot_args, config)genePlotUI(id, panel) genePlotServer(id, obj, coldata, plot_args, config)
id |
Module id |
panel |
string, can be 'sidebar' or 'main' |
obj |
reactiveValues object containing carnation object |
coldata |
reactiveValues object containing object metadata |
plot_args |
reactive list with 3 elements: 'gene.id' (all gene IDs) & 'gene_scratchpad' (genes selected in scratchpad) & 'comp_all' (selected comparison) |
config |
reactive list with config settings |
UI returns tagList with gene plot UI. Server invisibly returns NULL (used for side effects).
library(shiny) library(DESeq2) # Create reactive values to simulate app state oobj <- make_example_carnation_object() obj <- reactiveValues( dds = oobj$dds, rld = oobj$rld, res = oobj$res, all_dds = oobj$all_dds, all_rld = oobj$all_rld, dds_mapping = oobj$dds_mapping ) # Set up coldata structure that the module expects coldata <- reactiveValues( curr = list( all_samples = colData(oobj$dds$main), main = colData(oobj$dds$main) ) ) plot_args <- reactive({ list( gene.to.plot = c("gene1", "gene2"), gene.id = rownames(oobj$dds$main), comp_all = "comp1" ) }) config <- reactiveVal(get_config()) shinyApp( ui = fluidPage( sidebarPanel(genePlotUI('p', 'sidebar')), mainPanel(genePlotUI('p', 'main')) ), server = function(input, output, session){ genePlotServer('p', obj, coldata, plot_args, config) } )library(shiny) library(DESeq2) # Create reactive values to simulate app state oobj <- make_example_carnation_object() obj <- reactiveValues( dds = oobj$dds, rld = oobj$rld, res = oobj$res, all_dds = oobj$all_dds, all_rld = oobj$all_rld, dds_mapping = oobj$dds_mapping ) # Set up coldata structure that the module expects coldata <- reactiveValues( curr = list( all_samples = colData(oobj$dds$main), main = colData(oobj$dds$main) ) ) plot_args <- reactive({ list( gene.to.plot = c("gene1", "gene2"), gene.id = rownames(oobj$dds$main), comp_all = "comp1" ) }) config <- reactiveVal(get_config()) shinyApp( ui = fluidPage( sidebarPanel(genePlotUI('p', 'sidebar')), mainPanel(genePlotUI('p', 'main')) ), server = function(input, output, session){ genePlotServer('p', obj, coldata, plot_args, config) } )
This function checks for an environment variable 'CARNATION_ACCESS_YAML' to specify directory to save access yaml. If env variable does not exist uses home directory as save location.
get_access_path()get_access_path()
path to access yaml
p <- get_access_path()p <- get_access_path()
This function reads the bundled package config and returns it. If a local config yaml exists, only supported user-editable settings are merged into the returned config.
get_config(config_path = NULL)get_config(config_path = NULL)
config_path |
optional path to a local config yaml. If |
list containing config items
cfg <- get_config()cfg <- get_config()
This function checks for an environment variable
CARNATION_CONFIG_YAML to specify the local config yaml path.
If the variable is not set, a default path in the home directory is used.
get_config_path()get_config_path()
path to local config yaml
p <- get_config_path()p <- get_config_path()
This function plots a degPatterns object.
get_degplot( obj, time, color = NULL, cluster_column = "cluster", cluster_to_show, x_order, points = TRUE, boxes = TRUE, smooth = "smooth", lines = TRUE, facet = TRUE, prefix_title = "Cluster ", genes_to_label = NULL )get_degplot( obj, time, color = NULL, cluster_column = "cluster", cluster_to_show, x_order, points = TRUE, boxes = TRUE, smooth = "smooth", lines = TRUE, facet = TRUE, prefix_title = "Cluster ", genes_to_label = NULL )
obj |
degPatterns object |
time |
metadata variable to plot on x-axis |
color |
variable to color plot |
cluster_column |
column to use for grouping genes |
cluster_to_show |
which clusters to show in plot |
x_order |
order of x-axis values |
points |
boolean, show samples on plot? Default: TRUE |
boxes |
boolean, show boxes on plot? Default: TRUE |
smooth |
what type of trendline to use? can be 'smooth' (default) or 'line'. |
lines |
show lines joining samples? Default: TRUE |
facet |
boolean, should plot be faceted? Default: TRUE |
prefix_title |
string, prefix for facet titles |
genes_to_label |
genes to label on plot |
ggplot handle
# get degpatterns object data(degpatterns_dex, package = 'carnation') # get pattern plot all_clusters <- unique(degpatterns_dex$normalized$cluster) dp <- get_degplot(degpatterns_dex, time='dex', cluster_to_show=all_clusters, x_order=c('untrt','trt'))# get degpatterns object data(degpatterns_dex, package = 'carnation') # get pattern plot all_clusters <- unique(degpatterns_dex$normalized$cluster) dp <- get_degplot(degpatterns_dex, time='dex', cluster_to_show=all_clusters, x_order=c('untrt','trt'))
This is a simple function to obtain read counts for a specified gene, based on the DESeq2::plotCounts function.
get_gene_counts(dds, gene, intgroup = "condition", norm_method = "libsize")get_gene_counts(dds, gene, intgroup = "condition", norm_method = "libsize")
dds |
DESeqDataSet object |
gene |
gene name vector |
intgroup |
metadata variable to attach to counts |
norm_method |
normalization method, can be 'libsize' (default) or 'vst' |
data.frame with gene counts
# make example DESeq data set dds <- DESeq2::makeExampleDESeqDataSet() # get counts for gene1 gg <- get_gene_counts(dds, 'gene1')# make example DESeq data set dds <- DESeq2::makeExampleDESeqDataSet() # get counts for gene1 gg <- get_gene_counts(dds, 'gene1')
This function takes in a path to an RDS file and returns a string to be used as project name
get_project_name_from_path( x, depth = 2, end_offset = 0, staging_dir = "dev", fsep = .Platform$file.sep )get_project_name_from_path( x, depth = 2, end_offset = 0, staging_dir = "dev", fsep = .Platform$file.sep )
x |
character path to RDS file |
depth |
integer how many levels below path to look? |
end_offset |
integer how far from the end of path to end? |
staging_dir |
name of staging directory |
fsep |
file separator to split path with |
project name parsed from path to object
# path to carnation object obj_path <- "/path/to/project/test/main.rnaseq.rds" # parsed project name get_project_name_from_path(obj_path, depth = 2, end_offset = 0)# path to carnation object obj_path <- "/path/to/project/test/main.rnaseq.rds" # parsed project name get_project_name_from_path(obj_path, depth = 2, end_offset = 0)
Generate upset plot table
get_upset_table(gene.lists, comp_split_pattern = ";")get_upset_table(gene.lists, comp_split_pattern = ";")
gene.lists |
list with character vectors of gene names |
comp_split_pattern |
character used to separate gene set names |
list with upset table elements
lst <- list(group1 = c(a = "gene1", b = "gene2", c = "gene3", d = "gene4"), group2 = c(b = "gene2", d = "gene4", e = "gene5"), group3 = c(d = "gene4", e = "gene5", f = "gene6")) df <- get_upset_table(lst) str(df)lst <- list(group1 = c(a = "gene1", b = "gene2", c = "gene3", d = "gene4"), group2 = c(b = "gene2", d = "gene4", e = "gene5"), group3 = c(d = "gene4", e = "gene5", f = "gene6")) df <- get_upset_table(lst) str(df)
Get initial y-axis limits
get_y_init(df, y_delta, pseudocount)get_y_init(df, y_delta, pseudocount)
df |
data.frame with counts. Must have column 'count' |
y_delta |
y-axis padding for visualization, must be between 0 and 1 |
pseudocount |
pseudo-count to add to the data.frame |
min and max limits for count column, padded for visualization
# make example DESeq dataset dds <- DESeq2::makeExampleDESeqDataSet() # get gene counts df <- get_gene_counts(dds, gene = c('gene1', 'gene2')) # get y axis limits get_y_init(df, y_delta = 0.01, pseudocount = 1)# make example DESeq dataset dds <- DESeq2::makeExampleDESeqDataSet() # get gene counts df <- get_gene_counts(dds, gene = c('gene1', 'gene2')) # get y axis limits get_y_init(df, y_delta = 0.01, pseudocount = 1)
This function creates the gene plot.
getcountplot( df, intgroup = "group", factor.levels, title = NULL, ylab = "Normalized counts", color = "gene", nrow = 2, ymin = NULL, ymax = NULL, log = TRUE, freey = FALSE, trendline = "smooth", facet = NULL, legend = TRUE, boxes = TRUE, rotate_x_labels = 30 )getcountplot( df, intgroup = "group", factor.levels, title = NULL, ylab = "Normalized counts", color = "gene", nrow = 2, ymin = NULL, ymax = NULL, log = TRUE, freey = FALSE, trendline = "smooth", facet = NULL, legend = TRUE, boxes = TRUE, rotate_x_labels = 30 )
df |
data.frame with gene counts |
intgroup |
metadata variable to plot on x-axis |
factor.levels |
levels of intgroup to show on x-axis |
title |
title of plot |
ylab |
y-axis label |
color |
metadata variable to color by |
nrow |
number of rows to plot if faceting |
ymin |
y-axis lower limit |
ymax |
y-axis upper limit |
log |
should y-axis be log10-transformed? |
freey |
should y-axes of faceted plots have independent scales? |
trendline |
type of trendline to draw |
facet |
metadata variable to facet by |
legend |
show legend? |
boxes |
show boxes? |
rotate_x_labels |
angle to rotate x-axis labels (default=30) |
ggplot handle
# make example DESeq dataset dds <- DESeq2::makeExampleDESeqDataSet() # get gene counts df <- get_gene_counts(dds, gene = c('gene1', 'gene2')) # standard gene plot p <- getcountplot(df, intgroup = "condition", factor.levels = c("A", "B")) # with genes faceted p1 <- getcountplot(df, intgroup = "condition", factor.levels = c("A", "B"), facet = "gene")# make example DESeq dataset dds <- DESeq2::makeExampleDESeqDataSet() # get gene counts df <- get_gene_counts(dds, gene = c('gene1', 'gene2')) # standard gene plot p <- getcountplot(df, intgroup = "condition", factor.levels = c("A", "B")) # with genes faceted p1 <- getcountplot(df, intgroup = "condition", factor.levels = c("A", "B"), facet = "gene")
This is a copy of gs_radar from GeneTonic where the labels of gene sets are converted to parameters
gs_radar( res_enrich, res_enrich2 = NULL, label1 = "scenario 1", label2 = "scenario 2", n_gs = 20, p_value_column = "gs_pvalue" )gs_radar( res_enrich, res_enrich2 = NULL, label1 = "scenario 1", label2 = "scenario 2", n_gs = 20, p_value_column = "gs_pvalue" )
res_enrich |
GeneTonic object for comparison 1 |
res_enrich2 |
GeneTonic object for comparison 2 (default = NULL) |
label1 |
label for comparison 1 |
label2 |
label for comparison 2 |
n_gs |
number of gene sets (default = 20) |
p_value_column |
column to use as p-value (default = 'gs_pvalue') |
ggplot handle
library(GeneTonic) # get DESeqResults object data(res_dex, package='carnation') # get enrichResult object data(eres_dex, package='carnation') # convert to GeneTonic object gt <- shake_enrichResult(eres_dex) # get annotation df idx <- match(c('gene','symbol'), tolower(colnames(res_dex))) anno_df <- res_dex[,idx] colnames(anno_df) <- c('gene_id', 'gene_name') # add aggregate score columns gt <- get_aggrscores(gt, res_dex, anno_df) # make radar plot p <- gs_radar(gt)library(GeneTonic) # get DESeqResults object data(res_dex, package='carnation') # get enrichResult object data(eres_dex, package='carnation') # convert to GeneTonic object gt <- shake_enrichResult(eres_dex) # get annotation df idx <- match(c('gene','symbol'), tolower(colnames(res_dex))) anno_df <- res_dex[,idx] colnames(anno_df) <- c('gene_id', 'gene_name') # add aggregate score columns gt <- get_aggrscores(gt, res_dex, anno_df) # make radar plot p <- gs_radar(gt)
Module UI & server to generate heatmap.
heatmapUI(id, panel) heatmapServer(id, obj, coldata, plot_args, gene_scratchpad, config)heatmapUI(id, panel) heatmapServer(id, obj, coldata, plot_args, gene_scratchpad, config)
id |
Module id |
panel |
string, can be 'sidebar' or 'main' |
obj |
reactiveValues object containing carnation object |
coldata |
reactiveValues object containing object metadata |
plot_args |
reactive containing 'fdr.thres' (padj threshold), 'fc.thres' (log2FC) & 'upset_data' (list containing data from upset plot module) |
gene_scratchpad |
reactiveValues object containing genes selected in scratchpad which will be labeled |
config |
reactive list with config settings |
UI returns tagList with heatmap UI. Server invisibly returns NULL (used for side effects).
library(shiny) library(DESeq2) # Create reactive values to simulate app state oobj <- make_example_carnation_object() obj <- reactiveValues( dds = oobj$dds, rld = oobj$rld, res = oobj$res, all_dds = oobj$all_dds, all_rld = oobj$all_rld, dds_mapping = oobj$dds_mapping ) cdata <- lapply(oobj$rld, function(x) colData(x)) coldata <- reactiveValues( all=cdata, curr=cdata ) plot_args <- reactive({ list( fdr.thres=0.1, fc.thres=0, upset_data=list(genes=NULL, labels=NULL) ) }) gene_scratchpad <- reactive({ c('gene1', 'gene2') }) config <- reactiveVal(get_config()) shinyApp( ui = fluidPage( sidebarPanel(heatmapUI('p', 'sidebar')), mainPanel(heatmapUI('p', 'sidebar')) ), server = function(input, output, session){ heatmapServer('p', obj, coldata, plot_args, gene_scratchpad, config) } )library(shiny) library(DESeq2) # Create reactive values to simulate app state oobj <- make_example_carnation_object() obj <- reactiveValues( dds = oobj$dds, rld = oobj$rld, res = oobj$res, all_dds = oobj$all_dds, all_rld = oobj$all_rld, dds_mapping = oobj$dds_mapping ) cdata <- lapply(oobj$rld, function(x) colData(x)) coldata <- reactiveValues( all=cdata, curr=cdata ) plot_args <- reactive({ list( fdr.thres=0.1, fc.thres=0, upset_data=list(genes=NULL, labels=NULL) ) }) gene_scratchpad <- reactive({ c('gene1', 'gene2') }) config <- reactiveVal(get_config()) shinyApp( ui = fluidPage( sidebarPanel(heatmapUI('p', 'sidebar')), mainPanel(heatmapUI('p', 'sidebar')) ), server = function(input, output, session){ heatmapServer('p', obj, coldata, plot_args, gene_scratchpad, config) } )
Module UI & server for help buttons.
helpButtonUI(id) helpButtonServer(id, ...)helpButtonUI(id) helpButtonServer(id, ...)
id |
Module id. This also doubles as prefixes for help text files. |
... |
other params passed to helpModal() |
UI returns tagList with help button UI. Server invisibly returns NULL (used for side effects).
library(shiny) # app with a single help button to show DE summary table details if(interactive()){ shinyApp( ui = fluidPage( helpButtonUI('de_summary_help') ), server = function(input, output, session){ helpButtonServer('de_summary_help') } ) }library(shiny) # app with a single help button to show DE summary table details if(interactive()){ shinyApp( ui = fluidPage( helpButtonUI('de_summary_help') ), server = function(input, output, session){ helpButtonServer('de_summary_help') } ) }
This generates a modal dialog that includes text from a markdown file.
helpModal(mdfile, title = NULL, ...)helpModal(mdfile, title = NULL, ...)
mdfile |
path to markdown file |
title |
Title of modal dialog |
... |
other params passed to modalDialog() |
Modal dialog with help documentation.
UI & module to generate horizon plots.
horizonUI(id, panel) horizonServer(id, obj, config)horizonUI(id, panel) horizonServer(id, obj, config)
id |
Module id |
panel |
string, can be 'sidebar' or 'main' |
obj |
reactiveValues object containing two GeneTonic objects |
config |
reactive list with config settings |
UI returns tagList with plot UI server invisibly returns NULL (used for side effects)
library(shiny) # get enrichResult object data(eres_dex, package='carnation') # convert to GeneTonic object gt <- GeneTonic::shake_enrichResult(eres_dex) # get second enrichResult object data(eres_cell, package='carnation') # convert to GeneTonic object gt1 <- GeneTonic::shake_enrichResult(eres_cell) obj <- reactive({ list( obj1 = list(l_gs = gt$l_gs, anno_df = gt$anno_df, label = 'comp1'), obj2 = list(l_gs = gt1$l_gs, anno_df = gt1$anno_df, label = 'comp2') ) }) config <- reactiveVal(get_config()) # run simple shiny app with plot if(interactive()){ shinyApp( ui = fluidPage( sidebarPanel(horizonUI('p', 'sidebar')), mainPanel(horizonUI('p', 'main')) ), server = function(input, output, session){ horizonServer('p', obj, config) } ) }library(shiny) # get enrichResult object data(eres_dex, package='carnation') # convert to GeneTonic object gt <- GeneTonic::shake_enrichResult(eres_dex) # get second enrichResult object data(eres_cell, package='carnation') # convert to GeneTonic object gt1 <- GeneTonic::shake_enrichResult(eres_cell) obj <- reactive({ list( obj1 = list(l_gs = gt$l_gs, anno_df = gt$anno_df, label = 'comp1'), obj2 = list(l_gs = gt1$l_gs, anno_df = gt1$anno_df, label = 'comp2') ) }) config <- reactiveVal(get_config()) # run simple shiny app with plot if(interactive()){ shinyApp( ui = fluidPage( sidebarPanel(horizonUI('p', 'sidebar')), mainPanel(horizonUI('p', 'main')) ), server = function(input, output, session){ horizonServer('p', obj, config) } ) }
is user is in admin group?
in_admin_group(u)in_admin_group(u)
u |
username |
TRUE/FALSE to indicate if the user is part of the admin group
# save access details to file home <- Sys.getenv('HOME') # create carnation data area if it doesn't exist carnation_home <- file.path(home, 'carnation/data') if(!dir.exists(carnation_home)) dir.create(carnation_home) create_access_yaml(user = 'admin', user_group = 'admin', data_area = carnation_home) check <- in_admin_group('user')# save access details to file home <- Sys.getenv('HOME') # create carnation data area if it doesn't exist carnation_home <- file.path(home, 'carnation/data') if(!dir.exists(carnation_home)) dir.create(carnation_home) create_access_yaml(user = 'admin', user_group = 'admin', data_area = carnation_home) check <- in_admin_group('user')
This function copies the bundled package config to a user-writable local config yaml. This is intended for users who want to customize the supported config settings without editing the installed package.
init_local_config(config_path = get_config_path(), overwrite = FALSE)init_local_config(config_path = get_config_path(), overwrite = FALSE)
config_path |
path to the local config yaml to create.
Defaults to |
overwrite |
logical indicating whether to overwrite an existing file. |
Path to the local config yaml, invisibly.
cfg_out <- tempfile(fileext = ".yaml") init_local_config(cfg_out)cfg_out <- tempfile(fileext = ".yaml") init_local_config(cfg_out)
This function installs 'plotly' and 'kaleido' python packages in an environment to allow PDF downloads from plotly plots.
install_carnation(envname, ...)install_carnation(envname, ...)
envname |
name of the python environment |
... |
parameters passed to reticulate::py_install |
NULL, invisibly. The function is called for its side effects.
if(interactive()){ install_carnation() }if(interactive()){ install_carnation() }
is user an admin?
is_site_admin(u)is_site_admin(u)
u |
username |
boolean to indicate is user is in admin group
# check if default user is admin yy <- is_site_admin(u='admin')# check if default user is admin yy <- is_site_admin(u='admin')
Validate the schema for a single degpatterns analysis element used by the
pattern analysis module.
is_valid_pattern_obj(pattern_obj, require_symbol = FALSE)is_valid_pattern_obj(pattern_obj, require_symbol = FALSE)
pattern_obj |
A single pattern analysis element. Must be either a
|
require_symbol |
Logical, if |
Returns TRUE when validation succeeds, otherwise returns FALSE
after emitting a message describing the issue.
data(degpatterns_dex, package = "carnation") is_valid_pattern_obj(degpatterns_dex)data(degpatterns_dex, package = "carnation") is_valid_pattern_obj(degpatterns_dex)
Module UI & server to load new data
loadDataUI(id) loadDataServer(id, username, config, rds = NULL)loadDataUI(id) loadDataServer(id, username, config, rds = NULL)
id |
Module id |
username |
user name |
config |
reactive list with config settings |
rds |
Object to be edited |
UI returns tagList with module UI Server returns reactive with app reload trigger
library(shiny) username <- 'admin' config <- reactiveVal(get_config()) obj <- make_example_carnation_object() rds <- reactive({ obj=obj }) shinyApp( ui = fluidPage( loadDataUI('p') ), server = function(input, output, session){ loadDataServer('p', username=username, config, rds) } )library(shiny) username <- 'admin' config <- reactiveVal(get_config()) obj <- make_example_carnation_object() rds <- reactive({ obj=obj }) shinyApp( ui = fluidPage( loadDataUI('p') ), server = function(input, output, session){ loadDataServer('p', username=username, config, rds) } )
Returns example carnation object used in examples & testing
make_example_carnation_object()make_example_carnation_object()
reactiveValues object containing carnation object
obj <- make_example_carnation_object()obj <- make_example_carnation_object()
This function takes an uploaded object and sanitizes it to make sure it is suitable for internal use along with other additions:
adds a 'dds_mapping' element that maps dds_list keys to res_list objects.
if there are multiple dds_list objects, it adds a 'all_dds' element combining all samples.
make_final_object(obj)make_final_object(obj)
obj |
list object containing lists of DE analysis results, functional enrichment objects, pattern analysis objects & raw and normalized counts objects. |
final carnation object with additional pre-processing
library(DESeq2) # make example DESeq dataset dds <- makeExampleDESeqDataSet() # run DE analysis dds <- DESeq(dds) # extract comparison of interest res <- results(dds, contrast = c("condition", "A", "B")) # perform VST normalization rld <- varianceStabilizingTransformation(dds, blind = TRUE) # build minimal object obj <- list( res_list = list( comp = list( res = res, dds = "main", label = "A vs B" ) ), dds_list = list(main = dds), rld_list = list(main = rld) ) # final object final_obj <- make_final_object(obj)library(DESeq2) # make example DESeq dataset dds <- makeExampleDESeqDataSet() # run DE analysis dds <- DESeq(dds) # extract comparison of interest res <- results(dds, contrast = c("condition", "A", "B")) # perform VST normalization rld <- varianceStabilizingTransformation(dds, blind = TRUE) # build minimal object obj <- list( res_list = list( comp = list( res = res, dds = "main", label = "A vs B" ) ), dds_list = list(main = dds), rld_list = list(main = rld) ) # final object final_obj <- make_final_object(obj)
Most of the parameters are just placeholders and the dataframe must contain the columns 'ID' and 'geneID'
makeEnrichResult( df, split = "/", keytype = "UNKNOWN", ontology = "UNKNOWN", type = "enrichResult" )makeEnrichResult( df, split = "/", keytype = "UNKNOWN", ontology = "UNKNOWN", type = "enrichResult" )
df |
data frame with functional enrichment results |
split |
string, character used to split gene IDs |
keytype |
type of gene ID |
ontology |
ontology database being used |
type |
string, can be 'enrichResult' or 'gseaResult' |
enrichResult object
# get enrichResult object data(eres_dex, package='carnation') # extract the results df <- as.data.frame(eres_dex) # convert to a stripped down enrichResult object eres2 <- makeEnrichResult(df)# get enrichResult object data(eres_dex, package='carnation') # extract the results df <- as.data.frame(eres_dex) # convert to a stripped down enrichResult object eres2 <- makeEnrichResult(df)
UI & server for module to create MA plot
maPlotUI(id, panel) maPlotServer(id, obj, plot_args, config)maPlotUI(id, panel) maPlotServer(id, obj, plot_args, config)
id |
Module id |
panel |
string, can be 'sidebar' or 'main' |
obj |
reactiveValues object containing carnation object |
plot_args |
reactive containing 'fdr.thres' (padj threshold), 'fc.thres' (log2FC threshold) & 'gene.to.plot' (genes selected in scratchpad) |
config |
reactive list with config settings |
UI returns tagList with MA plot UI. Server invisibly returns NULL (used for side effects).
library(shiny) library(DESeq2) # Create reactive values to simulate app state oobj <- make_example_carnation_object() obj <- reactiveValues( dds = oobj$dds, rld = oobj$rld, res = oobj$res, all_dds = oobj$all_dds, all_rld = oobj$all_rld, dds_mapping = oobj$dds_mapping ) # Set up coldata structure that the module expects coldata <- reactiveValues( curr = list( all_samples = colData(oobj$dds$main), main = colData(oobj$dds$main) ) ) plot_args <- reactive({ list( fdr.thres=0.1, fc.thres=0, gene.to.plot=c('gene1', 'gene2') ) }) config <- reactiveVal(get_config()) shinyApp( ui = fluidPage( sidebarPanel(maPlotUI('p', 'sidebar')), mainPanel(maPlotUI('p', 'main')) ), server = function(input, output, session){ maPlotServer('p', obj, plot_args, config) } )library(shiny) library(DESeq2) # Create reactive values to simulate app state oobj <- make_example_carnation_object() obj <- reactiveValues( dds = oobj$dds, rld = oobj$rld, res = oobj$res, all_dds = oobj$all_dds, all_rld = oobj$all_rld, dds_mapping = oobj$dds_mapping ) # Set up coldata structure that the module expects coldata <- reactiveValues( curr = list( all_samples = colData(oobj$dds$main), main = colData(oobj$dds$main) ) ) plot_args <- reactive({ list( fdr.thres=0.1, fc.thres=0, gene.to.plot=c('gene1', 'gene2') ) }) config <- reactiveVal(get_config()) shinyApp( ui = fluidPage( sidebarPanel(maPlotUI('p', 'sidebar')), mainPanel(maPlotUI('p', 'main')) ), server = function(input, output, session){ maPlotServer('p', obj, plot_args, config) } )
This function materializes expensive derived pieces for a validated carnation object, including DESeqDataSet creation from raw count matrices, variance-stabilized counts, and GeneTonic conversions.
materialize_carnation_object(obj, config = NULL, cores = NULL)materialize_carnation_object(obj, config = NULL, cores = NULL)
obj |
A validated object returned by
|
config |
Optional config list. If NULL, will use |
cores |
Optional number of worker processes. If NULL, uses
|
The input object with materialized dds_list,
rld_list, and optional genetonic slots.
# Minimal example with DE results and counts library(DESeq2) # Create example data dds <- makeExampleDESeqDataSet() dds <- DESeq(dds) res <- results(dds, contrast = c("condition", "A", "B")) rld <- varianceStabilizingTransformation(dds, blind = TRUE) # Validate object inputs obj <- validate_carnation_object( res_list = list( comp1 = list( res = as.data.frame(res), dds = "main", label = "A vs B" ) ), dds_list = list(main = dds), rld_list = list(main = rld) ) materialized <- materialize_carnation_object(obj, cores = 1)# Minimal example with DE results and counts library(DESeq2) # Create example data dds <- makeExampleDESeqDataSet() dds <- DESeq(dds) res <- results(dds, contrast = c("condition", "A", "B")) rld <- varianceStabilizingTransformation(dds, blind = TRUE) # Validate object inputs obj <- validate_carnation_object( res_list = list( comp1 = list( res = as.data.frame(res), dds = "main", label = "A vs B" ) ), dds_list = list(main = dds), rld_list = list(main = rld) ) materialized <- materialize_carnation_object(obj, cores = 1)
This module generates the metadata tab that allows users to view the metadata associated with the loaded carnation object.
metadataUI(id, panel) metadataServer(id, obj, cols.to.drop)metadataUI(id, panel) metadataServer(id, obj, cols.to.drop)
id |
Module id |
panel |
context for generating ui elements ('sidebar' or 'main') |
obj |
reactiveValues object containing carnation object |
cols.to.drop |
columns to hide from table |
UI returns tagList with metadata UI. Server returns reactive object with metadata.
library(shiny) # Create reactive values to simulate app state oobj <- make_example_carnation_object() obj <- reactiveValues( dds = oobj$dds, rld = oobj$rld, res = oobj$res, all_dds = oobj$all_dds, all_rld = oobj$all_rld, dds_mapping = oobj$dds_mapping ) config <- get_config() cols.to.drop <- config$server$cols.to.drop shinyApp( ui = fluidPage( sidebarPanel(metadataUI('p', 'sidebar')), mainPanel(metadataUI('p', 'main')) ), server = function(input, output, session){ # reactiveVal to save updates saved_data <- reactiveVal() cdata <- metadataServer('p', obj, cols.to.drop) observeEvent(cdata(), { saved_data(cdata()) }) } )library(shiny) # Create reactive values to simulate app state oobj <- make_example_carnation_object() obj <- reactiveValues( dds = oobj$dds, rld = oobj$rld, res = oobj$res, all_dds = oobj$all_dds, all_rld = oobj$all_rld, dds_mapping = oobj$dds_mapping ) config <- get_config() cols.to.drop <- config$server$cols.to.drop shinyApp( ui = fluidPage( sidebarPanel(metadataUI('p', 'sidebar')), mainPanel(metadataUI('p', 'main')) ), server = function(input, output, session){ # reactiveVal to save updates saved_data <- reactiveVal() cdata <- metadataServer('p', obj, cols.to.drop) observeEvent(cdata(), { saved_data(cdata()) }) } )
summary(res) prints out info; this function captures it into a dataframe
my.summary(res, dds, alpha, lfc.thresh = 0)my.summary(res, dds, alpha, lfc.thresh = 0)
res |
DESeq2 results object |
dds |
DEseq2 object |
alpha |
Alpha level at which to call significantly changing genes |
lfc.thresh |
log2FoldChange threshold |
Dataframe of summarized results
n_genes <- 100 # make mock dds list dds <- DESeq2::makeExampleDESeqDataSet(n=n_genes) # make mock results df res <- data.frame( baseMean = runif(n_genes, 10, 1000), log2FoldChange = rnorm(n_genes, 0, 2), lfcSE = runif(n_genes, 0.1, 0.5), stat = rnorm(n_genes, 0, 3), pvalue = runif(n_genes, 0, 1), padj = runif(n_genes, 0, 1), symbol = paste0("GENE", 1:n_genes), row.names = paste0("gene", 1:n_genes) ) # get summary df <- my.summary(res, dds, alpha=0.1)n_genes <- 100 # make mock dds list dds <- DESeq2::makeExampleDESeqDataSet(n=n_genes) # make mock results df res <- data.frame( baseMean = runif(n_genes, 10, 1000), log2FoldChange = rnorm(n_genes, 0, 2), lfcSE = runif(n_genes, 0.1, 0.5), stat = rnorm(n_genes, 0, 3), pvalue = runif(n_genes, 0, 1), padj = runif(n_genes, 0, 1), symbol = paste0("GENE", 1:n_genes), row.names = paste0("gene", 1:n_genes) ) # get summary df <- my.summary(res, dds, alpha=0.1)
Module UI + server to generate a pca plot.
pcaPlotUI(id, panel) pcaPlotServer(id, obj, coldata, config)pcaPlotUI(id, panel) pcaPlotServer(id, obj, coldata, config)
id |
Module id |
panel |
string, can be 'sidebar' or 'main' |
obj |
reactiveValues object containing carnation object |
coldata |
reactiveValues object containing object metadata |
config |
reactive list with config settings |
UI returns tagList with PCA plot UI. Server invisibly returns NULL (used for side effects).
library(shiny) library(DESeq2) # Create reactive values to simulate app state oobj <- make_example_carnation_object() obj <- reactiveValues( dds = oobj$dds, rld = oobj$rld, res = oobj$res, all_dds = oobj$all_dds, all_rld = oobj$all_rld, dds_mapping = oobj$dds_mapping ) # Set up coldata structure that the module expects coldata <- reactiveValues( curr = list( all_samples = colData(oobj$dds$main), main = colData(oobj$dds$main) ) ) config <- reactiveVal(get_config()) shinyApp( ui = fluidPage( sidebarPanel(pcaPlotUI('p', 'sidebar')), mainPanel(pcaPlotUI('p', 'main')) ), server = function(input, output, session){ pcaPlotServer('p', obj, coldata, config) } )library(shiny) library(DESeq2) # Create reactive values to simulate app state oobj <- make_example_carnation_object() obj <- reactiveValues( dds = oobj$dds, rld = oobj$rld, res = oobj$res, all_dds = oobj$all_dds, all_rld = oobj$all_rld, dds_mapping = oobj$dds_mapping ) # Set up coldata structure that the module expects coldata <- reactiveValues( curr = list( all_samples = colData(oobj$dds$main), main = colData(oobj$dds$main) ) ) config <- reactiveVal(get_config()) shinyApp( ui = fluidPage( sidebarPanel(pcaPlotUI('p', 'sidebar')), mainPanel(pcaPlotUI('p', 'main')) ), server = function(input, output, session){ pcaPlotServer('p', obj, coldata, config) } )
This function creates an MA plot from a data.frame containing DE analysis results.
plotMA.label( res, fdr.thres = 0.01, fc.thres = 0, fc.lim = NULL, lab.genes = NULL, tolower.cols = c("SYMBOL", "ALIAS") )plotMA.label( res, fdr.thres = 0.01, fc.thres = 0, fc.lim = NULL, lab.genes = NULL, tolower.cols = c("SYMBOL", "ALIAS") )
res |
data.frame with DE analysis results. Must contain "padj" & "log2FoldChange" columns |
fdr.thres |
False discovery rate (FDR) threshold |
fc.thres |
log2FoldChange threshold |
fc.lim |
y-axis limits |
lab.genes |
genes to label on MA plot |
tolower.cols |
column names that will be converted to lower case |
ggplot handle
# make mock results df n_genes <- 100 res <- data.frame( baseMean = runif(n_genes, 10, 1000), log2FoldChange = rnorm(n_genes, 0, 2), lfcSE = runif(n_genes, 0.1, 0.5), stat = rnorm(n_genes, 0, 3), pvalue = runif(n_genes, 0, 1), padj = runif(n_genes, 0, 1), symbol = paste0("GENE", 1:n_genes), row.names = paste0("gene", 1:n_genes) ) plotMA.label(res, lab.genes = c("gene1", "gene2"))# make mock results df n_genes <- 100 res <- data.frame( baseMean = runif(n_genes, 10, 1000), log2FoldChange = rnorm(n_genes, 0, 2), lfcSE = runif(n_genes, 0.1, 0.5), stat = rnorm(n_genes, 0, 3), pvalue = runif(n_genes, 0, 1), padj = runif(n_genes, 0, 1), symbol = paste0("GENE", 1:n_genes), row.names = paste0("gene", 1:n_genes) ) plotMA.label(res, lab.genes = c("gene1", "gene2"))
This function creates an MA plot from a data.frame containing DE analysis results using plot_ly
plotMA.label_ly( res, fdr.thres = 0.01, fc.thres = 0, fc.lim = NULL, lab.genes = NULL, tolower.cols = c("SYMBOL", "ALIAS") )plotMA.label_ly( res, fdr.thres = 0.01, fc.thres = 0, fc.lim = NULL, lab.genes = NULL, tolower.cols = c("SYMBOL", "ALIAS") )
res |
data.frame with DE analysis results. Must contain "padj" & "log2FoldChange" columns |
fdr.thres |
False discovery rate (FDR) threshold |
fc.thres |
log2FoldChange threshold |
fc.lim |
y-axis limits |
lab.genes |
genes to label on MA plot |
tolower.cols |
column names that will be converted to lower case |
plotly handle
# make mock results df n_genes <- 100 res <- data.frame( baseMean = runif(n_genes, 10, 1000), log2FoldChange = rnorm(n_genes, 0, 2), lfcSE = runif(n_genes, 0.1, 0.5), stat = rnorm(n_genes, 0, 3), pvalue = runif(n_genes, 0, 1), padj = runif(n_genes, 0, 1), symbol = paste0("GENE", 1:n_genes), row.names = paste0("gene", 1:n_genes) ) plotMA.label_ly(res, lab.genes = c("gene1", "gene2"))# make mock results df n_genes <- 100 res <- data.frame( baseMean = runif(n_genes, 10, 1000), log2FoldChange = rnorm(n_genes, 0, 2), lfcSE = runif(n_genes, 0.1, 0.5), stat = rnorm(n_genes, 0, 3), pvalue = runif(n_genes, 0, 1), padj = runif(n_genes, 0, 1), symbol = paste0("GENE", 1:n_genes), row.names = paste0("gene", 1:n_genes) ) plotMA.label_ly(res, lab.genes = c("gene1", "gene2"))
Plot an interactive PCA plot
plotPCA.ly(rld, intgroup)plotPCA.ly(rld, intgroup)
rld |
DESeqTransform object output by varianceStabilizingTransformation() or rlog() |
intgroup |
character vector of names in colData(x) to use for grouping |
Handle to ggplot with added label field in aes_string() for plotting with ggplotly()
# make example dds object dds <- DESeq2::makeExampleDESeqDataSet() # normalize rld <- DESeq2::varianceStabilizingTransformation(dds, blind=TRUE) # make pca plot p <- plotPCA.ly(rld, intgroup='condition')# make example dds object dds <- DESeq2::makeExampleDESeqDataSet() # normalize rld <- DESeq2::varianceStabilizingTransformation(dds, blind=TRUE) # make pca plot p <- plotPCA.ly(rld, intgroup='condition')
Create a PCA plot with specified PCs on x- and y-axis
plotPCA.san( object, intgroup = "group", pcx, pcy, pcz = NULL, ntop = 500, samples = NULL, loadings = FALSE, loadings_ngenes = 10 )plotPCA.san( object, intgroup = "group", pcx, pcy, pcz = NULL, ntop = 500, samples = NULL, loadings = FALSE, loadings_ngenes = 10 )
object |
normalized DESeqDataSet object |
intgroup |
metadata variable to use for grouping samples |
pcx |
principal component to plot on x-axis |
pcy |
principal component to plot on y-axis |
pcz |
principal component to plot on z-axis. If not NULL, function returns a 3-D PCA plot. |
ntop |
number of most-variable genes to use |
samples |
vector of sample names to show on plot |
loadings |
boolean, show gene loadings? Default is FALSE. |
loadings_ngenes |
integer, # genes to show loadings for (default=10) |
ggplot handle
# make example dds object dds <- DESeq2::makeExampleDESeqDataSet() # normalize rld <- DESeq2::varianceStabilizingTransformation(dds, blind=TRUE) # make pca plot p <- plotPCA.san(rld, intgroup='condition', pcx='PC1', pcy='PC2')# make example dds object dds <- DESeq2::makeExampleDESeqDataSet() # normalize rld <- DESeq2::varianceStabilizingTransformation(dds, blind=TRUE) # make pca plot p <- plotPCA.san(rld, intgroup='condition', pcx='PC1', pcy='PC2')
Plot a scatterplot to compare two contrasts
plotScatter.label( compare, df, label_x, label_y, lim.x, lim.y, color.palette, lab.genes = NULL, plot_all = "no", name.col = "geneid", lines = c("yes", "yes", "yes"), alpha = 1, size = 4, show.grid = "yes" )plotScatter.label( compare, df, label_x, label_y, lim.x, lim.y, color.palette, lab.genes = NULL, plot_all = "no", name.col = "geneid", lines = c("yes", "yes", "yes"), alpha = 1, size = 4, show.grid = "yes" )
compare |
string, what values to plot? can be 'log2FoldChange' or 'P-adj' |
df |
data frame with log2FoldChange & padj values to plot from 2 contrasts |
label_x |
string, label for x-axis |
label_y |
string, label for y-axis |
lim.x |
x-axis limits |
lim.y |
y-axis limits |
color.palette |
character vector of colors to use for significance categories 'Both - same LFC sign', 'Both - opposite LFC sign', 'None', label_x, label_y |
lab.genes |
genes to label (default=NULL) |
plot_all |
string, can be 'yes' or 'no'. if 'yes', points outside axis limits are plotted along x/y axis lines (default='no'). |
name.col |
gene name column to merge the 2 results, also used for labeling points |
lines |
3-element character vector to plot gridlines in the order (x=0, y=0, x=y), with 'yes' or 'no' values. E.g. ('yes', 'yes', 'no') will plot dotted lines for x = 0 & y = 0, but not the x = y diagonal. |
alpha |
float, marker opacity (default=1). |
size |
float, marker size (default=4). |
show.grid |
string, can be 'yes' (default) or 'no'. |
ggplot handle
# make mock results df n_genes <- 100 res1 <- data.frame( baseMean = runif(n_genes, 10, 1000), log2FoldChange = rnorm(n_genes, 0, 2), lfcSE = runif(n_genes, 0.1, 0.5), stat = rnorm(n_genes, 0, 3), pvalue = runif(n_genes, 0, 1), padj = runif(n_genes, 0, 1), symbol = paste0("GENE", 1:n_genes), row.names = paste0("gene", 1:n_genes) ) res2 <- data.frame( baseMean = runif(n_genes, 10, 1000), log2FoldChange = rnorm(n_genes, 0, 2), lfcSE = runif(n_genes, 0.1, 0.5), stat = rnorm(n_genes, 0, 3), pvalue = runif(n_genes, 0, 1), padj = runif(n_genes, 0, 1), symbol = paste0("GENE", 1:n_genes), row.names = paste0("gene", 1:n_genes) ) # add geneid column res1 <- cbind(geneid=rownames(res1), res1) res2 <- cbind(geneid=rownames(res2), res2) # make merged df from the two comparisons cols.sub <- c('log2FoldChange', 'padj', 'geneid') df_full <- dplyr::inner_join( dplyr::select(as.data.frame(res1), all_of(cols.sub)), dplyr::select(as.data.frame(res2), all_of(cols.sub)), by = 'geneid', suffix = c('.x', '.y') ) # calculate x & y limits for log2FoldChange xlim <- range(df_full[[ 'log2FoldChange.x' ]]) ylim <- range(df_full[[ 'log2FoldChange.y' ]]) # get color palette color.palette <- RColorBrewer::brewer.pal(n=5, name='Set2') # add significance column sig.x <- df_full$padj.x < 0.1 & !is.na(df_full$padj.x) sig.y <- df_full$padj.y < 0.1 & !is.na(df_full$padj.y) up.x <- df_full$log2FoldChange.x >= 0 up.y <- df_full$log2FoldChange.y >= 0 significance <- rep('None', nrow(df_full)) significance[ sig.x & sig.y & ((up.x & up.y) | (!up.x & !up.y)) ] <- 'Both - same LFC sign' significance[ sig.x & sig.y & ((up.x & !up.y) | (!up.x & up.y)) ] <- 'Both - opposite LFC sign' significance[ sig.x & !sig.y ] <- 'A vs B' significance[ !sig.x & sig.y ] <- 'B vs A' df_full$significance <- significance # generate scatter plot p <- plotScatter.label(compare = 'log2FoldChange', df = df_full, label_x = 'A vs B', label_y = 'B vs A', lim.x = xlim, lim.y = ylim, color.palette = color.palette)# make mock results df n_genes <- 100 res1 <- data.frame( baseMean = runif(n_genes, 10, 1000), log2FoldChange = rnorm(n_genes, 0, 2), lfcSE = runif(n_genes, 0.1, 0.5), stat = rnorm(n_genes, 0, 3), pvalue = runif(n_genes, 0, 1), padj = runif(n_genes, 0, 1), symbol = paste0("GENE", 1:n_genes), row.names = paste0("gene", 1:n_genes) ) res2 <- data.frame( baseMean = runif(n_genes, 10, 1000), log2FoldChange = rnorm(n_genes, 0, 2), lfcSE = runif(n_genes, 0.1, 0.5), stat = rnorm(n_genes, 0, 3), pvalue = runif(n_genes, 0, 1), padj = runif(n_genes, 0, 1), symbol = paste0("GENE", 1:n_genes), row.names = paste0("gene", 1:n_genes) ) # add geneid column res1 <- cbind(geneid=rownames(res1), res1) res2 <- cbind(geneid=rownames(res2), res2) # make merged df from the two comparisons cols.sub <- c('log2FoldChange', 'padj', 'geneid') df_full <- dplyr::inner_join( dplyr::select(as.data.frame(res1), all_of(cols.sub)), dplyr::select(as.data.frame(res2), all_of(cols.sub)), by = 'geneid', suffix = c('.x', '.y') ) # calculate x & y limits for log2FoldChange xlim <- range(df_full[[ 'log2FoldChange.x' ]]) ylim <- range(df_full[[ 'log2FoldChange.y' ]]) # get color palette color.palette <- RColorBrewer::brewer.pal(n=5, name='Set2') # add significance column sig.x <- df_full$padj.x < 0.1 & !is.na(df_full$padj.x) sig.y <- df_full$padj.y < 0.1 & !is.na(df_full$padj.y) up.x <- df_full$log2FoldChange.x >= 0 up.y <- df_full$log2FoldChange.y >= 0 significance <- rep('None', nrow(df_full)) significance[ sig.x & sig.y & ((up.x & up.y) | (!up.x & !up.y)) ] <- 'Both - same LFC sign' significance[ sig.x & sig.y & ((up.x & !up.y) | (!up.x & up.y)) ] <- 'Both - opposite LFC sign' significance[ sig.x & !sig.y ] <- 'A vs B' significance[ !sig.x & sig.y ] <- 'B vs A' df_full$significance <- significance # generate scatter plot p <- plotScatter.label(compare = 'log2FoldChange', df = df_full, label_x = 'A vs B', label_y = 'B vs A', lim.x = xlim, lim.y = ylim, color.palette = color.palette)
Plot an interactive scatterplot to compare two contrasts
plotScatter.label_ly( compare, df, label_x, label_y, lim.x, lim.y, color.palette, lab.genes = NULL, name.col = "geneid", lines = c("yes", "yes", "yes"), alpha = 1, size = 4, show.grid = "yes", source = "A" )plotScatter.label_ly( compare, df, label_x, label_y, lim.x, lim.y, color.palette, lab.genes = NULL, name.col = "geneid", lines = c("yes", "yes", "yes"), alpha = 1, size = 4, show.grid = "yes", source = "A" )
compare |
string, what values to plot? can be 'log2FoldChange' or 'P-adj' |
df |
data frame with log2FoldChange & padj values to plot from 2 contrasts |
label_x |
string, label for x-axis |
label_y |
string, label for y-axis |
lim.x |
x-axis limits |
lim.y |
y-axis limits |
color.palette |
character vector of colors to use for significance categories 'Both - same LFC sign', 'Both - opposite LFC sign', 'None', label_x, label_y |
lab.genes |
genes to label (default=NULL) |
name.col |
gene name column to merge the 2 results, also used for labeling points |
lines |
3-element character vector to plot gridlines in the order (x=0, y=0, x=y), with 'yes' or 'no' values. E.g. ('yes', 'yes', 'no') will plot dotted lines for x = 0 & y = 0, but not the x = y diagonal. |
alpha |
float, marker opacity (default=1). |
size |
float, marker size (default=4). |
show.grid |
string, can be 'yes' (default) or 'no'. |
source |
name of source to return event_data from |
plotly handle
# make mock results df n_genes <- 100 res1 <- data.frame( baseMean = runif(n_genes, 10, 1000), log2FoldChange = rnorm(n_genes, 0, 2), lfcSE = runif(n_genes, 0.1, 0.5), stat = rnorm(n_genes, 0, 3), pvalue = runif(n_genes, 0, 1), padj = runif(n_genes, 0, 1), symbol = paste0("GENE", 1:n_genes), row.names = paste0("gene", 1:n_genes) ) res2 <- data.frame( baseMean = runif(n_genes, 10, 1000), log2FoldChange = rnorm(n_genes, 0, 2), lfcSE = runif(n_genes, 0.1, 0.5), stat = rnorm(n_genes, 0, 3), pvalue = runif(n_genes, 0, 1), padj = runif(n_genes, 0, 1), symbol = paste0("GENE", 1:n_genes), row.names = paste0("gene", 1:n_genes) ) # add geneid column res1 <- cbind(geneid=rownames(res1), res1) res2 <- cbind(geneid=rownames(res2), res2) # make merged df from the two comparisons cols.sub <- c('log2FoldChange', 'padj', 'geneid') df_full <- dplyr::inner_join( dplyr::select(as.data.frame(res1), all_of(cols.sub)), dplyr::select(as.data.frame(res2), all_of(cols.sub)), by = 'geneid', suffix = c('.x', '.y') ) # calculate x & y limits for log2FoldChange xlim <- range(df_full[[ 'log2FoldChange.x' ]]) ylim <- range(df_full[[ 'log2FoldChange.y' ]]) # get color palette color.palette <- RColorBrewer::brewer.pal(n=5, name='Set2') # add significance column sig.x <- df_full$padj.x < 0.1 & !is.na(df_full$padj.x) sig.y <- df_full$padj.y < 0.1 & !is.na(df_full$padj.y) up.x <- df_full$log2FoldChange.x >= 0 up.y <- df_full$log2FoldChange.y >= 0 significance <- rep('None', nrow(df_full)) significance[ sig.x & sig.y & ((up.x & up.y) | (!up.x & !up.y)) ] <- 'Both - same LFC sign' significance[ sig.x & sig.y & ((up.x & !up.y) | (!up.x & up.y)) ] <- 'Both - opposite LFC sign' significance[ sig.x & !sig.y ] <- 'A vs B' significance[ !sig.x & sig.y ] <- 'B vs A' df_full$significance <- significance # generate scatter plot p <- plotScatter.label_ly(compare = 'log2FoldChange', df = df_full, label_x = 'A vs B', label_y = 'B vs A', lim.x = xlim, lim.y = ylim, color.palette = color.palette)# make mock results df n_genes <- 100 res1 <- data.frame( baseMean = runif(n_genes, 10, 1000), log2FoldChange = rnorm(n_genes, 0, 2), lfcSE = runif(n_genes, 0.1, 0.5), stat = rnorm(n_genes, 0, 3), pvalue = runif(n_genes, 0, 1), padj = runif(n_genes, 0, 1), symbol = paste0("GENE", 1:n_genes), row.names = paste0("gene", 1:n_genes) ) res2 <- data.frame( baseMean = runif(n_genes, 10, 1000), log2FoldChange = rnorm(n_genes, 0, 2), lfcSE = runif(n_genes, 0.1, 0.5), stat = rnorm(n_genes, 0, 3), pvalue = runif(n_genes, 0, 1), padj = runif(n_genes, 0, 1), symbol = paste0("GENE", 1:n_genes), row.names = paste0("gene", 1:n_genes) ) # add geneid column res1 <- cbind(geneid=rownames(res1), res1) res2 <- cbind(geneid=rownames(res2), res2) # make merged df from the two comparisons cols.sub <- c('log2FoldChange', 'padj', 'geneid') df_full <- dplyr::inner_join( dplyr::select(as.data.frame(res1), all_of(cols.sub)), dplyr::select(as.data.frame(res2), all_of(cols.sub)), by = 'geneid', suffix = c('.x', '.y') ) # calculate x & y limits for log2FoldChange xlim <- range(df_full[[ 'log2FoldChange.x' ]]) ylim <- range(df_full[[ 'log2FoldChange.y' ]]) # get color palette color.palette <- RColorBrewer::brewer.pal(n=5, name='Set2') # add significance column sig.x <- df_full$padj.x < 0.1 & !is.na(df_full$padj.x) sig.y <- df_full$padj.y < 0.1 & !is.na(df_full$padj.y) up.x <- df_full$log2FoldChange.x >= 0 up.y <- df_full$log2FoldChange.y >= 0 significance <- rep('None', nrow(df_full)) significance[ sig.x & sig.y & ((up.x & up.y) | (!up.x & !up.y)) ] <- 'Both - same LFC sign' significance[ sig.x & sig.y & ((up.x & !up.y) | (!up.x & up.y)) ] <- 'Both - opposite LFC sign' significance[ sig.x & !sig.y ] <- 'A vs B' significance[ !sig.x & sig.y ] <- 'B vs A' df_full$significance <- significance # generate scatter plot p <- plotScatter.label_ly(compare = 'log2FoldChange', df = df_full, label_x = 'A vs B', label_y = 'B vs A', lim.x = xlim, lim.y = ylim, color.palette = color.palette)
UI & module to generate radar plots.
radarUI(id, panel, type = "") radarServer(id, obj, config, type = "")radarUI(id, panel, type = "") radarServer(id, obj, config, type = "")
id |
Module id |
panel |
string, can be 'sidebar' or 'main' |
type |
string, if 'comp' then show the comparison view |
obj |
reactiveValues object containing GeneTonic object |
config |
reactive list with config settings |
UI returns tagList with plot UI server invisibly returns NULL (used for side effects)
library(shiny) # get enrichResult object data(eres_dex, package='carnation') # convert to GeneTonic object gt <- GeneTonic::shake_enrichResult(eres_dex) obj <- reactive({ list(l_gs = gt$l_gs, anno_df = gt$anno_df, label = 'comp1') }) config <- reactiveVal(get_config()) # run simple shiny app with plot if(interactive()){ shinyApp( ui = fluidPage( sidebarPanel(radarUI('p', 'sidebar')), mainPanel(radarUI('p', 'main')) ), server = function(input, output, session){ radarServer('p', obj, config) } ) }library(shiny) # get enrichResult object data(eres_dex, package='carnation') # convert to GeneTonic object gt <- GeneTonic::shake_enrichResult(eres_dex) obj <- reactive({ list(l_gs = gt$l_gs, anno_df = gt$anno_df, label = 'comp1') }) config <- reactiveVal(get_config()) # run simple shiny app with plot if(interactive()){ shinyApp( ui = fluidPage( sidebarPanel(radarUI('p', 'sidebar')), mainPanel(radarUI('p', 'main')) ), server = function(input, output, session){ radarServer('p', obj, config) } ) }
This function reads the access yaml file and returns user groups and data areas as a list of data frames.
read_access_yaml()read_access_yaml()
return carnation access settings from yaml file
# save access details to file home <- Sys.getenv('HOME') # create carnation data area if it doesn't exist carnation_home <- file.path(home, 'carnation/data') if(!dir.exists(carnation_home)) dir.create(carnation_home) create_access_yaml(user = 'admin', user_group = 'admin', data_area = carnation_home) al <- read_access_yaml()# save access details to file home <- Sys.getenv('HOME') # create carnation data area if it doesn't exist carnation_home <- file.path(home, 'carnation/data') if(!dir.exists(carnation_home)) dir.create(carnation_home) create_access_yaml(user = 'admin', user_group = 'admin', data_area = carnation_home) al <- read_access_yaml()
DESeqResults object testing the difference between
two cell lines of smooth muscle cellsA DESeqResults object testing the difference between
two cell lines of smooth muscle cells
A DESeqResults object, generated in the DESeq2 framework
This DESeqResults object on the data from the airway package
has been created comparing two smooth muscle cell lines,
accounting for the effect of dexamethasone treatment.
Details on how this object has been created are included in the
create_carnation_data.R script, included in the scripts folder of the
Carnation package.
Himes BE, Jiang X, Wagner P, Hu R, Wang Q, Klanderman B, Whitaker RM, Duan Q, Lasky-Su J, Nikolos C, Jester W, Johnson M, Panettieri R Jr, Tantisira KG, Weiss ST, Lu Q. “RNA-Seq Transcriptome Profiling Identifies CRISPLD2 as a Glucocorticoid Responsive Gene that Modulates Cytokine Function in Airway Smooth Muscle Cells.” PLoS One. 2014 Jun 13;9(6):e99625. PMID: 24926665. GEO: GSE52778
DESeqResults object testing the effect of dexamethasone
on smooth muscle cellsA DESeqResults object testing the effect of dexamethasone
on smooth muscle cells
A DESeqResults object, generated in the DESeq2 framework
This DESeqResults object on the data from the airway package
has been created comparing dexamethasone treated vs untreated samples,
accounting for the different cell lines included.
Details on how this object has been created are included in the
create_carnation_data.R script, included in the scripts folder of the
Carnation package.
Himes BE, Jiang X, Wagner P, Hu R, Wang Q, Klanderman B, Whitaker RM, Duan Q, Lasky-Su J, Nikolos C, Jester W, Johnson M, Panettieri R Jr, Tantisira KG, Weiss ST, Lu Q. “RNA-Seq Transcriptome Profiling Identifies CRISPLD2 as a Glucocorticoid Responsive Gene that Modulates Cytokine Function in Airway Smooth Muscle Cells.” PLoS One. 2014 Jun 13;9(6):e99625. PMID: 24926665. GEO: GSE52778
Interactive shiny dashboard for exploring RNA-Seq analysis.
run_carnation( credentials = NULL, passphrase = NULL, enable_admin = TRUE, config_path = NULL, ... )run_carnation( credentials = NULL, passphrase = NULL, enable_admin = TRUE, config_path = NULL, ... )
credentials |
path to encrypted sqlite db with user credentials. |
passphrase |
passphrase for credentials db. |
enable_admin |
if TRUE, admin view is shown. Note, this is only available if credentials have sqlite backend. |
config_path |
optional path to a local config yaml override. |
... |
parameters passed to shinyApp() call |
shinyApp object
if(interactive()){ shiny::runApp( run_carnation() ) }if(interactive()){ shiny::runApp( run_carnation() ) }
This function saves access details (user groups and data areas) to the designated access yaml file.
save_access_yaml(lst)save_access_yaml(lst)
lst |
list of data frames with user_groups and data_areas |
save access settings to yaml file
# save access details to file home <- Sys.getenv('HOME') # create carnation data area if it doesn't exist carnation_home <- file.path(home, 'carnation/data') if(!dir.exists(carnation_home)) dir.create(carnation_home) create_access_yaml(user = 'admin', user_group = 'admin', data_area = carnation_home) # read access yaml lst <- read_access_yaml() # add new user lst$user_group$admin <- c(lst$user_group$admin, 'user1') # save to access settings save_access_yaml(lst)# save access details to file home <- Sys.getenv('HOME') # create carnation data area if it doesn't exist carnation_home <- file.path(home, 'carnation/data') if(!dir.exists(carnation_home)) dir.create(carnation_home) create_access_yaml(user = 'admin', user_group = 'admin', data_area = carnation_home) # read access yaml lst <- read_access_yaml() # add new user lst$user_group$admin <- c(lst$user_group$admin, 'user1') # save to access settings save_access_yaml(lst)
Module UI & server to save carnation object.
saveUI(id) saveServer(id, original, current, coldata, pattern, username, config)saveUI(id) saveServer(id, original, current, coldata, pattern, username, config)
id |
Module id |
original |
original carnation object |
current |
current carnation object |
coldata |
reactiveValues object containing object metadata |
pattern |
regex pattern for finding carnation data |
username |
user name |
config |
reactive list with config settings |
UI returns actionButton Server returns reactive with trigger to refresh the app
library(shiny) library(DESeq2) # default username username <- reactive({ NULL }) # internal carnation config config <- reactiveVal(get_config()) # regex to find carnation files pattern <- reactive({ config()$server$pattern }) # get example object obj <- make_example_carnation_object() # make reactive with obj & path original <- reactiveValues( obj = obj, path = "/path/to/carnation/obj.rds" ) # extract metadata coldata <- reactive({ lapply(obj$dds, colData) }) # edit metadata coldata_edit <- lapply(coldata, function(x){ x$type <- 'new'; x }) # add to object edit_obj <- obj for(name in names(edit_obj$dds)){ colData(edit_obj$dds[[ name ]]) <- coldata_edit[[ name ]] } # run simple shiny app with plot shinyApp( ui = fluidPage( saveUI('p') ), server = function(input, output, session){ save_event <- saveServer('save_object', original=original, current=reactive({ edit_obj }), coldata=coldata, pattern=pattern(), username=username, config) } )library(shiny) library(DESeq2) # default username username <- reactive({ NULL }) # internal carnation config config <- reactiveVal(get_config()) # regex to find carnation files pattern <- reactive({ config()$server$pattern }) # get example object obj <- make_example_carnation_object() # make reactive with obj & path original <- reactiveValues( obj = obj, path = "/path/to/carnation/obj.rds" ) # extract metadata coldata <- reactive({ lapply(obj$dds, colData) }) # edit metadata coldata_edit <- lapply(coldata, function(x){ x$type <- 'new'; x }) # add to object edit_obj <- obj for(name in names(edit_obj$dds)){ colData(edit_obj$dds[[ name ]]) <- coldata_edit[[ name ]] } # run simple shiny app with plot shinyApp( ui = fluidPage( saveUI('p') ), server = function(input, output, session){ save_event <- saveServer('save_object', original=original, current=reactive({ edit_obj }), coldata=coldata, pattern=pattern(), username=username, config) } )
Module UI + server for generating scatter plots.
scatterPlotUI(id, panel) scatterPlotServer(id, obj, plot_args, gene_scratchpad, reset_genes, config)scatterPlotUI(id, panel) scatterPlotServer(id, obj, plot_args, gene_scratchpad, reset_genes, config)
id |
Module id |
panel |
string, can be 'sidebar' or 'main' passed to UI |
obj |
reactiveValues object containing carnation object passed to server |
plot_args |
reactive containing 'fdr.thres' (padj threshold), 'fc.thres' (log2FC) |
gene_scratchpad |
reactive containing gene scratchpad genes |
reset_genes |
reactive to reset gene scratchpad selection |
config |
reactive list with config settings passed to server |
UI returns tagList with scatter plot UI. Server invisibly returns NULL (used for side effects).
library(shiny) # Create reactive values to simulate app state oobj <- make_example_carnation_object() obj <- reactiveValues( dds = oobj$dds, rld = oobj$rld, res = oobj$res, all_dds = oobj$all_dds, all_rld = oobj$all_rld, dds_mapping = oobj$dds_mapping ) plot_args <- reactive({ list( fdr.thres=0.1, fc.thres=0 ) }) gene_scratchpad <- reactive({ c('gene1', 'gene2') }) reset_genes <- reactiveVal() config <- reactiveVal(get_config()) shinyApp( ui = fluidPage( sidebarPanel(scatterPlotUI('p', 'sidebar')), mainPanel(scatterPlotUI('p', 'sidebar')) ), server = function(input, output, session){ scatter_data <- scatterPlotServer('p', obj, plot_args, gene_scratchpad, reset_genes, config) } )library(shiny) # Create reactive values to simulate app state oobj <- make_example_carnation_object() obj <- reactiveValues( dds = oobj$dds, rld = oobj$rld, res = oobj$res, all_dds = oobj$all_dds, all_rld = oobj$all_rld, dds_mapping = oobj$dds_mapping ) plot_args <- reactive({ list( fdr.thres=0.1, fc.thres=0 ) }) gene_scratchpad <- reactive({ c('gene1', 'gene2') }) reset_genes <- reactiveVal() config <- reactiveVal(get_config()) shinyApp( ui = fluidPage( sidebarPanel(scatterPlotUI('p', 'sidebar')), mainPanel(scatterPlotUI('p', 'sidebar')) ), server = function(input, output, session){ scatter_data <- scatterPlotServer('p', obj, plot_args, gene_scratchpad, reset_genes, config) } )
This function updates a limited subset of the package config YAML. Only stable user-facing settings are writable; style settings and other internal options are intentionally left untouched.
set_config( config_path = get_config_path(), de_analysis = NULL, fdr_threshold = NULL, log2fc_threshold = NULL, max_upload_size = NULL, cores = NULL, pattern = NULL )set_config( config_path = get_config_path(), de_analysis = NULL, fdr_threshold = NULL, log2fc_threshold = NULL, max_upload_size = NULL, cores = NULL, pattern = NULL )
config_path |
character path to the config YAML file to update.
Defaults to the local config returned by |
de_analysis |
optional list with DE analysis config updates.
Currently only |
fdr_threshold |
optional numeric FDR threshold between 0 and 1. |
log2fc_threshold |
optional numeric log2 fold-change threshold greater than or equal to 0. |
max_upload_size |
optional positive numeric upload limit in MB. |
cores |
optional positive integer number of cores to use. |
pattern |
optional character suffix pattern used to match dataset
filenames before the trailing |
Updated config list, invisibly.
cfg_out <- tempfile(fileext = ".yaml") set_config( config_path = cfg_out, de_analysis = list( column_names = list( padj = "qvalue", log2FoldChange = c("logFC", "avg_log2FC") ) ), fdr_threshold = 0.05, log2fc_threshold = 1, max_upload_size = 50, cores = 2, pattern = "carnation" )cfg_out <- tempfile(fileext = ".yaml") set_config( config_path = cfg_out, de_analysis = list( column_names = list( padj = "qvalue", log2FoldChange = c("logFC", "avg_log2FC") ) ), fdr_threshold = 0.05, log2fc_threshold = 1, max_upload_size = 50, cores = 2, pattern = "carnation" )
Module UI & server for user access details interface.
Server code for settings module
settingsUI(id, panel, username) settingsServer(id, details, depth, end_offset, assay_fun, config)settingsUI(id, panel, username) settingsServer(id, details, depth, end_offset, assay_fun, config)
id |
Module id |
panel |
context for generating ui elements ('sidebar' or 'main') |
username |
user name |
details |
reactive list with user name & app location details |
depth |
project name depth |
end_offset |
project name end offset |
assay_fun |
function to parse assay names from file path |
config |
reactive list with config settings |
UI returns tagList with module UI Server returns reactive with list containing user access details
library(shiny) # default username username <- reactive({ NULL }) # internal carnation config config <- reactiveVal(get_config()) # regex to find carnation files pattern <- reactive({ config()$server$pattern }) # access permissions assay.list <- reactiveValues(l=read_access_yaml()) if(interactive()){ shinyApp( ui = fluidPage( sidebarPanel(uiOutput('settings_sidebar')), mainPanel(uiOutput('settings_main')) ), server = function(input, output, session){ output$settings_main <- renderUI({ settingsUI('settings', panel='main', username=username) }) output$settings_sidebar <- renderUI({ settingsUI('settings', panel='sidebar', username=username) }) settings <- settingsServer('p', details=reactive({ list(username=username, where=NULL) }), depth=2, end_offset=0, assay_fun=function(x) sub(paste0(pattern(), '\\.rds$'), '', basename(x), ignore.case=TRUE), config ) } ) }library(shiny) # default username username <- reactive({ NULL }) # internal carnation config config <- reactiveVal(get_config()) # regex to find carnation files pattern <- reactive({ config()$server$pattern }) # access permissions assay.list <- reactiveValues(l=read_access_yaml()) if(interactive()){ shinyApp( ui = fluidPage( sidebarPanel(uiOutput('settings_sidebar')), mainPanel(uiOutput('settings_main')) ), server = function(input, output, session){ output$settings_main <- renderUI({ settingsUI('settings', panel='main', username=username) }) output$settings_sidebar <- renderUI({ settingsUI('settings', panel='sidebar', username=username) }) settings <- settingsServer('p', details=reactive({ list(username=username, where=NULL) }), depth=2, end_offset=0, assay_fun=function(x) sub(paste0(pattern(), '\\.rds$'), '', basename(x), ignore.case=TRUE), config ) } ) }
Combine everything in the results list into a single table
summarize_res_list( res.list, dds.list, dds_mapping, alpha, lfc.thresh, labels = NULL )summarize_res_list( res.list, dds.list, dds_mapping, alpha, lfc.thresh, labels = NULL )
res.list |
Named list of lists, where each sublist contains the following names: c('res', 'dds', 'label'). "res" is a DESeqResults object, "dds" is either the indexing label for the dds.list object or the DESeq object, and "label" is a nicer-looking label to use. NOTE: backwards compatibility with older versions of lcdb-wf depends on no dds.list object being passed. |
dds.list |
List of DESeqDataSet objects whose names are expected to match 'dds' slots in the 'res.list' object |
dds_mapping |
List mapping names of dds.list to res.list elements |
alpha |
false-discovery rate threshold |
lfc.thresh |
log2FoldChange threshold |
labels |
list of descriptions for res.list elements |
Dataframe
n_genes <- 100 # make mock dds list dds_list <- list(main=DESeq2::makeExampleDESeqDataSet(n=n_genes)) # make mock results df res1 <- data.frame( baseMean = runif(n_genes, 10, 1000), log2FoldChange = rnorm(n_genes, 0, 2), lfcSE = runif(n_genes, 0.1, 0.5), stat = rnorm(n_genes, 0, 3), pvalue = runif(n_genes, 0, 1), padj = runif(n_genes, 0, 1), symbol = paste0("GENE", 1:n_genes), row.names = paste0("gene", 1:n_genes) ) res2 <- data.frame( baseMean = runif(n_genes, 10, 1000), log2FoldChange = rnorm(n_genes, 0, 2), lfcSE = runif(n_genes, 0.1, 0.5), stat = rnorm(n_genes, 0, 3), pvalue = runif(n_genes, 0, 1), padj = runif(n_genes, 0, 1), symbol = paste0("GENE", 1:n_genes), row.names = paste0("gene", 1:n_genes) ) # make list of results res_list <- list( comp1=res1, comp2=res2 ) # make dds mapping dds_mapping <- list(comp1='main', comp2='main') # get summary df <- summarize_res_list(res_list, dds_list, dds_mapping, alpha=0.1, lfc.thresh=0)n_genes <- 100 # make mock dds list dds_list <- list(main=DESeq2::makeExampleDESeqDataSet(n=n_genes)) # make mock results df res1 <- data.frame( baseMean = runif(n_genes, 10, 1000), log2FoldChange = rnorm(n_genes, 0, 2), lfcSE = runif(n_genes, 0.1, 0.5), stat = rnorm(n_genes, 0, 3), pvalue = runif(n_genes, 0, 1), padj = runif(n_genes, 0, 1), symbol = paste0("GENE", 1:n_genes), row.names = paste0("gene", 1:n_genes) ) res2 <- data.frame( baseMean = runif(n_genes, 10, 1000), log2FoldChange = rnorm(n_genes, 0, 2), lfcSE = runif(n_genes, 0.1, 0.5), stat = rnorm(n_genes, 0, 3), pvalue = runif(n_genes, 0, 1), padj = runif(n_genes, 0, 1), symbol = paste0("GENE", 1:n_genes), row.names = paste0("gene", 1:n_genes) ) # make list of results res_list <- list( comp1=res1, comp2=res2 ) # make dds mapping dds_mapping <- list(comp1='main', comp2='main') # get summary df <- summarize_res_list(res_list, dds_list, dds_mapping, alpha=0.1, lfc.thresh=0)
UI & module to generate summary overview plots.
sumovPlotUI(id, panel, type = "") sumovPlotServer(id, obj, config, type = "")sumovPlotUI(id, panel, type = "") sumovPlotServer(id, obj, config, type = "")
id |
Module id |
panel |
string, can be 'sidebar' or 'main' |
type |
string, if 'comp' then show the comparison view |
obj |
reactiveValues object containing GeneTonic object |
config |
reactive list with config settings |
UI returns tagList with plot UI server invisibly returns NULL (used for side effects)
library(shiny) # get enrichResult object data(eres_dex, package='carnation') # convert to GeneTonic object gt <- GeneTonic::shake_enrichResult(eres_dex) obj <- reactive({ list(l_gs = gt$l_gs, anno_df = gt$anno_df, label = 'comp1') }) config <- reactiveVal(get_config()) # run simple shiny app with plot if(interactive()){ shinyApp( ui = fluidPage( sidebarPanel(sumovPlotUI('p', 'sidebar')), mainPanel(sumovPlotUI('p', 'main')) ), server = function(input, output, session){ sumovPlotServer('p', obj, config) } ) }library(shiny) # get enrichResult object data(eres_dex, package='carnation') # convert to GeneTonic object gt <- GeneTonic::shake_enrichResult(eres_dex) obj <- reactive({ list(l_gs = gt$l_gs, anno_df = gt$anno_df, label = 'comp1') }) config <- reactiveVal(get_config()) # run simple shiny app with plot if(interactive()){ shinyApp( ui = fluidPage( sidebarPanel(sumovPlotUI('p', 'sidebar')), mainPanel(sumovPlotUI('p', 'main')) ), server = function(input, output, session){ sumovPlotServer('p', obj, config) } ) }
Get top DE genes by log2FoldChange or adjusted p-value
top.genes(res, fdr.thres = 0.01, fc.thres = 0, n = 10, by = "log2FoldChange")top.genes(res, fdr.thres = 0.01, fc.thres = 0, n = 10, by = "log2FoldChange")
res |
data.frame with DE analysis results |
fdr.thres |
FDR threshold |
fc.thres |
log2FoldChange threshold |
n |
number of genes to return |
by |
metric to determine top genes ('log2FoldChange' or 'padj') |
vector of gene symbols
# get DE results data(res_dex, package='carnation') g <- top.genes(res_dex)# get DE results data(res_dex, package='carnation') g <- top.genes(res_dex)
Module UI & server to generate upset plots.
upsetPlotUI(id, panel) upsetPlotServer(id, obj, plot_args, gene_scratchpad, reset_genes, config)upsetPlotUI(id, panel) upsetPlotServer(id, obj, plot_args, gene_scratchpad, reset_genes, config)
id |
Module id |
panel |
string, can be 'sidebar' or 'main' |
obj |
reactiveValues object containing carnation object |
plot_args |
reactive containing 'fdr.thres' (padj threshold) & 'fc.thres' (log2FC) |
gene_scratchpad |
reactiveValues object containing genes selected in scratchpad |
reset_genes |
reactive to reset gene scratchpad selection |
config |
reactive list with config settings |
UI returns tagList with upset plot UI. Server returns reactive with list containing upset table, intersections & selected genes.
library(shiny) oobj <- make_example_carnation_object() obj <- reactiveValues( dds = oobj$dds, rld = oobj$rld, res = oobj$res, all_dds = oobj$all_dds, all_rld = oobj$all_rld, dds_mapping = oobj$dds_mapping ) plot_args <- reactive({ list( fdr.thres=0.1, fc.thres=0 ) }) gene_scratchpad <- reactive({ c('gene1', 'gene2') }) reset_genes <- reactiveVal() config <- reactiveVal(get_config()) shinyApp( ui = fluidPage( sidebarPanel(upsetPlotUI('p', 'sidebar')), mainPanel(upsetPlotUI('p', 'sidebar')) ), server = function(input, output, session){ upset_data <- upsetPlotServer('p', obj, plot_args, gene_scratchpad, reset_genes, config) } )library(shiny) oobj <- make_example_carnation_object() obj <- reactiveValues( dds = oobj$dds, rld = oobj$rld, res = oobj$res, all_dds = oobj$all_dds, all_rld = oobj$all_rld, dds_mapping = oobj$dds_mapping ) plot_args <- reactive({ list( fdr.thres=0.1, fc.thres=0 ) }) gene_scratchpad <- reactive({ c('gene1', 'gene2') }) reset_genes <- reactiveVal() config <- reactiveVal(get_config()) shinyApp( ui = fluidPage( sidebarPanel(upsetPlotUI('p', 'sidebar')), mainPanel(upsetPlotUI('p', 'sidebar')) ), server = function(input, output, session){ upset_data <- upsetPlotServer('p', obj, plot_args, gene_scratchpad, reset_genes, config) } )
This function takes various input data types (DE results, counts, enrichment,
pattern analysis) and validates them according to carnation's requirements,
returning a normalized intermediate object. Expensive derived-object
creation steps such as variance-stabilized counts and GeneTonic conversion
are handled separately by materialize_carnation_object().
validate_carnation_object( res_list, dds_list, rld_list = NULL, labels = NULL, enrich_list = NULL, degpatterns = NULL, metadata = NULL, dds_mapping = NULL, config = NULL )validate_carnation_object( res_list, dds_list, rld_list = NULL, labels = NULL, enrich_list = NULL, degpatterns = NULL, metadata = NULL, dds_mapping = NULL, config = NULL )
res_list |
Named list of DE results. Each element should be either:
|
dds_list |
Named list of count data. Each element should be either:
|
rld_list |
Optional named list of variance-stabilized count objects.
If NULL, these can be generated later via
|
labels |
Optional named list of comparison labels. If NULL and res_list
contains nested structure with |
enrich_list |
Optional named list of functional enrichment results.
Should be structured as:
|
degpatterns |
Optional named list of pattern analysis results. Each
element should be either a data frame or a list with |
metadata |
Optional data frame with sample metadata. Required if
|
dds_mapping |
Optional named list mapping |
config |
Optional config list. If NULL, will use |
This function performs comprehensive validation of all input data:
DE results: Checks for required columns (with support for DESeq2, edgeR, limma), ensures gene and symbol columns exist
Counts: Validates structure, checks sample name matching with metadata
Enrichment: Validates clusterProfiler format (OR or GSEA)
Pattern analysis: Checks for required columns (genes, value, cluster)
If validation fails, the function will stop with an informative error message.
A validated list with canonical slots res_list,
dds_list, optional rld_list, labels,
dds_mapping, enrich_list, degpatterns, and
metadata when supplied.
A list containing normalized inputs with elements
res_list, dds_list, optional rld_list,
labels, dds_mapping, and optional enrich_list,
degpatterns, and metadata.
# Minimal example with DE results and counts library(DESeq2) # Create example data dds <- makeExampleDESeqDataSet() dds <- DESeq(dds) res <- results(dds, contrast = c("condition", "A", "B")) rld <- varianceStabilizingTransformation(dds, blind = TRUE) # Validate object inputs obj <- validate_carnation_object( res_list = list( comp1 = list( res = as.data.frame(res), dds = "main", label = "A vs B" ) ), dds_list = list(main = dds), rld_list = list(main = rld) ) materialized <- materialize_carnation_object(obj, cores = 1) final_obj <- make_final_object(materialized) # Save for use with carnation saveRDS(final_obj, "my_analysis.rds") # Alternative: start from count matrix and metadata counts <- as.data.frame(counts(dds)) counts$gene <- rownames(counts) counts <- counts[, c(ncol(counts), 1:(ncol(counts)-1))] metadata <- as.data.frame(colData(dds)) metadata$sample <- rownames(metadata) metadata <- metadata[, c(ncol(metadata), 1:(ncol(metadata)-1))] obj <- validate_carnation_object( res_list = list(comp1 = as.data.frame(res)), dds_list = list(main = counts), metadata = metadata, dds_mapping = list(comp1 = "main") )# Minimal example with DE results and counts library(DESeq2) # Create example data dds <- makeExampleDESeqDataSet() dds <- DESeq(dds) res <- results(dds, contrast = c("condition", "A", "B")) rld <- varianceStabilizingTransformation(dds, blind = TRUE) # Validate object inputs obj <- validate_carnation_object( res_list = list( comp1 = list( res = as.data.frame(res), dds = "main", label = "A vs B" ) ), dds_list = list(main = dds), rld_list = list(main = rld) ) materialized <- materialize_carnation_object(obj, cores = 1) final_obj <- make_final_object(materialized) # Save for use with carnation saveRDS(final_obj, "my_analysis.rds") # Alternative: start from count matrix and metadata counts <- as.data.frame(counts(dds)) counts$gene <- rownames(counts) counts <- counts[, c(ncol(counts), 1:(ncol(counts)-1))] metadata <- as.data.frame(colData(dds)) metadata$sample <- rownames(metadata) metadata <- metadata[, c(ncol(metadata), 1:(ncol(metadata)-1))] obj <- validate_carnation_object( res_list = list(comp1 = as.data.frame(res)), dds_list = list(main = counts), metadata = metadata, dds_mapping = list(comp1 = "main") )