From 3bf4295b18399bdf5a8f45e61c24157419cccbf0 Mon Sep 17 00:00:00 2001 From: Yichen Wang Date: Sun, 24 Mar 2024 18:18:01 -0400 Subject: [PATCH] Fixes upon CRAN 2.0.0 feedbacks --- DESCRIPTION | 4 +- NEWS.md | 11 ++- R/ATAC.R | 16 +++- R/GSEA.R | 19 +++- R/cINMF.R | 14 ++- R/import.R | 16 +++- R/integration.R | 15 +-- R/visualization.R | 8 +- README.md | 20 ++++ man/createH5LigerDataset.Rd | 12 ++- man/createLiger.Rd | 4 + man/exportInteractTrack.Rd | 5 +- man/linkGenesAndPeaks.Rd | 11 ++- man/plotSankey.Rd | 8 +- man/runCINMF.Rd | 12 ++- man/runGOEnrich.Rd | 4 +- man/runGSEA.Rd | 7 +- tests/testthat/test_downstream.R | 71 ++++++++------ tests/testthat/test_factorization.R | 52 ++++++----- tests/testthat/test_object.R | 102 +++++++++++---------- tests/testthat/test_preprocessing.R | 54 ++++++----- tests/testthat/test_subset.R | 31 ++++--- tests/testthat/test_visualization.R | 43 +++++---- vignettes/articles/STARmap_dropviz_vig.Rmd | 4 +- 24 files changed, 340 insertions(+), 203 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 3d9ae102..daf42221 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: rliger -Version: 2.0.0 -Date: 2024-03-20 +Version: 2.0.1 +Date: 2024-03-24 Type: Package Title: Linked Inference of Genomic Experimental Relationships Description: Uses an extension of nonnegative matrix factorization to identify shared and dataset-specific factors. See Welch J, Kozareva V, et al (2019) , and Liu J, Gao C, Sodicoff J, et al (2020) for more details. diff --git a/NEWS.md b/NEWS.md index 60af7ca4..03a3f6ad 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,13 +4,19 @@ - Currently we allow analysis with 10X cellranger output H5 file and H5AD file from anndata>=0.8.0 - Writing to H5AD file should follow anndata specification otherwise the file cannot be read back to a Python seesion. - Writing to 10X H5 file should be carefully investigated. + - Consider using object backend to store information instead of active H5 binding, which cannot be serialized to RDS. + - Investigate whether to use existing backend implementation like HDF5Array, DelayedArray. - Ability to reorganize datasets - Allow doing something like `reorganize(ligerObj, variable = "somethingNotDataset")` and resulting in a new liger object with different ligerDataset grouping. - Ability to do downstream analysis on H5 data - Pseudo-bulk should be easy because we are just aggregating cells. - Wilcoxon might be a bit harder because ranks are calculated per gene but the H5 sparse data is column majored. Might need to find a fast on-disk transposition method. -- Fix runUINMF aborting criteria - - UINMF is capable of running with k > number of shared genes. Don't have to abort on it. + +## rliger 2.0.1 + +- Fixed wrong UINMF aborting criteria +- Fixed example/test skipping criteria for nonexisting dependencies +- Fixed file access issue when checking package on CRAN ## rliger 2.0.0 @@ -23,6 +29,7 @@ - Added native Seurat object support for the core integration workflow - Added a documentation website built with pkgdown - Added new iNMF variant method, consensus iNMF (c-iNMF), in `runCINMF()`. Not stable. +- Added GO enrichment dowsntream analysis in `runGOEnrich()` - Changed `liger` object class structure - Moved iNMF (previously `optimizeALS()`), UINMF (previously `optimizeALS(unshared = TRUE)`) and online iNMF (previously `online_iNMF()`) implementation to new package *RcppPlanc* with vastly improved performance. Now wrapped in `runINMF()`, `runUINMF()` and `runOnlineINMF()` respectively, and all can be invoked with `runIntegration()`. - Updated H5AD support to match up with Python anndata package 0.8.0 specs diff --git a/R/ATAC.R b/R/ATAC.R index 6a59776b..10dbf8a5 100644 --- a/R/ATAC.R +++ b/R/ATAC.R @@ -169,10 +169,13 @@ imputeKNN <- function( #' @export #' @examples #' \donttest{ -#' bmmc <- normalize(bmmc) -#' bmmc <- selectGenes(bmmc) -#' bmmc <- scaleNotCenter(bmmc) -#' if (requireNamespace("RcppPlanc", quietly = TRUE)) { +#' if (requireNamespace("RcppPlanc", quietly = TRUE) && +#' requireNamespace("GenomicRanges", quietly = TRUE) && +#' requireNamespace("IRanges", quietly = TRUE) && +#' requireNamespace("psych", quietly = TRUE)) { +#' bmmc <- normalize(bmmc) +#' bmmc <- selectGenes(bmmc) +#' bmmc <- scaleNotCenter(bmmc) #' bmmc <- runINMF(bmmc, miniBatchSize = 100) #' bmmc <- quantileNorm(bmmc) #' bmmc <- normalizePeak(bmmc) @@ -362,7 +365,10 @@ linkGenesAndPeaks <- function( #' bmmc <- normalize(bmmc) #' bmmc <- selectGenes(bmmc) #' bmmc <- scaleNotCenter(bmmc) -#' if (requireNamespace("RcppPlanc", quietly = TRUE)) { +#' if (requireNamespace("RcppPlanc", quietly = TRUE) && +#' requireNamespace("GenomicRanges", quietly = TRUE) && +#' requireNamespace("IRanges", quietly = TRUE) && +#' requireNamespace("psych", quietly = TRUE)) { #' bmmc <- runINMF(bmmc) #' bmmc <- quantileNorm(bmmc) #' bmmc <- normalizePeak(bmmc) diff --git a/R/GSEA.R b/R/GSEA.R index 76baefd1..7bf34d6d 100644 --- a/R/GSEA.R +++ b/R/GSEA.R @@ -17,7 +17,12 @@ #' @export #' @examples #' \donttest{ -#' runGSEA(pbmcPlot) +#' if (requireNamespace("org.Hs.eg.db", quietly = TRUE) && +#' requireNamespace("reactome.db", quietly = TRUE) && +#' requireNamespace("fgsea", quietly = TRUE) && +#' requireNamespace("AnnotationDbi", quietly = TRUE)) { +#' runGSEA(pbmcPlot) +#' } #' } runGSEA <- function( object, @@ -47,7 +52,13 @@ runGSEA <- function( cli::cli_abort( "Package {.pkg fgsea} is needed for this function to work. Please install it by command: - {.code BiocManager::install('fgsea')}") # nocov end + {.code BiocManager::install('fgsea')}") + + if (!requireNamespace("AnnotationDbi", quietly = TRUE)) + cli::cli_abort( + "Package {.pkg AnnotationDbi} is needed for this function to work. + Please install it by command: + {.code BiocManager::install('AnnotationDbi')}") # nocov end .deprecateArgs(list(gene_sets = "genesets", mat_w = "useW", @@ -151,7 +162,9 @@ runGSEA <- function( #' # Setting `significant = FALSE` because it's hard for a gene list obtained #' # from small test dataset to represent real-life biology. #' \donttest{ -#' go <- runGOEnrich(res, group = 0, significant = FALSE) +#' if (requireNamespace("gprofiler2", quietly = TRUE)) { +#' go <- runGOEnrich(res, group = 0, significant = FALSE) +#' } #' } runGOEnrich <- function( result, diff --git a/R/cINMF.R b/R/cINMF.R index e73f9705..dc504e6e 100644 --- a/R/cINMF.R +++ b/R/cINMF.R @@ -1,10 +1,14 @@ #' Perform consensus iNMF on scaled datasets #' @description +#' \bold{NOT STABLE} - This is an experimental function and is subject to change. +#' #' Performs consensus integrative non-negative matrix factorization (c-iNMF) -#' to return factorized \eqn{H}, \eqn{W}, and \eqn{V} matrices. We run the -#' regular iNMF multiple times with different random starts, and then take the -#' consensus of frequently appearing factors from gene loading matrices, \eqn{W} -#' and \eqn{V}. The cell factor loading \eqn{H} matrices are eventually solved +#' to return factorized \eqn{H}, \eqn{W}, and \eqn{V} matrices. In order to +#' address the non-convex nature of NMF, we built on the cNMF method proposed by +#' D. Kotliar, 2019. We run the regular iNMF multiple times with different +#' random starts, and cluster the pool of all the factors in \eqn{W} and +#' \eqn{V}s and take the consensus of the clusters of the largest population. +#' The cell factor loading \eqn{H} matrices are eventually solved #' with the consensus \eqn{W} and \eqn{V} matrices. #' #' Please see \code{\link{runINMF}} for detailed introduction to the regular @@ -257,7 +261,7 @@ runCINMF.Seurat <- function( cli::cli_abort( "Package {.pkg RcppPlanc} is required for c-iNMF integration. Please install it by command: - {.code devtools::install_github('welch-lab/RcppPlanc')}") # nocov end + {.code install.packages('RcppPlanc', repos = 'https:/welch-lab.r-universe.dev')}") # nocov end if (nRandomStarts <= 1) { cli::cli_abort("{.var nRandomStarts} must be greater than 1 for taking the consensus.") } diff --git a/R/import.R b/R/import.R index 67844529..71fb98bd 100644 --- a/R/import.R +++ b/R/import.R @@ -1,6 +1,10 @@ #' Create liger object #' @description This function allows creating \linkS4class{liger} object from #' multiple datasets of various forms (See \code{rawData}). +#' +#' \bold{DO} make a copy of the H5AD files because rliger functions write to +#' the files and they will not be able to be read back to Python. This will be +#' fixed in the future. #' @param rawData Named list of datasets. Required. Elements allowed include a #' matrix, a \code{Seurat} object, a \code{SingleCellExperiment} object, an #' \code{AnnData} object, a \linkS4class{ligerDataset} object or a filename to @@ -239,10 +243,14 @@ createLigerDataset <- function( #' @description #' For convenience, the default \code{formatType = "10x"} directly fits the #' structure of cellranger output. \code{formatType = "anndata"} works for -#' current AnnData H5AD file specification (see Details). If there a customized -#' H5 file structure is presented, any of the \code{rawData}, +#' current AnnData H5AD file specification (see Details). If a customized H5 +#' file structure is presented, any of the \code{rawData}, #' \code{indicesName}, \code{indptrName}, \code{genesName}, \code{barcodesName} #' should be specified accordingly to override the \code{formatType} preset. +#' +#' \bold{DO} make a copy of the H5AD files because rliger functions write to +#' the files and they will not be able to be read back to Python. This will be +#' fixed in the future. #' @details #' For H5AD file written from an AnnData object, we allow using #' \code{formatType = "anndata"} for the function to infer the proper structure. @@ -282,7 +290,9 @@ createLigerDataset <- function( #' @return H5-based \linkS4class{ligerDataset} object #' @examples #' h5Path <- system.file("extdata/ctrl.h5", package = "rliger") -#' ld <- createH5LigerDataset(h5Path) +#' tempPath <- tempfile(fileext = ".h5") +#' file.copy(from = h5Path, to = tempPath) +#' ld <- createH5LigerDataset(tempPath) createH5LigerDataset <- function( h5file, formatType = "10X", diff --git a/R/integration.R b/R/integration.R index 0a5f29a1..e84f4b06 100644 --- a/R/integration.R +++ b/R/integration.R @@ -384,7 +384,7 @@ runINMF.Seurat <- function( cli::cli_abort( "Package {.pkg RcppPlanc} is required for iNMF integration. Please install it by command: - {.code devtools::install_github('welch-lab/RcppPlanc')}") # nocov end + {.code install.packages('RcppPlanc', repos = 'https:/welch-lab.r-universe.dev')}") # nocov end barcodeList <- lapply(object, colnames) allFeatures <- lapply(object, rownames) @@ -822,7 +822,7 @@ runOnlineINMF.liger <- function( cli::cli_abort( "Package {.pkg RcppPlanc} is required for online iNMF integration. Please install it by command: - {.code devtools::install_github('welch-lab/RcppPlanc')}") # nocov end + {.code install.packages('RcppPlanc', repos = 'https:/welch-lab.r-universe.dev')}") # nocov end nDatasets <- length(object) + length(newDatasets) barcodeList <- c(lapply(object, colnames), lapply(newDatasets, colnames)) names(barcodeList) <- c(names(object), names(newDatasets)) @@ -1207,7 +1207,7 @@ runUINMF.liger <- function( cli::cli_abort( "Package {.pkg RcppPlanc} is required for mosaic iNMF integration with unshared features. Please install it by command: - {.code devtools::install_github('welch-lab/RcppPlanc')}")# nocov end + {.code install.packages('RcppPlanc', repos = 'https:/welch-lab.r-universe.dev')}")# nocov end barcodeList <- lapply(object, colnames) allFeatures <- lapply(object, rownames) features <- Reduce(.same, allFeatures) @@ -1215,9 +1215,6 @@ runUINMF.liger <- function( if (min(lengths(barcodeList)) < k) { cli::cli_abort("Number of factors (k={k}) should be less than the number of cells in the smallest dataset ({min(lengths(barcodeList))}).") } - if (length(features) < k) { - cli::cli_abort("Number of factors (k={k}) should be less than the number of shared features ({length(features)}).") - } bestObj <- Inf bestRes <- NULL @@ -1685,12 +1682,6 @@ calcAgreement <- function( "i" = "e.g. {.code memCopy <- subsetLiger(object, useSlot = 'scaleData', newH5 = FALSE)}") ) } - if (!requireNamespace("RcppPlanc", quietly = TRUE)) - cli::cli_abort( - "Package {.pkg RcppPlanc} is needed for this function to work. - Please install it by command: - {.code devtools::install_github('RcppPlanc')}") - scaled <- getMatrix(object, "scaleData", returnList = TRUE) scaleDataIsNull <- sapply(scaled, is.null) diff --git a/R/visualization.R b/R/visualization.R index fa665d75..260a09da 100644 --- a/R/visualization.R +++ b/R/visualization.R @@ -1068,9 +1068,11 @@ plotGeneLoadingRank <- function( #' cellMeta(pbmcPlot, "leiden_cluster", "ctrl") #' cellMeta(pbmcPlot, "stim_cluster", "stim") <- #' cellMeta(pbmcPlot, "leiden_cluster", "stim") -#' plotSankey(pbmcPlot, "ctrl_cluster", "stim_cluster", -#' titles = c("control", "LIGER", "stim"), -#' prefixes = c("c", NA, "s")) +#' if (requireNamespace("sankey", quietly = TRUE)) { +#' plotSankey(pbmcPlot, "ctrl_cluster", "stim_cluster", +#' titles = c("control", "LIGER", "stim"), +#' prefixes = c("c", NA, "s")) +#' } plotSankey <- function( object, cluster1, diff --git a/README.md b/README.md index 9f27387b..8844057b 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,26 @@ analysis, and visualization. Users can: We have also designed LIGER to interface with existing single-cell analysis packages, including [Seurat](https://satijalab.org/seurat/). +## Citation + +If you use LIGER in your research please cite our paper correspondingly: + +* Generally the *Cell* paper should be cited: + +>Joshua D. Welch and et al., Single-Cell Multi-omic Integration Compares and Contrasts Features of Brain Cell Identity, Cell, VOLUME 177, ISSUE 7, P1873-1887.E17 (2019), [https://doi.org/10.1016/j.cell.2019.05.006](https://doi.org/10.1016/j.cell.2019.05.006) + +* For the *rliger* package: + +>Liu, J., Gao, C., Sodicoff, J. et al. Jointly defining cell types from multiple single-cell datasets using LIGER. Nat Protoc 15, 3632–3662 (2020), [https://doi.org/10.1038/s41596-020-0391-8](https://doi.org/10.1038/s41596-020-0391-8) + +* For online iNMF integration method: + +>Gao, C., Liu, J., Kriebel, A.R. et al. Iterative single-cell multi-omic integration using online learning. Nat Biotechnol 39, 1000–1007 (2021), [https://doi.org/10.1038/s41587-021-00867-x](https://doi.org/10.1038/s41587-021-00867-x) + +* For UINMF integration method: + +>Kriebel, A.R., Welch, J.D. UINMF performs mosaic integration of single-cell multi-omic datasets using nonnegative matrix factorization. Nat Commun 13, 780 (2022), [https://doi.org/10.1038/s41467-022-28431-4](https://doi.org/10.1038/s41467-022-28431-4) + ## Feedback If you have any questions, comments, or suggestions, you are welcomed to [open an Issue](https://github.com/welch-lab/liger/issues)! diff --git a/man/createH5LigerDataset.Rd b/man/createH5LigerDataset.Rd index d0a7801d..b0adffe3 100644 --- a/man/createH5LigerDataset.Rd +++ b/man/createH5LigerDataset.Rd @@ -58,10 +58,14 @@ H5-based \linkS4class{ligerDataset} object \description{ For convenience, the default \code{formatType = "10x"} directly fits the structure of cellranger output. \code{formatType = "anndata"} works for -current AnnData H5AD file specification (see Details). If there a customized -H5 file structure is presented, any of the \code{rawData}, +current AnnData H5AD file specification (see Details). If a customized H5 +file structure is presented, any of the \code{rawData}, \code{indicesName}, \code{indptrName}, \code{genesName}, \code{barcodesName} should be specified accordingly to override the \code{formatType} preset. + +\bold{DO} make a copy of the H5AD files because rliger functions write to +the files and they will not be able to be read back to Python. This will be +fixed in the future. } \details{ For H5AD file written from an AnnData object, we allow using @@ -80,5 +84,7 @@ the AnnData was originally created. } \examples{ h5Path <- system.file("extdata/ctrl.h5", package = "rliger") -ld <- createH5LigerDataset(h5Path) +tempPath <- tempfile(fileext = ".h5") +file.copy(from = h5Path, to = tempPath) +ld <- createH5LigerDataset(tempPath) } diff --git a/man/createLiger.Rd b/man/createLiger.Rd index da0f9979..f3fbdccc 100644 --- a/man/createLiger.Rd +++ b/man/createLiger.Rd @@ -83,6 +83,10 @@ can be dangerous for large scale analysis.} \description{ This function allows creating \linkS4class{liger} object from multiple datasets of various forms (See \code{rawData}). + +\bold{DO} make a copy of the H5AD files because rliger functions write to +the files and they will not be able to be read back to Python. This will be +fixed in the future. } \examples{ # Create from raw count matrices diff --git a/man/exportInteractTrack.Rd b/man/exportInteractTrack.Rd index 01fc88f7..9a9ae76f 100644 --- a/man/exportInteractTrack.Rd +++ b/man/exportInteractTrack.Rd @@ -38,7 +38,10 @@ Genome Browser}. bmmc <- normalize(bmmc) bmmc <- selectGenes(bmmc) bmmc <- scaleNotCenter(bmmc) -if (requireNamespace("RcppPlanc", quietly = TRUE)) { +if (requireNamespace("RcppPlanc", quietly = TRUE) && + requireNamespace("GenomicRanges", quietly = TRUE) && + requireNamespace("IRanges", quietly = TRUE) && + requireNamespace("psych", quietly = TRUE)) { bmmc <- runINMF(bmmc) bmmc <- quantileNorm(bmmc) bmmc <- normalizePeak(bmmc) diff --git a/man/linkGenesAndPeaks.Rd b/man/linkGenesAndPeaks.Rd index 232b9f85..23a1365e 100644 --- a/man/linkGenesAndPeaks.Rd +++ b/man/linkGenesAndPeaks.Rd @@ -57,10 +57,13 @@ result). } \examples{ \donttest{ -bmmc <- normalize(bmmc) -bmmc <- selectGenes(bmmc) -bmmc <- scaleNotCenter(bmmc) -if (requireNamespace("RcppPlanc", quietly = TRUE)) { +if (requireNamespace("RcppPlanc", quietly = TRUE) && + requireNamespace("GenomicRanges", quietly = TRUE) && + requireNamespace("IRanges", quietly = TRUE) && + requireNamespace("psych", quietly = TRUE)) { + bmmc <- normalize(bmmc) + bmmc <- selectGenes(bmmc) + bmmc <- scaleNotCenter(bmmc) bmmc <- runINMF(bmmc, miniBatchSize = 100) bmmc <- quantileNorm(bmmc) bmmc <- normalizePeak(bmmc) diff --git a/man/plotSankey.Rd b/man/plotSankey.Rd index 13fd6cf9..db6677cd 100644 --- a/man/plotSankey.Rd +++ b/man/plotSankey.Rd @@ -91,7 +91,9 @@ cellMeta(pbmcPlot, "ctrl_cluster", "ctrl") <- cellMeta(pbmcPlot, "leiden_cluster", "ctrl") cellMeta(pbmcPlot, "stim_cluster", "stim") <- cellMeta(pbmcPlot, "leiden_cluster", "stim") -plotSankey(pbmcPlot, "ctrl_cluster", "stim_cluster", - titles = c("control", "LIGER", "stim"), - prefixes = c("c", NA, "s")) +if (requireNamespace("sankey", quietly = TRUE)) { + plotSankey(pbmcPlot, "ctrl_cluster", "stim_cluster", + titles = c("control", "LIGER", "stim"), + prefixes = c("c", NA, "s")) +} } diff --git a/man/runCINMF.Rd b/man/runCINMF.Rd index 43f634bb..80d98c57 100644 --- a/man/runCINMF.Rd +++ b/man/runCINMF.Rd @@ -126,11 +126,15 @@ feature key. Default \code{"cinmf"}.} } } \description{ +\bold{NOT STABLE} - This is an experimental function and is subject to change. + Performs consensus integrative non-negative matrix factorization (c-iNMF) -to return factorized \eqn{H}, \eqn{W}, and \eqn{V} matrices. We run the -regular iNMF multiple times with different random starts, and then take the -consensus of frequently appearing factors from gene loading matrices, \eqn{W} -and \eqn{V}. The cell factor loading \eqn{H} matrices are eventually solved +to return factorized \eqn{H}, \eqn{W}, and \eqn{V} matrices. In order to +address the non-convex nature of NMF, we built on the cNMF method proposed by +D. Kotliar, 2019. We run the regular iNMF multiple times with different +random starts, and cluster the pool of all the factors in \eqn{W} and +\eqn{V}s and take the consensus of the clusters of the largest population. +The cell factor loading \eqn{H} matrices are eventually solved with the consensus \eqn{W} and \eqn{V} matrices. Please see \code{\link{runINMF}} for detailed introduction to the regular diff --git a/man/runGOEnrich.Rd b/man/runGOEnrich.Rd index ef734726..3ecbdd27 100644 --- a/man/runGOEnrich.Rd +++ b/man/runGOEnrich.Rd @@ -65,7 +65,9 @@ res <- runMarkerDEG(pbmcPlot) # Setting `significant = FALSE` because it's hard for a gene list obtained # from small test dataset to represent real-life biology. \donttest{ -go <- runGOEnrich(res, group = 0, significant = FALSE) +if (requireNamespace("gprofiler2", quietly = TRUE)) { + go <- runGOEnrich(res, group = 0, significant = FALSE) +} } } \references{ diff --git a/man/runGSEA.Rd b/man/runGSEA.Rd index 4f74f247..c12825aa 100644 --- a/man/runGSEA.Rd +++ b/man/runGSEA.Rd @@ -44,6 +44,11 @@ each metagene (factor) might belongs to. } \examples{ \donttest{ -runGSEA(pbmcPlot) +if (requireNamespace("org.Hs.eg.db", quietly = TRUE) && + requireNamespace("reactome.db", quietly = TRUE) && + requireNamespace("fgsea", quietly = TRUE) && + requireNamespace("AnnotationDbi", quietly = TRUE)) { + runGSEA(pbmcPlot) +} } } diff --git a/tests/testthat/test_downstream.R b/tests/testthat/test_downstream.R index de1b8a93..1afd9f35 100644 --- a/tests/testthat/test_downstream.R +++ b/tests/testthat/test_downstream.R @@ -1,4 +1,3 @@ -has_RcppPlanc <- requireNamespace("RcppPlanc", quietly = TRUE) data("pbmc", package = "rliger") withNewH5Copy <- function(fun) { @@ -6,23 +5,27 @@ withNewH5Copy <- function(fun) { stimpath.orig <- system.file("extdata/stim.h5", package = "rliger") if (!file.exists(ctrlpath.orig)) stop("Cannot find original h5 file at: ", ctrlpath.orig) - if (file.exists("ctrltest.h5")) file.remove("ctrltest.h5") - if (file.exists("stimtest.h5")) file.remove("stimtest.h5") - pwd <- getwd() - # Temp setting for GitHub Actions - fsep <- ifelse(Sys.info()["sysname"] == "Windows", "\\", "/") - if (Sys.info()["sysname"] == "Windows") { - pwd <- file.path("C:\\Users", Sys.info()["user"], "Documents", fsep = fsep) - } - - ctrlpath <- file.path(pwd, "ctrltest.h5", fsep = fsep) - stimpath <- file.path(pwd, "stimtest.h5", fsep = fsep) + # if (file.exists("ctrltest.h5")) file.remove("ctrltest.h5") + # if (file.exists("stimtest.h5")) file.remove("stimtest.h5") + # pwd <- getwd() + # # Temp setting for GitHub Actions + # fsep <- ifelse(Sys.info()["sysname"] == "Windows", "\\", "/") + # if (Sys.info()["sysname"] == "Windows") { + # pwd <- file.path("C:\\Users", Sys.info()["user"], "Documents", fsep = fsep) + # } + + # ctrlpath <- file.path(pwd, "ctrltest.h5", fsep = fsep) + # stimpath <- file.path(pwd, "stimtest.h5", fsep = fsep) + ctrlpath <- tempfile(pattern = "ctrltest_", fileext = ".h5") + stimpath <- tempfile(pattern = "stimtest_", fileext = ".h5") cat("Working ctrl H5 file path: ", ctrlpath, "\n") cat("Working stim H5 file path: ", stimpath, "\n") file.copy(ctrlpath.orig, ctrlpath, copy.mode = TRUE) file.copy(stimpath.orig, stimpath, copy.mode = TRUE) if (!file.exists(ctrlpath)) stop("Cannot find copied h5 file at: ", ctrlpath) + if (!file.exists(stimpath)) + stop("Cannot find copied h5 file at: ", stimpath) fun(list(ctrl = ctrlpath, stim = stimpath)) @@ -63,7 +66,7 @@ is_online <- function() { context("Clustering") test_that("clustering", { - skip_if_not(has_RcppPlanc) + skip_if_not_installed("RcppPlanc") pbmc <- process(pbmc, f = FALSE, q = FALSE) expect_error(runCluster(pbmc), "No cell factor loading available") @@ -113,7 +116,7 @@ test_that("clustering", { context("dimensionality reduction") test_that("dimensionality reduction", { - skip_if_not(has_RcppPlanc) + skip_if_not_installed("RcppPlanc") pbmc <- process(pbmc) expect_message(runUMAP(pbmc, useRaw = TRUE), "Generating UMAP on unnormalized") @@ -137,7 +140,7 @@ test_that("dimensionality reduction", { context("Differential Expression") test_that("wilcoxon", { - skip_if_not(has_RcppPlanc) + skip_if_not_installed("RcppPlanc") expect_error(runMarkerDEG(pbmc), "No `conditionBy` given or default cluster not set") pbmc <- process(pbmc) @@ -165,6 +168,7 @@ test_that("wilcoxon", { expect_identical(names(res3), c("ctrl", "shared", "stim", "num_factors_V1", "num_factors_V2")) + skip_if_not_installed("gprofiler2") expect_error(runGOEnrich(res1, group = "a"), "Selected groups not available") expect_error(runGOEnrich(res1, group = 0, orderBy = c("logFC", "pval")), @@ -183,7 +187,8 @@ test_that("wilcoxon", { test_that("pseudo bulk", { - skip_if_not(has_RcppPlanc) + skip_if_not_installed("RcppPlanc") + skip_if_not_installed("DESeq2") pbmc <- process(pbmc) pbmc <- runCluster(pbmc, nRandomStarts = 1) res1 <- runPairwiseDEG(pbmc, groupTest = pbmc$leiden_cluster == 1, @@ -234,20 +239,23 @@ test_that("pseudo bulk", { #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% context("GSEA") -custom <- list( - `Immune System` = c("9636", "2633", "6282", "6280", "6279", "2207", "2214", - "6402", "91543", "6233", "10578", "3553", "5473", - "3627", "51316", "929", "972") -) - -if (is_online()) { - test_that("gsea", { - expect_warning({ - expect_is(runGSEA(pbmcPlot, genesets = "Immune System"), "list") - expect_is(runGSEA(pbmcPlot, customGenesets = custom), "list") - }) +test_that("gsea", { + skip_if_not(is_online()) + skip_if_not_installed("org.Hs.eg.db") + skip_if_not_installed("reactome.db") + skip_if_not_installed("fgsea") + skip_if_not_installed("AnnotationDbi") + custom <- list( + `Immune System` = c("9636", "2633", "6282", "6280", "6279", "2207", "2214", + "6402", "91543", "6233", "10578", "3553", "5473", + "3627", "51316", "929", "972") + ) + expect_warning({ + expect_is(runGSEA(pbmcPlot, genesets = "Immune System"), "list") + expect_is(runGSEA(pbmcPlot, customGenesets = custom), "list") }) -} +}) + #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # ATAC @@ -256,7 +264,10 @@ if (is_online()) { context("ATAC") data("bmmc") test_that("ATAC", { - skip_if_not(has_RcppPlanc) + skip_if_not_installed("RcppPlanc") + skip_if_not_installed("GenomicRanges") + skip_if_not_installed("IRanges") + skip_if_not_installed("psych") bmmc <- normalize(bmmc) bmmc <- selectGenes(bmmc) bmmc <- scaleNotCenter(bmmc) diff --git a/tests/testthat/test_factorization.R b/tests/testthat/test_factorization.R index b884ef96..13e9e2ef 100644 --- a/tests/testthat/test_factorization.R +++ b/tests/testthat/test_factorization.R @@ -1,4 +1,3 @@ -has_RcppPlanc <- requireNamespace("RcppPlanc", quietly = TRUE) data("pbmc", package = "rliger") rawDataList <- getMatrix(pbmc, "rawData") @@ -7,23 +6,27 @@ withNewH5Copy <- function(fun) { stimpath.orig <- system.file("extdata/stim.h5", package = "rliger") if (!file.exists(ctrlpath.orig)) stop("Cannot find original h5 file at: ", ctrlpath.orig) - if (file.exists("ctrltest.h5")) file.remove("ctrltest.h5") - if (file.exists("stimtest.h5")) file.remove("stimtest.h5") - pwd <- getwd() - # Temp setting for GitHub Actions - fsep <- ifelse(Sys.info()["sysname"] == "Windows", "\\", "/") - if (Sys.info()["sysname"] == "Windows") { - pwd <- file.path("C:\\Users", Sys.info()["user"], "Documents", fsep = fsep) - } + # if (file.exists("ctrltest.h5")) file.remove("ctrltest.h5") + # if (file.exists("stimtest.h5")) file.remove("stimtest.h5") + # pwd <- getwd() + # # Temp setting for GitHub Actions + # fsep <- ifelse(Sys.info()["sysname"] == "Windows", "\\", "/") + # if (Sys.info()["sysname"] == "Windows") { + # pwd <- file.path("C:\\Users", Sys.info()["user"], "Documents", fsep = fsep) + # } - ctrlpath <- file.path(pwd, "ctrltest.h5", fsep = fsep) - stimpath <- file.path(pwd, "stimtest.h5", fsep = fsep) + # ctrlpath <- file.path(pwd, "ctrltest.h5", fsep = fsep) + # stimpath <- file.path(pwd, "stimtest.h5", fsep = fsep) + ctrlpath <- tempfile(pattern = "ctrltest_", fileext = ".h5") + stimpath <- tempfile(pattern = "stimtest_", fileext = ".h5") cat("Working ctrl H5 file path: ", ctrlpath, "\n") cat("Working stim H5 file path: ", stimpath, "\n") file.copy(ctrlpath.orig, ctrlpath, copy.mode = TRUE) file.copy(stimpath.orig, stimpath, copy.mode = TRUE) if (!file.exists(ctrlpath)) stop("Cannot find copied h5 file at: ", ctrlpath) + if (!file.exists(stimpath)) + stop("Cannot find copied h5 file at: ", stimpath) fun(list(ctrl = ctrlpath, stim = stimpath)) @@ -52,7 +55,7 @@ process <- function(object) { context("iNMF") test_that("iNMF - in-memory", { - skip_if_not(has_RcppPlanc) + skip_if_not_installed("RcppPlanc") pbmc <- normalize(pbmc) pbmc <- selectGenes(pbmc) @@ -88,11 +91,11 @@ test_that("iNMF - in-memory", { # }) test_that("UINMF", { - skip_if_not(has_RcppPlanc) + skip_if_not_installed("RcppPlanc") # Need to fake the situation because test dataset doesn't have real # unshared var feature pbmc <- normalize(pbmc) - pbmc <- selectGenes(pbmc, 0.8) + pbmc <- selectGenes(pbmc, 1.2) # Should found 22 shared var features allFeature <- union(rownames(pbmc@datasets$ctrl), rownames(pbmc@datasets$stim)) unshare <- setdiff(allFeature, varFeatures(pbmc)) expect_error(runUINMF(pbmc), @@ -101,15 +104,21 @@ test_that("UINMF", { expect_error(runUINMF(pbmc), "No scaled data for unshared feature found. ") varUnsharedFeatures(pbmc, "ctrl") <- unshare[1:10] - varUnsharedFeatures(pbmc, "stim") <- unshare[11:20] + pbmc <- scaleNotCenter(pbmc) - pbmc <- runUINMF(pbmc, k = 10, nIteration = 2, nRandomStarts = 2) + # This aims at testing nVarFeature < k but we have enough unshared var feature + pbmc <- runUINMF(pbmc, k = 30, nIteration = 2, nRandomStarts = 2) expect_no_error(rliger:::.checkValidFactorResult(pbmc)) + + varUnsharedFeatures(pbmc, "stim") <- unshare[11:20] + pbmc <- scaleNotCenter(pbmc, useDatasets = "stim") + # Normal case + expect_no_error(pbmc <- runUINMF(pbmc, k = 10, nIteration = 2)) }) test_that("Optimize new parameters", { - skip_if_not(has_RcppPlanc) + skip_if_not_installed("RcppPlanc") pbmc <- process(pbmc) pbmc <- runOnlineINMF(pbmc, k = 10, minibatchSize = 100) pbmc0 <- optimizeNewK(pbmc, kNew = 10, nIteration = 2) @@ -142,7 +151,7 @@ test_that("Optimize new parameters", { }) test_that("Online iNMF - in-memory", { - skip_if_not(has_RcppPlanc) + skip_if_not_installed("RcppPlanc") expect_error(runOnlineINMF(pbmc, k = 20, minibatchSize = 100), "Scaled data not available. ") pbmc <- process(pbmc) @@ -185,7 +194,7 @@ test_that("Online iNMF - in-memory", { }) test_that("quantileNorm", { - skip_if_not(has_RcppPlanc) + skip_if_not_installed("RcppPlanc") pbmc <- process(pbmc) pbmc <- runOnlineINMF(pbmc, k = 20, minibatchSize = 100) @@ -226,8 +235,9 @@ test_that("quantileNorm", { context("Seurat iNMF wrapper") test_that("Seurat wrapper", { - skip_if_not(has_RcppPlanc) - skip_if_not(requireNamespace("Seurat", quietly = TRUE)) + skip_if_not_installed("RcppPlanc") + skip_if_not_installed("Seurat") + skip_if_not_installed("SeuratObject") seu <- ligerToSeurat(pbmc) seu <- normalize(seu) seu <- selectGenes(seu) diff --git a/tests/testthat/test_object.R b/tests/testthat/test_object.R index 397e47b6..06e8d480 100644 --- a/tests/testthat/test_object.R +++ b/tests/testthat/test_object.R @@ -1,4 +1,3 @@ -has_RcppPlanc <- requireNamespace("RcppPlanc", quietly = TRUE) data("pbmc", package = "rliger") rawDataList <- getMatrix(pbmc, "rawData") @@ -7,23 +6,27 @@ withNewH5Copy <- function(fun) { stimpath.orig <- system.file("extdata/stim.h5", package = "rliger") if (!file.exists(ctrlpath.orig)) stop("Cannot find original h5 file at: ", ctrlpath.orig) - if (file.exists("ctrltest.h5")) file.remove("ctrltest.h5") - if (file.exists("stimtest.h5")) file.remove("stimtest.h5") - pwd <- tempdir() - # Temp setting for GitHub Actions - fsep <- ifelse(Sys.info()["sysname"] == "Windows", "\\", "/") - if (Sys.info()["sysname"] == "Windows") { - pwd <- file.path("C:\\Users", Sys.info()["user"], "Documents", fsep = fsep) - } - - ctrlpath <- file.path(pwd, "ctrltest.h5", fsep = fsep) - stimpath <- file.path(pwd, "stimtest.h5", fsep = fsep) + # if (file.exists("ctrltest.h5")) file.remove("ctrltest.h5") + # if (file.exists("stimtest.h5")) file.remove("stimtest.h5") + # pwd <- getwd() + # # Temp setting for GitHub Actions + # fsep <- ifelse(Sys.info()["sysname"] == "Windows", "\\", "/") + # if (Sys.info()["sysname"] == "Windows") { + # pwd <- file.path("C:\\Users", Sys.info()["user"], "Documents", fsep = fsep) + # } + + # ctrlpath <- file.path(pwd, "ctrltest.h5", fsep = fsep) + # stimpath <- file.path(pwd, "stimtest.h5", fsep = fsep) + ctrlpath <- tempfile(pattern = "ctrltest_", fileext = ".h5") + stimpath <- tempfile(pattern = "stimtest_", fileext = ".h5") cat("Working ctrl H5 file path: ", ctrlpath, "\n") cat("Working stim H5 file path: ", stimpath, "\n") file.copy(ctrlpath.orig, ctrlpath, copy.mode = TRUE) file.copy(stimpath.orig, stimpath, copy.mode = TRUE) if (!file.exists(ctrlpath)) stop("Cannot find copied h5 file at: ", ctrlpath) + if (!file.exists(stimpath)) + stop("Cannot find copied h5 file at: ", stimpath) fun(list(ctrl = ctrlpath, stim = stimpath)) @@ -122,7 +125,7 @@ test_that("liger object creation - on disk", { context("liger object S3/S4 methods") test_that("liger S3/S4 methods", { - skip_if_not(has_RcppPlanc) + skip_if_not_installed("RcppPlanc") pbmc <- process(pbmc) expect_output(show(pbmc), "An object of class liger with 600 cells") expect_equal(dim(pbmc), c(NA, 600)) @@ -224,7 +227,7 @@ test_that("ligerDataset (in memory) object creation", { #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% test_that("ligerDataset methods", { - skip_if_not(has_RcppPlanc) + skip_if_not_installed("RcppPlanc") pbmc <- process(pbmc) expect_false(isH5Liger(pbmc)) ctrl <- dataset(pbmc, "ctrl") @@ -328,7 +331,7 @@ test_that("ligerDataset methods", { }) test_that("H5 ligerDataset methods", { - skip_if_not(has_RcppPlanc) + skip_if_not_installed("RcppPlanc") withNewH5Copy( function(rawList) { pbmc <- createLiger(rawList) @@ -372,7 +375,8 @@ test_that("H5 ligerDataset methods", { expect_no_error(h5fileInfo(ctrl, "barcodesName") <- "matrix/barcodes") - ctrl.h5$close() + # ctrl.h5$close() + closeAllH5(ctrl) expect_message(show(ctrl), "Link to HDF5 file fails.") } ) @@ -408,24 +412,24 @@ test_that("as.liger methods", { expect_true(all.equal(sapply(datasets(lig), ncol), c(a = 150, b = 150))) } - if (requireNamespace("Seurat", quietly = TRUE)) { - # Seurat - seu <- SeuratObject::CreateSeuratObject( - ctrlRaw, - meta.data = data.frame(orig.ident = factor(rep(c("a", "b"), each = 150)), - nUMI = 0, - row.names = colnames(ctrlRaw)) - ) + skip_if_not_installed("Seurat") + skip_if_not_installed("SeuratObject") + # Seurat + seu <- SeuratObject::CreateSeuratObject( + ctrlRaw, + meta.data = data.frame(orig.ident = factor(rep(c("a", "b"), each = 150)), + nUMI = 0, + row.names = colnames(ctrlRaw)) + ) - seu <- Seurat::NormalizeData(seu) %>% - Seurat::FindVariableFeatures() %>% - Seurat::ScaleData() %>% - Seurat::RunPCA() - expect_message(lig <- as.liger(seu)) - expect_true(all.equal(sapply(datasets(lig), ncol), c(a = 150, b = 150))) + seu <- Seurat::NormalizeData(seu) %>% + Seurat::FindVariableFeatures() %>% + Seurat::ScaleData() %>% + Seurat::RunPCA() + expect_message(lig <- as.liger(seu)) + expect_true(all.equal(sapply(datasets(lig), ncol), c(a = 150, b = 150))) - expect_in("pca", names(dimReds(lig))) - } + expect_in("pca", names(dimReds(lig))) }) test_that("as.ligerDataset methods", { @@ -464,23 +468,23 @@ test_that("as.ligerDataset methods", { }) test_that("ligerToSeurat", { - if (requireNamespace("Seurat", quietly = TRUE)) { - seu <- ligerToSeurat(pbmc) - expect_equal(SeuratObject::Assays(seu), "RNA") - - pbmc@datasets$stim <- as.ligerDataset(pbmc@datasets$stim, modal = "atac") - pbmc <- normalize(pbmc, useDatasets = "ctrl") - seu <- ligerToSeurat(pbmc) - expect_equal(SeuratObject::Assays(seu), "LIGER") - expect_true(all.equal(SeuratObject::Layers(seu), - c("counts.ctrl", "counts.stim", "ligerNormData.ctrl"))) - - expect_error(seu <- ligerToSeurat(pbmcPlot), "rawData not found") - - rawData(pbmcPlot, "ctrl") <- rawData(pbmc, "ctrl") - rawData(pbmcPlot, "stim") <- rawData(pbmc, "stim") - seu <- ligerToSeurat(pbmcPlot, identByDataset = TRUE) - } + skip_if_not_installed("Seurat") + skip_if_not_installed("SeuratObject") + seu <- ligerToSeurat(pbmc) + expect_equal(SeuratObject::Assays(seu), "RNA") + + pbmc@datasets$stim <- as.ligerDataset(pbmc@datasets$stim, modal = "atac") + pbmc <- normalize(pbmc, useDatasets = "ctrl") + seu <- ligerToSeurat(pbmc) + expect_equal(SeuratObject::Assays(seu), "LIGER") + expect_true(all.equal(SeuratObject::Layers(seu), + c("counts.ctrl", "counts.stim", "ligerNormData.ctrl"))) + + expect_error(seu <- ligerToSeurat(pbmcPlot), "rawData not found") + + rawData(pbmcPlot, "ctrl") <- rawData(pbmc, "ctrl") + rawData(pbmcPlot, "stim") <- rawData(pbmc, "stim") + seu <- ligerToSeurat(pbmcPlot, identByDataset = TRUE) }) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Importing data diff --git a/tests/testthat/test_preprocessing.R b/tests/testthat/test_preprocessing.R index 695516bc..947d1a9a 100644 --- a/tests/testthat/test_preprocessing.R +++ b/tests/testthat/test_preprocessing.R @@ -8,23 +8,27 @@ withNewH5Copy <- function(fun) { stimpath.orig <- system.file("extdata/stim.h5", package = "rliger") if (!file.exists(ctrlpath.orig)) stop("Cannot find original h5 file at: ", ctrlpath.orig) - if (file.exists("ctrltest.h5")) file.remove("ctrltest.h5") - if (file.exists("stimtest.h5")) file.remove("stimtest.h5") - pwd <- getwd() - # Temp setting for GitHub Actions - fsep <- ifelse(Sys.info()["sysname"] == "Windows", "\\", "/") - if (Sys.info()["sysname"] == "Windows") { - pwd <- file.path("C:\\Users", Sys.info()["user"], "Documents", fsep = fsep) - } - - ctrlpath <- file.path(pwd, "ctrltest.h5", fsep = fsep) - stimpath <- file.path(pwd, "stimtest.h5", fsep = fsep) + # if (file.exists("ctrltest.h5")) file.remove("ctrltest.h5") + # if (file.exists("stimtest.h5")) file.remove("stimtest.h5") + # pwd <- getwd() + # # Temp setting for GitHub Actions + # fsep <- ifelse(Sys.info()["sysname"] == "Windows", "\\", "/") + # if (Sys.info()["sysname"] == "Windows") { + # pwd <- file.path("C:\\Users", Sys.info()["user"], "Documents", fsep = fsep) + # } + + # ctrlpath <- file.path(pwd, "ctrltest.h5", fsep = fsep) + # stimpath <- file.path(pwd, "stimtest.h5", fsep = fsep) + ctrlpath <- tempfile(pattern = "ctrltest_", fileext = ".h5") + stimpath <- tempfile(pattern = "stimtest_", fileext = ".h5") cat("Working ctrl H5 file path: ", ctrlpath, "\n") cat("Working stim H5 file path: ", stimpath, "\n") file.copy(ctrlpath.orig, ctrlpath, copy.mode = TRUE) file.copy(stimpath.orig, stimpath, copy.mode = TRUE) if (!file.exists(ctrlpath)) stop("Cannot find copied h5 file at: ", ctrlpath) + if (!file.exists(stimpath)) + stop("Cannot find copied h5 file at: ", stimpath) fun(list(ctrl = ctrlpath, stim = stimpath)) @@ -105,15 +109,14 @@ test_that("QC", { pbmc <- removeMissing(pbmc, orient = "feature") expect_equal(ncol(pbmc), 600) - if (requireNamespace("DoubletFinder", quietly = TRUE)) { - pbmc.df1 <- runDoubletFinder(pbmc) - expect_is(pbmc.df1$DoubletFinder_classification, "character") - expect_is(pbmc.df1$DoubletFinder_pANN, "numeric") + skip_if_not_installed("DoubletFinder") + pbmc.df1 <- runDoubletFinder(pbmc) + expect_is(pbmc.df1$DoubletFinder_classification, "character") + expect_is(pbmc.df1$DoubletFinder_pANN, "numeric") - pbmc.df2 <- runDoubletFinder(pbmc, nExp = 0.1) - expect_false(identical(pbmc.df1$DoubletFinder_classification, - pbmc.df2$DoubletFinder_classification)) - } + pbmc.df2 <- runDoubletFinder(pbmc, nExp = 0.1) + expect_false(identical(pbmc.df1$DoubletFinder_classification, + pbmc.df2$DoubletFinder_classification)) }) context("normalization") @@ -156,6 +159,8 @@ test_that("Normalization - in-memory", { setNames(rep(1, ncol(fakeNorm)), colnames(fakeNorm)))) # Seurat method + skip_if_not_installed("Seurat") + skip_if_not_installed("SeuratObject") seu <- ligerToSeurat(pbmc, assay = "RNA") expect_no_error(normalize(seu)) }) @@ -208,9 +213,12 @@ test_that("selectGenes", { expect_is(g, "ggplot") # Seurat method - seu <- ligerToSeurat(pbmc, assay = "RNA") - seu <- normalize(seu) - expect_no_error(selectGenes(seu, nGenes = 100)) + if (requireNamespace("Seurat", quietly = TRUE) && + requireNamespace("SeuratObject", quietly = TRUE)) { + seu <- ligerToSeurat(pbmc, assay = "RNA") + seu <- normalize(seu) + expect_no_error(selectGenes(seu, nGenes = 100)) + } pbmc <- selectGenesVST(pbmc, useDataset = "ctrl", n = 50) expect_equal(length(varFeatures(pbmc)), 50) @@ -266,6 +274,8 @@ test_that("scaleNotCenter - in-memory", { pbmc.rev <- reverseMethData(pbmc, useDatasets = "ctrl") expect_true(identical(scaleData(ctrl.meth), scaleData(pbmc.rev, "ctrl"))) + skip_if_not_installed("Seurat") + skip_if_not_installed("SeuratObject") seu <- ligerToSeurat(pbmc, assay = "RNA") seu <- normalize(seu) seu <- selectGenes(seu, datasetVar = "orig.ident") diff --git a/tests/testthat/test_subset.R b/tests/testthat/test_subset.R index 83d6c43d..8954c0fe 100644 --- a/tests/testthat/test_subset.R +++ b/tests/testthat/test_subset.R @@ -1,4 +1,3 @@ -has_RcppPlanc <- requireNamespace("RcppPlanc", quietly = TRUE) data("pbmc", package = "rliger") withNewH5Copy <- function(fun) { @@ -6,19 +5,27 @@ withNewH5Copy <- function(fun) { stimpath.orig <- system.file("extdata/stim.h5", package = "rliger") if (!file.exists(ctrlpath.orig)) stop("Cannot find original h5 file at: ", ctrlpath.orig) - if (file.exists("ctrltest.h5")) file.remove("ctrltest.h5") - if (file.exists("stimtest.h5")) file.remove("stimtest.h5") - pwd <- tempdir() - fsep <- ifelse(Sys.info()["sysname"] == "Windows", "\\", "/") + # if (file.exists("ctrltest.h5")) file.remove("ctrltest.h5") + # if (file.exists("stimtest.h5")) file.remove("stimtest.h5") + # pwd <- getwd() + # # Temp setting for GitHub Actions + # fsep <- ifelse(Sys.info()["sysname"] == "Windows", "\\", "/") + # if (Sys.info()["sysname"] == "Windows") { + # pwd <- file.path("C:\\Users", Sys.info()["user"], "Documents", fsep = fsep) + # } - ctrlpath <- file.path(pwd, "ctrltest.h5", fsep = fsep) - stimpath <- file.path(pwd, "stimtest.h5", fsep = fsep) + # ctrlpath <- file.path(pwd, "ctrltest.h5", fsep = fsep) + # stimpath <- file.path(pwd, "stimtest.h5", fsep = fsep) + ctrlpath <- tempfile(pattern = "ctrltest_", fileext = ".h5") + stimpath <- tempfile(pattern = "stimtest_", fileext = ".h5") cat("Working ctrl H5 file path: ", ctrlpath, "\n") cat("Working stim H5 file path: ", stimpath, "\n") file.copy(ctrlpath.orig, ctrlpath, copy.mode = TRUE) file.copy(stimpath.orig, stimpath, copy.mode = TRUE) if (!file.exists(ctrlpath)) stop("Cannot find copied h5 file at: ", ctrlpath) + if (!file.exists(stimpath)) + stop("Cannot find copied h5 file at: ", stimpath) fun(list(ctrl = ctrlpath, stim = stimpath)) @@ -52,7 +59,7 @@ context("subset liger object") test_that("subsetLiger", { expect_message(a <- subsetLiger("a"), "`object` is not a ") expect_identical(a, "a") - skip_if_not(has_RcppPlanc) + skip_if_not_installed("RcppPlanc") pbmc <- process(pbmc) expect_error(subsetLiger(pbmc, featureIdx = 1:3), "Feature subscription from a") @@ -67,9 +74,11 @@ test_that("subsetLiger", { context("subset ligerDataset object") test_that("subsetH5LigerDataset", { - skip_if_not(has_RcppPlanc) + skip_if_not_installed("RcppPlanc") withNewH5Copy( function(rawList, arg1, arg2) { + ctrlfile <- rawList$ctrl + stimfile <- rawList$stim pbmcH5 <- createLiger(rawList) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%% # Then whatever test with pbmc. For example: @@ -116,7 +125,7 @@ test_that("subsetH5LigerDataset", { ctrlSmallH5 <- rliger:::subsetH5LigerDataset( ctrl, 1:20, 1:20, filenameSuffix = "small2" ) - newPath <- file.path(path, "ctrltest.h5.small2.h5") + newPath <- paste0(ctrlfile, ".small2.h5") expect_true(file.exists(newPath)) unlink(newPath) expect_no_error( @@ -124,7 +133,7 @@ test_that("subsetH5LigerDataset", { useSlot = "normData", filenameSuffix = "small3") ) - newPath <- file.path(path, "ctrltest.h5.small3.h5") + newPath <- paste0(ctrlfile, ".small3.h5") expect_true(file.exists(newPath)) unlink(newPath) expect_no_error( diff --git a/tests/testthat/test_visualization.R b/tests/testthat/test_visualization.R index a9f0c6f8..b8b461db 100644 --- a/tests/testthat/test_visualization.R +++ b/tests/testthat/test_visualization.R @@ -5,23 +5,27 @@ withNewH5Copy <- function(fun) { stimpath.orig <- system.file("extdata/stim.h5", package = "rliger") if (!file.exists(ctrlpath.orig)) stop("Cannot find original h5 file at: ", ctrlpath.orig) - if (file.exists("ctrltest.h5")) file.remove("ctrltest.h5") - if (file.exists("stimtest.h5")) file.remove("stimtest.h5") - pwd <- getwd() - # Temp setting for GitHub Actions - fsep <- ifelse(Sys.info()["sysname"] == "Windows", "\\", "/") - if (Sys.info()["sysname"] == "Windows") { - pwd <- file.path("C:\\Users", Sys.info()["user"], "Documents", fsep = fsep) - } + # if (file.exists("ctrltest.h5")) file.remove("ctrltest.h5") + # if (file.exists("stimtest.h5")) file.remove("stimtest.h5") + # pwd <- getwd() + # # Temp setting for GitHub Actions + # fsep <- ifelse(Sys.info()["sysname"] == "Windows", "\\", "/") + # if (Sys.info()["sysname"] == "Windows") { + # pwd <- file.path("C:\\Users", Sys.info()["user"], "Documents", fsep = fsep) + # } - ctrlpath <- file.path(pwd, "ctrltest.h5", fsep = fsep) - stimpath <- file.path(pwd, "stimtest.h5", fsep = fsep) + # ctrlpath <- file.path(pwd, "ctrltest.h5", fsep = fsep) + # stimpath <- file.path(pwd, "stimtest.h5", fsep = fsep) + ctrlpath <- tempfile(pattern = "ctrltest_", fileext = ".h5") + stimpath <- tempfile(pattern = "stimtest_", fileext = ".h5") cat("Working ctrl H5 file path: ", ctrlpath, "\n") cat("Working stim H5 file path: ", stimpath, "\n") file.copy(ctrlpath.orig, ctrlpath, copy.mode = TRUE) file.copy(stimpath.orig, stimpath, copy.mode = TRUE) if (!file.exists(ctrlpath)) stop("Cannot find copied h5 file at: ", ctrlpath) + if (!file.exists(stimpath)) + stop("Cannot find copied h5 file at: ", stimpath) fun(list(ctrl = ctrlpath, stim = stimpath)) @@ -77,7 +81,10 @@ test_that("scatter plots", { plotDimRed(pbmcPlot, colorBy = "S100A8", slot = "normData", trimHigh = 5, trimLow = 0), plotDimRed(pbmcPlot, colorBy = "leiden_cluster", shapeBy = "dataset"), - plotDimRed(pbmcPlot, colorBy = NULL, shapeBy = "dataset"), + plotDimRed(pbmcPlot, colorBy = NULL, shapeBy = "dataset") + ) + skip_if_not_installed("scattermore") + expect_gg( plotDimRed(pbmcPlot, colorBy = "leiden_cluster", raster = TRUE) ) }) @@ -94,15 +101,17 @@ test_that("Violin plots", { dotColor = NULL), "list") expect_gg( plotGeneViolin(pbmcPlot, "S100A8", byDataset = FALSE), - plotTotalCountViolin(pbmc, dot = TRUE), - plotGeneDetectedViolin(pbmc, dot = TRUE, dotColor = NULL, - raster = TRUE) + plotTotalCountViolin(pbmc, dot = TRUE) ) # General - expect_gg(plotCellViolin(pbmcPlot, "nUMI", groupBy = NULL, - colorBy = "leiden_cluster", box = TRUE, dot = TRUE, - raster = TRUE)) + skip_if_not_installed("scattermore") + expect_gg( + plotGeneDetectedViolin(pbmc, dot = TRUE, dotColor = NULL, raster = TRUE), + plotCellViolin(pbmcPlot, "nUMI", groupBy = NULL, + colorBy = "leiden_cluster", box = TRUE, dot = TRUE, + raster = TRUE) + ) }) #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/vignettes/articles/STARmap_dropviz_vig.Rmd b/vignettes/articles/STARmap_dropviz_vig.Rmd index d19ca630..921123f8 100644 --- a/vignettes/articles/STARmap_dropviz_vig.Rmd +++ b/vignettes/articles/STARmap_dropviz_vig.Rmd @@ -66,8 +66,10 @@ Unshared Integrative Non-negative Matrix Factorization (UINMF) can be applied wi In this tutorial, we set dataset specific lambda (regularization parameter) values to penalize the dataset specific effect differently. +Another noteworthy advantage of UINMF is that we are able to use a larger number of factors than there are shared features. We captilize on this by changing the default value of `k` to 40. + ```{r factorization} -lig <- runUINMF(lig, k = 25, lambda = c(10, 1)) +lig <- runUINMF(lig, k = 40, lambda = c(10, 1)) ``` ## Step 4: Quantile Normalization and Joint Clustering