diff --git a/.Rbuildignore b/.Rbuildignore index 31e3754..6a1fadf 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -2,3 +2,6 @@ ^\.Rproj\.user$ ^LICENSE\.md$ ^\.github$ +^_pkgdown\.yml$ +^docs$ +^pkgdown$ diff --git a/DESCRIPTION b/DESCRIPTION index 5daf4f4..c91d5ec 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: iSEEfier Title: Streamlining the creation of initial states for starting an iSEE instance -Version: 0.2.0 +Version: 0.99.0 Authors@R: c( person(given = "Najla", family = "Abassi", role = c("aut", "cre"), @@ -32,12 +32,14 @@ Imports: rlang, stats, SummarizedExperiment, + SingleCellExperiment, visNetwork Suggests: knitr, rmarkdown, scater, scRNAseq, + org.Mm.eg.db, scuttle, BiocStyle, testthat (>= 3.0.0) diff --git a/NAMESPACE b/NAMESPACE index 796c96f..2edfa9a 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -11,6 +11,7 @@ importClassesFrom(iSEE,FeatureAssayPlot) importClassesFrom(iSEE,ReducedDimensionPlot) importClassesFrom(iSEE,RowDataTable) importClassesFrom(iSEEu,MarkdownBoard) +importFrom(SingleCellExperiment,reducedDimNames) importFrom(SummarizedExperiment,colData) importFrom(ggplot2,aes) importFrom(ggplot2,geom_tile) @@ -27,6 +28,7 @@ importFrom(igraph,"V<-") importFrom(igraph,V) importFrom(igraph,graph.empty) importFrom(igraph,graph_from_data_frame) +importFrom(methods,is) importFrom(methods,new) importFrom(rlang,.data) importFrom(stats,na.omit) diff --git a/NEWS.md b/NEWS.md index af16f64..3548622 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,12 @@ +# iSEEfier 0.99.0 + +* Ready for Bioconductor submission! + +# iSEEfier 0.3.0 + +* Main functions are equipped with extra parameters determining their behavior +* Unit test suite is fully in! + # iSEEfier 0.2.0 * Functions renamed to the final version, in a more matching and descriptive manner diff --git a/R/iSEEfier.R b/R/iSEEfier.R index 45ea5c7..d72c023 100644 --- a/R/iSEEfier.R +++ b/R/iSEEfier.R @@ -1,5 +1,5 @@ #' iSEEinit: Create an initial state of an iSEE instance for gene expression visualization -#' +#' #' `iSEEinit()` defines the initial setup of an iSEE instance, recommending tailored visual elements to effortlessly illustrate the expression of a gene list in a single view. #' #' @param sce SingleCellExperiment object @@ -14,13 +14,15 @@ #' @export #' @importFrom methods new #' @importFrom SummarizedExperiment colData +#' @importFrom SingleCellExperiment reducedDimNames +#' @importFrom methods is #' @importClassesFrom iSEE ColumnDataPlot #' @importClassesFrom iSEE ReducedDimensionPlot #' @importClassesFrom iSEE FeatureAssayPlot #' @importClassesFrom iSEE RowDataTable #' @importClassesFrom iSEE ComplexHeatmapPlot #' @importClassesFrom iSEEu MarkdownBoard -#' +#' #' #' @examples #' sce <- scRNAseq::RichardTCellData() @@ -38,92 +40,169 @@ iSEEinit <- function(sce, groups = colnames(colData(sce))[1], markdownboard = FALSE, dynamicMarkerTable = FALSE) { + + ## Checks on arguments + if (!is(sce, "SingleCellExperiment")) + stop("Please provide a SingleCellExperiment as input!") + + stopifnot(is.character(feature.list)) + stopifnot(length(feature.list) > 0) + + stopifnot(is.character(reddim.type)) + stopifnot(length(reddim.type) == 1) + + stopifnot(is.character(clusters)) + stopifnot(length(clusters) == 1) + + stopifnot(is.character(groups)) + stopifnot(length(groups) == 1) + + stopifnot(is.logical(markdownboard)) + stopifnot(length(markdownboard) == 1) + stopifnot(is.logical(dynamicMarkerTable)) + stopifnot(length(dynamicMarkerTable) == 1) + + if (!(reddim.type %in% reducedDimNames(sce))) { + available_reddims <- reducedDimNames(sce) + stop("The selected reduced dimensionality embedding is not available!\n", + "Please select one of these: ", + paste(available_reddims, collapse = ", ")) + } + + if (!all(feature.list %in% rownames(sce))) { + not_available_features <- feature.list[!feature.list %in% rownames(sce)] + message("Some of the features specified are not available in the provided sce object!\n", + "Feature(s) not found: ", + paste(not_available_features, collapse = ", ")) + + feature.list <- feature.list[feature.list %in% rownames(sce)] + if (length(feature.list) == 0) + stop("No features available!") + } + + if (!(clusters %in% colnames(colData(sce)))) { + if (ncol(colData(sce)) > 0) { + fallback_clusters <- colnames(colData(sce))[1] + } else { + stop("No colData provided for the `clusters`!") + } + + message("colData column not found for the `clusters` parameter, defaulting to ", + fallback_clusters) + } + + if (!(groups %in% colnames(colData(sce)))) { + if (ncol(colData(sce)) > 0) { + fallback_groups <- colnames(colData(sce))[1] + } else { + stop("No colData provided for the `groups`!") + } + + message("colData column not found for the `groups` parameter, defaulting to ", + fallback_groups) + } + + + + initial <- list() - feature.list <- as.list(feature.list) - clusters <- as.character(clusters) - group <- as.character(groups) - - + ## TODO: do we need this to be enforced as list? + # feature.list <- as.list(feature.list) + # clusters <- as.character(clusters) + # groups <- as.character(groups) + + for (j in feature.list) { - initial[[paste0("ReducedDimensionPlot", which(feature.list == j))]] <- new("ReducedDimensionPlot", - Type = reddim.type, - ColorBy = "Feature name", - ColorByFeatureName = j, - ColorByFeatureSource = paste0("RowDataTable", which(feature.list == j)), - ColumnSelectionSource = "ColumnDataPlot1", - SelectionAlpha = 0.05 + initial[[paste0("ReducedDimensionPlot", which(feature.list == j))]] <- new( + "ReducedDimensionPlot", + Type = reddim.type, + ColorBy = "Feature name", + ColorByFeatureName = j, + ColorByFeatureSource = paste0("RowDataTable", which(feature.list == j)), + ColumnSelectionSource = "ColumnDataPlot1", + SelectionAlpha = 0.05 ) - - initial[[paste0("FeatureAssayPlot", which(feature.list == j))]] <- new("FeatureAssayPlot", - XAxis = "Column data", - XAxisColumnData = clusters, - YAxisFeatureName = j, - YAxisFeatureSource = paste0("RowDataTable", which(feature.list == j)), - ColorBy = "Column data", - ColorByColumnData = clusters + + initial[[paste0("FeatureAssayPlot", which(feature.list == j))]] <- new( + "FeatureAssayPlot", + XAxis = "Column data", + XAxisColumnData = clusters, + YAxisFeatureName = j, + YAxisFeatureSource = paste0("RowDataTable", which(feature.list == j)), + ColorBy = "Column data", + ColorByColumnData = clusters ) - - initial[[paste0("RowDataTable", which(feature.list == j))]] <- new("RowDataTable", - Selected = j, - Search = j + + initial[[paste0("RowDataTable", which(feature.list == j))]] <- new( + "RowDataTable", + Selected = j, + Search = j ) } - + if (length(feature.list) > 1) { - initial[[paste0("FeatureAssayPlot", length(feature.list) + 1)]] <- new("FeatureAssayPlot", - XAxis = "Feature name", - XAxisFeatureName = feature.list[[1]], - YAxisFeatureName = feature.list[[2]] + initial[[paste0("FeatureAssayPlot", length(feature.list) + 1)]] <- new( + "FeatureAssayPlot", + XAxis = "Feature name", + XAxisFeatureName = feature.list[[1]], + YAxisFeatureName = feature.list[[2]] ) } - - initial[[paste0("ReducedDimensionPlot", length(feature.list) + 1)]] <- new("ReducedDimensionPlot", - Type = reddim.type, - ColorByColumnData = clusters, - ColorBy = "Column data", - ColumnSelectionSource = paste0("FeatureAssayPlot", length(feature.list) + 1), - FacetColumnBy = "Column data", - FacetColumnByColData = group, - SelectionAlpha = 0.05 + + initial[[paste0("ReducedDimensionPlot", length(feature.list) + 1)]] <- new( + "ReducedDimensionPlot", + Type = reddim.type, + ColorByColumnData = clusters, + ColorBy = "Column data", + ColumnSelectionSource = paste0("FeatureAssayPlot", length(feature.list) + 1), + FacetColumnBy = "Column data", + FacetColumnByColData = groups, + SelectionAlpha = 0.05 ) - - - initial[["ComplexHeatmapPlot1"]] <- new("ComplexHeatmapPlot", - CustomRowsText = paste(feature.list, collapse = "\n"), - ColumnData = clusters + + + initial[["ComplexHeatmapPlot1"]] <- new( + "ComplexHeatmapPlot", + CustomRowsText = paste(feature.list, collapse = "\n"), + ColumnData = clusters ) - - initial[["ColumnDataPlot1"]] <- new("ColumnDataPlot", - YAxis = clusters, - ColorBy = "Column data", - ColorByColumnData = clusters, - PanelWidth = 6L + + initial[["ColumnDataPlot1"]] <- new( + "ColumnDataPlot", + YAxis = clusters, + ColorBy = "Column data", + ColorByColumnData = clusters, + PanelWidth = 6L ) - + if (markdownboard == TRUE) { - initial[["MarkdownBoard1"]] <- new("MarkdownBoard", - Content = "# Placeholder\n\nFill me with text!", - PanelWidth = 4L) + initial[["MarkdownBoard1"]] <- new( + "MarkdownBoard", + Content = "# Placeholder\n\nFill me with text!", + PanelWidth = 4L) } - + if(dynamicMarkerTable == TRUE) { - initial[[paste0("ReducedDimensionPlot",length(feature.list)+2)]] <- new("ReducedDimensionPlot", - Type = reddim.type, - ColorByColumnData = clusters, - ColorBy = "Column data", - SelectionAlpha = 0.05, - ColumnSelectionSource = paste0("FeatureAssayPlot",length(feature.list)+2)) - - - initial[["DynamicMarkerTable1"]] <- new("DynamicMarkerTable", - ColumnSelectionSource = paste0("ReducedDimensionPlot",length(feature.list)+2)) - - initial[[paste0("FeatureAssayPlot",length(feature.list)+2)]] <- new("FeatureAssayPlot", - XAxis = "Column data", - XAxisColumnData = group, - YAxisFeatureSource = "DynamicMarkerTable1") + initial[[paste0("ReducedDimensionPlot",length(feature.list)+2)]] <- new( + "ReducedDimensionPlot", + Type = reddim.type, + ColorByColumnData = clusters, + ColorBy = "Column data", + SelectionAlpha = 0.05, + ColumnSelectionSource = paste0("FeatureAssayPlot",length(feature.list)+2)) + + + initial[["DynamicMarkerTable1"]] <- new( + "DynamicMarkerTable", + ColumnSelectionSource = paste0("ReducedDimensionPlot",length(feature.list)+2)) + + initial[[paste0("FeatureAssayPlot",length(feature.list)+2)]] <- new( + "FeatureAssayPlot", + XAxis = "Column data", + XAxisColumnData = groups, + YAxisFeatureSource = "DynamicMarkerTable1") } - + return(initial) - -} \ No newline at end of file + +} diff --git a/R/iSEEnrich.R b/R/iSEEnrich.R index dd1486d..9e87896 100644 --- a/R/iSEEnrich.R +++ b/R/iSEEnrich.R @@ -1,12 +1,12 @@ #' iSEEnrich -#' +#' #' `iSEEnrich()` creates an initial state of an iSEE instance for interactive exploration of feature sets extracted from GO and KEGG database, #' displaying all associated genes in a `RowDataTable` panel. #' #' @param sce SingleCellExperiment object #' @param collection A character vector specifying the gene set collections of interest (GO,KEGG) #' @param organism A character string of the org.*.eg.db package to use to extract mappings of gene sets to gene IDs. -#' @param gene_identifer A character string specifying the identifier to use to extract gene IDs for the organism package +#' @param gene_identifier A character string specifying the identifier to use to extract gene IDs for the organism package #' #' @return A list of "Panel" objects specifying the initial state of iSEE instance #' @export iSEEnrich @@ -14,31 +14,60 @@ #' @importFrom iSEEu createGeneSetCommands #' @importFrom iSEEu registerFeatureSetCommands #' @importFrom iSEEu FeatureSetTable -#' +#' #' #' @examples -#' sce <- scRNAseq::BacherTCellData() +#' sce <- scRNAseq::RichardTCellData() #' sce <- scuttle::logNormCounts(sce) #' sce <- scater::runPCA(sce) #' GO_collection <- "GO" -#' Hs_organism <- "org.Hs.eg.db" +#' Mm_organism <- "org.Mm.eg.db" #' gene_id <- "SYMBOL" -#' results <- iSEEnrich(sce = sce, collection = GO_collection, -#' organism = Hs_organism, gene_identifer = gene_id) -#' -iSEEnrich <- function(sce, collection = c("GO", "KEGG"), +#' results <- iSEEnrich(sce = sce, +#' collection = GO_collection, +#' organism = Mm_organism, +#' gene_identifier = gene_id) +#' +iSEEnrich <- function(sce, + collection = c("GO", "KEGG"), organism = "org.Hs.eg.db", - gene_identifer = "ENTREZID") { + gene_identifier = "ENTREZID") { + + ## Checks on arguments + if (!is(sce, "SingleCellExperiment")) + stop("Please provide a SingleCellExperiment as input!") + + stopifnot(is.character(collection)) + stopifnot(length(collection) == 1) + + collection <- match.arg(collection, c("GO", "KEGG")) + + stopifnot(is.character(organism)) + stopifnot(length(organism) == 1) + + stopifnot(is.character(gene_identifier)) + stopifnot(length(gene_identifier) == 1) + + if (!requireNamespace(organism, quietly = TRUE)) + stop("Please check the value of the provided orgDb package ", + "(it needs to be installed)...") + + initial <- list() - + cmds <- createGeneSetCommands(collections = collection, organism = organism, - identifier = gene_identifer) + identifier = gene_identifier) sce1 <- registerFeatureSetCommands(sce, cmds) - + initial[["FeatureSetTable1"]] <- FeatureSetTable() - + initial[["RowDataTable1"]] <- RowDataTable(RowSelectionSource="FeatureSetTable1") - - return(list(initial = initial, sce1 = sce1)) -} \ No newline at end of file + + return( + list( + initial = initial, + sce = sce1 + ) + ) +} diff --git a/R/utils.R b/R/utils.R index 89d4217..db51ba7 100644 --- a/R/utils.R +++ b/R/utils.R @@ -279,7 +279,7 @@ view_initial_network <- function(initial, #' #' It is worth mentioning that [iSEE::iSEE()] is actually able to handle the #' automatic renaming of panels that could be detected as duplicated. This can -#' basically relax the requirement on the "unicity" of the configured panels, with +#' basically relax the requirement on the "uniqueness" of the configured panels, with #' the only caveat of having to think of how the *transmissions* between panels #' will be handled; nevertheless, most users might not even need to face this #' situation. diff --git a/man/glue_initials.Rd b/man/glue_initials.Rd index d28f22b..b206213 100644 --- a/man/glue_initials.Rd +++ b/man/glue_initials.Rd @@ -45,7 +45,7 @@ For example, if using a panel of class \code{FancyPlotPanel} and one called It is worth mentioning that \code{\link[iSEE:iSEE]{iSEE::iSEE()}} is actually able to handle the automatic renaming of panels that could be detected as duplicated. This can -basically relax the requirement on the "unicity" of the configured panels, with +basically relax the requirement on the "uniqueness" of the configured panels, with the only caveat of having to think of how the \emph{transmissions} between panels will be handled; nevertheless, most users might not even need to face this situation. diff --git a/man/iSEEnrich.Rd b/man/iSEEnrich.Rd index c00b1b1..545b93b 100644 --- a/man/iSEEnrich.Rd +++ b/man/iSEEnrich.Rd @@ -8,7 +8,7 @@ iSEEnrich( sce, collection = c("GO", "KEGG"), organism = "org.Hs.eg.db", - gene_identifer = "ENTREZID" + gene_identifier = "ENTREZID" ) } \arguments{ @@ -18,7 +18,7 @@ iSEEnrich( \item{organism}{A character string of the org.*.eg.db package to use to extract mappings of gene sets to gene IDs.} -\item{gene_identifer}{A character string specifying the identifier to use to extract gene IDs for the organism package} +\item{gene_identifier}{A character string specifying the identifier to use to extract gene IDs for the organism package} } \value{ A list of "Panel" objects specifying the initial state of iSEE instance @@ -28,13 +28,15 @@ A list of "Panel" objects specifying the initial state of iSEE instance displaying all associated genes in a \code{RowDataTable} panel. } \examples{ -sce <- scRNAseq::BacherTCellData() +sce <- scRNAseq::RichardTCellData() sce <- scuttle::logNormCounts(sce) sce <- scater::runPCA(sce) GO_collection <- "GO" -Hs_organism <- "org.Hs.eg.db" +Mm_organism <- "org.Mm.eg.db" gene_id <- "SYMBOL" -results <- iSEEnrich(sce = sce, collection = GO_collection, -organism = Hs_organism, gene_identifer = gene_id) +results <- iSEEnrich(sce = sce, + collection = GO_collection, + organism = Mm_organism, + gene_identifier = gene_id) } diff --git a/tests/testthat/setuptests_iSEEfier.R b/tests/testthat/setuptests_iSEEfier.R new file mode 100644 index 0000000..69d5668 --- /dev/null +++ b/tests/testthat/setuptests_iSEEfier.R @@ -0,0 +1,20 @@ +## Preparing up the datasets to use for the test suite +message("--- Loading packages...") +suppressPackageStartupMessages({ + library("scRNAseq") + library("scuttle") + library("scater") +}) +message("- Done!") + +message("--- Preparing datasets...") +sce_allen <- scRNAseq::ReprocessedAllenData(assays = "tophat_counts") +sce_allen <- scuttle::logNormCounts(sce_allen, exprs_values="tophat_counts") +sce_allen <- scater::runPCA(sce_allen) +sce_allen <- scater::runTSNE(sce_allen) + +# sce_bacher <- scRNAseq::BacherTCellData() +# sce_bacher <- scuttle::logNormCounts(sce_bacher) +# sce_bacher <- scater::runPCA(sce_bacher) + +message("- Done!!") diff --git a/tests/testthat/test-iSEEfier.R b/tests/testthat/test-iSEEfier.R new file mode 100644 index 0000000..b03075b --- /dev/null +++ b/tests/testthat/test-iSEEfier.R @@ -0,0 +1,206 @@ +test_that("test iSEEinit",{ + initial <- iSEEinit(sce = sce_allen, + feature.list = c("Il2rb", + "Klre1"), + clusters = "Primary.Type", + groups = "Secondary.Type") + expect_true(is.list(initial)) + + initial_with_board <- iSEEinit(sce = sce_allen, + feature.list = c("Il2rb", + "Klre1"), + clusters = "Primary.Type", + groups = "Secondary.Type", + markdownboard = TRUE) + expect_true(is.list(initial_with_board)) + + initial_with_dynamictable <- iSEEinit(sce = sce_allen, + reddim.type = "PCA", + feature.list = c("Il2rb", + "Klre1"), + clusters = "Primary.Type", + groups = "Secondary.Type", + dynamicMarkerTable = TRUE) + expect_true(is.list(initial_with_dynamictable)) + + ## This is to trigger the argument checks + expect_error({ + iSEEinit(sce = "Pippo", + feature.list = c("Il2rb", + "Klre1"), + clusters = "Primary.Type", + groups = "Secondary.Type") + }, "Please provide a SingleCellExperiment as input!") + + expect_error({ + iSEEinit(sce = sce_allen, + reddim.type = "PCA", + feature.list = TRUE, + clusters = "Primary.Type", + groups = "Secondary.Type") + }) + + expect_error({ + iSEEinit(sce = sce_allen, + reddim.type = "PCA", + feature.list = character(0L), + clusters = "Primary.Type", + groups = "Secondary.Type") + }) + + expect_error({ + iSEEinit(sce = sce_allen, + reddim.type = TRUE, + feature.list = c("Il2rb", + "Klre1"), + clusters = "Primary.Type", + groups = "Secondary.Type") + }) + + expect_error({ + iSEEinit(sce = sce_allen, + reddim.type = "pca", + feature.list = c("Il2rb", + "Klre1"), + clusters = "Primary.Type", + groups = "Secondary.Type") + }) + + expect_error({ + iSEEinit(sce = sce_allen, + reddim.type = c("PCA", "TSNE"), + feature.list = c("Il2rb", + "Klre1"), + clusters = "Primary.Type", + groups = "Secondary.Type") + }) + + expect_error({ + iSEEinit(sce = sce_allen, + reddim.type = "PCA", + feature.list = c("Il2rb", + "Klre1"), + clusters = TRUE, + groups = "Secondary.Type") + }) + + expect_error({ + iSEEinit(sce = sce_allen, + reddim.type = "PCA", + feature.list = c("Il2rb", + "Klre1"), + clusters = c("JaneDoe", "JohnDoe"), + groups = "Secondary.Type") + }) + + expect_error({ + iSEEinit(sce = sce_allen, + reddim.type = "PCA", + feature.list = c("Il2rb", + "Klre1"), + clusters = "Primary.Type", + groups = FALSE) + }) + + expect_error({ + iSEEinit(sce = sce_allen, + reddim.type = "PCA", + feature.list = c("Il2rb", + "Klre1"), + clusters = "Primary.Type", + groups = c("Primary.Type", "Secondary.Type")) + }) + + expect_error({ + iSEEinit(sce = sce_allen, + reddim.type = "PCA", + feature.list = c("Il2rb", + "Klre1"), + clusters = "Primary.Type", + groups = "Secondary.Type", + markdownboard = "yes") + }) + expect_error({ + iSEEinit(sce = sce_allen, + reddim.type = "PCA", + feature.list = c("Il2rb", + "Klre1"), + clusters = "Primary.Type", + groups = "Secondary.Type", + markdownboard = c(TRUE, TRUE)) + }) + + expect_error({ + iSEEinit(sce = sce_allen, + reddim.type = "PCA", + feature.list = c("Il2rb", + "Klre1"), + clusters = "Primary.Type", + groups = "Secondary.Type", + dynamicMarkerTable= "no") + }) + + expect_error({ + iSEEinit(sce = sce_allen, + reddim.type = "PCA", + feature.list = c("Il2rb", + "Klre1"), + clusters = "Primary.Type", + groups = "Secondary.Type", + dynamicMarkerTable= c(FALSE, FALSE)) + }) + + expect_message({ + init_pippo <- iSEEinit(sce = sce_allen, + reddim.type = "PCA", + feature.list = c("Il2rb", + "Klre1", + "Pippo"), + clusters = "Primary.Type", + groups = "Secondary.Type") + }) + expect_error({ + init_pippo_pluto <- iSEEinit(sce = sce_allen, + reddim.type = "PCA", + feature.list = c("Pluto", + "Pippo"), + clusters = "Primary.Type", + groups = "Secondary.Type") + }) + + sce_nocd <- sce_allen + colData(sce_nocd) <- NULL + + expect_message({ + initial_cluster_fallback <- iSEEinit(sce = sce_allen, + feature.list = c("Il2rb", + "Klre1"), + clusters = "Primary_Type", + groups = "Secondary.Type") + }) + + expect_error({ + initial <- iSEEinit(sce = sce_nocd, + feature.list = c("Il2rb", + "Klre1"), + clusters = "anything", + groups = "Secondary.Type") + }) + + expect_message({ + initial_group_fallback <- iSEEinit(sce = sce_allen, + feature.list = c("Il2rb", + "Klre1"), + clusters = "Primary.Type", + groups = "Secondary_Type") + }) + + expect_error({ + initial <- iSEEinit(sce = sce_nocd, + feature.list = c("Il2rb", + "Klre1"), + clusters = "Primary.Type", + groups = "anything_else") + }) + +}) diff --git a/tests/testthat/test-iSEEnrich.R b/tests/testthat/test-iSEEnrich.R index d8d7641..ebff11c 100644 --- a/tests/testthat/test-iSEEnrich.R +++ b/tests/testthat/test-iSEEnrich.R @@ -1,12 +1,62 @@ test_that("test iSEEnrich", { - sce <- scRNAseq::BacherTCellData() - sce <- scuttle::logNormCounts(sce) - sce <- scater::runPCA(sce) + GO_collection <- "GO" - Hs_organism <- "org.Hs.eg.db" + Mm_organism <- "org.Mm.eg.db" gene_id <- "SYMBOL" - results <- iSEEnrich(sce = sce, collection = GO_collection, - organism = Hs_organism, - gene_identifer = gene_id) - expect_true(class(results)== "list") + + results <- iSEEnrich(sce = sce_allen, + collection = GO_collection, + organism = Mm_organism, + gene_identifier = gene_id) + expect_true(is.list(results)) + expect_true(is.list(results$initial)) + expect_true(is(results$sce, "SingleCellExperiment")) + + ## This is to trigger the argument checks + expect_error({ + iSEEnrich(sce = "Pippo", + collection = GO_collection, + organism = Mm_organism, + gene_identifier = gene_id) + }) + + expect_error({ + iSEEnrich(sce = sce_allen, + collection = "MSIGDB", + organism = Mm_organism, + gene_identifier = gene_id) + }) + + expect_error({ + iSEEnrich(sce = sce_allen, + collection = c("MSIGDB", "GO"), + organism = Mm_organism, + gene_identifier = gene_id) + }) + + expect_error({ + iSEEnrich(sce = sce_allen, + collection = GO_collection, + organism = TRUE, + gene_identifier = gene_id) + }) + + expect_error({ + iSEEnrich(sce = sce_allen, + collection = GO_collection, + organism = c("org.Mm.eg.db", "mouse"), + gene_identifier = gene_id) + }) + + expect_error({ + iSEEnrich(sce = sce_allen, + collection = GO_collection, + organism = c("mouse"), + gene_identifier = gene_id) + }) + + + + + }) diff --git a/tests/testthat/test-utils.R b/tests/testthat/test-utils.R new file mode 100644 index 0000000..97773f8 --- /dev/null +++ b/tests/testthat/test-utils.R @@ -0,0 +1,61 @@ +test_that("iSEEfier utils work", { + init_1 <- iSEEinit(sce = sce_allen, + feature.list = c("Il2rb", + "Klre1"), + clusters = "Primary.Type", + groups = "Secondary.Type") + expect_true(is.list(init_1)) + + init_2 <- iSEEinit(sce = sce_allen, + feature.list = c("Actb", "Gapdh"), + clusters = "Primary.Type", + groups = "Secondary.Type", markdownboard = TRUE) + expect_true(is.list(init_2)) + + expect_true(length(init_1) == 10) + expect_true(length(init_2) == 11) + + p_tiles_1 <- view_initial_tiles(init_1) + p_tiles_2 <- view_initial_tiles(init_2) + + expect_true(is(p_tiles_1, "gg")) + expect_true(is(p_tiles_2, "gg")) + + g_tiles_1 <- view_initial_network(init_1) + g_tiles_2 <- view_initial_network(init_2, plot_format = "visNetwork") + expect_true(is(g_tiles_1, "igraph")) + expect_true(is(g_tiles_2, "igraph")) + + init_chopped <- init_1[c(3,6)] + g_tiles_noedges <- view_initial_network(init_chopped, plot_format = "none") + expect_true(length(igraph::E(g_tiles_noedges)) == 0) + + expect_message( + init_combined <- glue_initials(init_1, init_2, remove_duplicate_panels = TRUE), + "Dropping" + ) + expect_true(length(init_combined) == 19) + + p_tiles_combined <- view_initial_tiles(init_combined) + expect_true(is(p_tiles_combined, "gg")) + + ## Covering edge cases + expect_error( + glue_initials(init_1, init_2$ReducedDimensionPlot1), + "You need to provide a set of `initial` configuration lists for iSEE" + ) + + init_mod <- init_1 + names(init_mod)[1] <- "ImaginaryPanel1" + class(init_mod[[1]]) <- "ImaginaryPanel" + expect_error( + glue_initials(init_mod, init_2), + "Some elements included in the provided input are not recognized as iSEE panels!" + ) + ## This one works by enabling the specific panel + glued_custom <- glue_initials(init_mod, init_2, + custom_panels_allowed = "ImaginaryPanel", + remove_duplicate_panels = FALSE) + expect_true(length(glued_custom) == 21) + +}) diff --git a/tests/testthat/test_iSEEfier.R b/tests/testthat/test_iSEEfier.R deleted file mode 100644 index b121c4c..0000000 --- a/tests/testthat/test_iSEEfier.R +++ /dev/null @@ -1,12 +0,0 @@ -test_that("test iSEEinit",{ - sce <- scRNAseq::ReprocessedAllenData(assays = "tophat_counts") - sce <- scuttle::logNormCounts(sce, exprs_values="tophat_counts") - sce <- scater::runPCA(sce) - sce <- scater::runTSNE(sce) - initial <- iSEEinit(sce = sce, - feature.list = c("IL2rb", - "Klre1"), - clusters = "Primary.Type", - groups = "Secondary.Type") - expect_true(class(initial)== "list") -}) diff --git a/vignettes/iSEEfier_userguide.Rmd b/vignettes/iSEEfier_userguide.Rmd index ac41ceb..870b869 100644 --- a/vignettes/iSEEfier_userguide.Rmd +++ b/vignettes/iSEEfier_userguide.Rmd @@ -36,7 +36,7 @@ knitr::opts_chunk$set( # Introduction {#introduction} -This vignette describes how to use `r BiocStyle::Biocpkg("iSEEfier")` package to configure various initial states of iSEE instances, in order to simplify the task of visualizing single-cell RNA-seq, bulk RNA-seq data, or even your proteomics data in `r BiocStyle::Biocpkg("iSEE")`. +This vignette describes how to use the `r BiocStyle::Biocpkg("iSEEfier")` package to configure various initial states of iSEE instances, in order to simplify the task of visualizing single-cell RNA-seq, bulk RNA-seq data, or even your proteomics data in `r BiocStyle::Biocpkg("iSEE")`. In the remainder of this vignette, we will illustrate the main features of `r BiocStyle::Biocpkg("iSEEfier")` on a publicly available dataset from Baron et al. "A Single-Cell Transcriptomic Map of the Human and Mouse Pancreas Reveals Inter- and Intra-cell Population Structure", published in Cell Systems in 2016. [doi:10.1016/j.cels.2016.08.011](https://doi.org/10.1016/j.cels.2016.08.011). @@ -62,19 +62,19 @@ library("iSEEfier") # Create an initial state for gene expression visualization using `iSEEinit()` -When we have all input elements ready, we can create an iSEE initial state by running: +When we have all input elements ready, we can create an `iSEE` initial state by running: ```{r runfunc, eval=FALSE} iSEEinit(sce = sce_obj, feature.list = feature_list, reddim.type = reduced_dim, clusters = cluster, - groups = group, + groups = group, markdownboard = FALSE, dynamicMarkerTable = FALSE) ``` -To configure the initial state of our iSEE instance using `iSEEinit()`, we need five parameters: +To configure the initial state of our `iSEE` instance using `iSEEinit()`, we need five parameters: 1. `sce` : A `SingleCellExperiment` object. This object stores information of different quantifications (counts, log-expression...), dimensionality reduction coordinates (t-SNE, UMAP...), as well as some metadata related to the samples and features. @@ -151,7 +151,7 @@ iSEE(sce, initial= initial1) This instance, generated with `iSEEinit()`, returns a combination of panels, linked to each other, with the goal of visualizing the expression of certain marker genes in each cell population/group: -- A `ReducedDimensionPlot`, `FeatureAssayPlot` and `RowDataTable` for each single gene. +- A `ReducedDimensionPlot`, `FeatureAssayPlot` and `RowDataTable` for each single gene in `feature.list`. - A `ComplexHeatmapPlot` with all genes in `feature.list` @@ -163,7 +163,7 @@ This instance, generated with `iSEEinit()`, returns a combination of panels, lin # Create an initial state for feature sets exploration using `iSEEnrich()` -Sometimes it is interesting to look at some specific feature sets and the associated genes. That's when the utility of iSEEnrich becomes apparent. +Sometimes it is interesting to look at some specific feature sets and the associated genes. That's when the utility of `iSEEnrich` becomes apparent. We will need 4 elements to explore feature sets of interest: - `sce`: A SingleCellExperiment object @@ -176,7 +176,7 @@ We will need 4 elements to explore feature sets of interest: ```{r set-param} GO_collection <- "GO" -Hs_organism <- "org.Mm.eg.db" +Mm_organism <- "org.Mm.eg.db" gene_id <- "SYMBOL" ``` @@ -185,21 +185,22 @@ Now let's create this initial setup for `iSEE` using `iSEEnrich()` ```{r initial2} results <- iSEEnrich(sce = sce, collection = GO_collection, - organism = Hs_organism, - gene_identifer = gene_id) + organism = Mm_organism, + gene_identifier = gene_id) ``` -To start the iSEE instance we run: +`iSEEnrich` will specifically return a list with the updated `sce` object and its associated `initial` configuration. +To start the `iSEE` instance we run: ```{r iSEEviz2, eval=FALSE} -iSEE(results$sce1, initial = results$initial) +iSEE(results$sce, initial = results$initial) ``` # Visualize a preview of the initial configurations with `view_initial_tiles()` Previously, we successfully generated two distinct initial configurations for iSEE. However, understanding the expected content of our iSEE instances is not always straightforward. That's when we can use `view_initial_tiles()`. -We only need as an input the initial configuration to obtain a graphical visualization of the expected the corresponding iSEE instance: +We only need as an input the initial configuration to obtain a graphical visualization of the expected the corresponding `iSEE` instance: ```{r panelgraph} library(ggplot2) @@ -207,10 +208,12 @@ view_initial_tiles(initial = initial1) view_initial_tiles(initial = results$initial) ``` -# Visualize Network connections between panels with `view_initial_network()` +# Visualize network connections between panels with `view_initial_network()` As some of these panels are linked to each other, we can visualize these networks with `view_initial_network()`. Similar to `iSEEconfigviewer()`, this function takes the initial setup as input: +This function always returns the `igraph` object underlying the visualizations that can be displayed as a side effect. + ```{r networkviz} library("igraph") library("visNetwork") @@ -224,7 +227,7 @@ g2 <- view_initial_network(initial2, plot_format = "visNetwork") # Merge different initial configurations with `glue_initials()` -Sometimes, it would be interesting to merge different iSEE initial configurations to visualize all different panel in the same iSEE instance. +Sometimes, it would be interesting to merge different `iSEE` initial configurations to visualize all different panel in the same `iSEE` instance. ```{r glueconfig} merged_config <- glue_initials(initial1,initial2)