diff --git a/DESCRIPTION b/DESCRIPTION index ebf7d59..7e4bd92 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: UCell Type: Package Title: Rank-based signature enrichment analysis for single-cell data -Version: 2.7.2 +Version: 2.7.3 Authors@R: c( person('Massimo', 'Andreatta', email = 'massimo.andreatta@unil.ch', @@ -17,7 +17,7 @@ Description: UCell is a package for evaluating gene signatures in single-cell da demands less computing time and memory than other available methods, enabling the processing of large datasets in a few minutes even on machines with limited computing power. UCell can be applied to any single-cell data matrix, and includes functions to directly interact with SingleCellExperiment and Seurat objects. -Depends: R(>= 4.2.0) +Depends: R(>= 4.3.0) Imports: methods, data.table(>= 1.13.6), Matrix, @@ -26,7 +26,7 @@ Imports: methods, BiocNeighbors, SingleCellExperiment, SummarizedExperiment -Suggests: Seurat, +Suggests: Seurat(>= 5.0.0), scater, scRNAseq, reshape2, diff --git a/R/AddModuleScore_UCell.R b/R/AddModuleScore_UCell.R index 6da2ecb..e1217e5 100644 --- a/R/AddModuleScore_UCell.R +++ b/R/AddModuleScore_UCell.R @@ -27,8 +27,7 @@ #' importance to negative genes #' @param assay Pull out data from this assay of the Seurat object #' (if NULL, use \code{DefaultAssay(obj)}) -#' @param slot Pull out data from this slot of the Seurat object (will -#' become "layer" in Seurat v5) +#' @param slot Pull out data from this slot (layer in v5) of the Seurat object #' @param chunk.size Number of cells to be processed simultaneously (lower #' size requires slightly more computation but reduces memory demands) #' @param BPPARAM A [BiocParallel::bpparam()] object that tells UCell @@ -70,52 +69,46 @@ AddModuleScore_UCell <- function(obj, features, maxRank=1500, chunk.size=1000, BPPARAM=NULL, ncores=1, storeRanks=FALSE, w_neg=1, assay=NULL, slot="counts", ties.method="average", force.gc=FALSE, name="_UCell") { - if (!requireNamespace("Seurat", quietly = TRUE)) { stop("Function 'AddModuleScore_UCell' requires the Seurat package. Please install it.", call. = FALSE) } - features <- check_signature_names(features) - if (is.null(assay)) { assay <- Seurat::DefaultAssay(obj) } - - # If rank matrix was pre-computed, evaluate the new signatures - # from these ranks. Else, calculate new ranks to score signatures - # (optionally storing ranks, takes up more memory but become very - # fast to evaluate further signatures) + # from these ranks. if ("UCellRanks" %in% Seurat::Assays(obj)) { meta.list <- rankings2Uscore( - Seurat::GetAssayData(obj, "counts", assay="UCellRanks"), + Seurat::GetAssayData(obj, layer="counts", assay="UCellRanks"), features=features, chunk.size=chunk.size, w_neg=w_neg, ncores=ncores, BPPARAM=BPPARAM, force.gc=force.gc, name=name) - } else { - meta.list <- calculate_Uscore( - Seurat::GetAssayData(obj, slot, assay=assay), + layers <- SeuratObject::Layers(obj, assay=assay, search = slot) + if (is.null(layers)) { + stop(sprintf("Cannot find layer %s in assay %s", slot, assay)) + } + meta.list <- lapply(layers, function(x) { + calculate_Uscore( + Seurat::GetAssayData(obj, layer=x, assay=assay), features=features, maxRank=maxRank, chunk.size=chunk.size, w_neg=w_neg, ncores=ncores, BPPARAM=BPPARAM, ties.method=ties.method, force.gc=force.gc, storeRanks=storeRanks, name=name) - + }) + meta.list <- unlist(meta.list, recursive = FALSE) #store ranks matrix? if (storeRanks==TRUE){ cells_rankings.merge <- lapply(meta.list, function(x) rbind(x[["cells_rankings"]])) cells_rankings.merge <- Reduce(cbind, cells_rankings.merge) - obj[["UCellRanks"]] <- Seurat::CreateAssayObject( cells_rankings.merge) } } - meta.merge <- lapply(meta.list,function(x) rbind(x[["cells_AUC"]])) meta.merge <- Reduce(rbind, meta.merge) - obj <- Seurat::AddMetaData(obj, as.data.frame(meta.merge)) - return(obj) } diff --git a/R/HelperFunctions.R b/R/HelperFunctions.R index 0faeecb..2894fed 100644 --- a/R/HelperFunctions.R +++ b/R/HelperFunctions.R @@ -419,10 +419,8 @@ SmoothKNN.Seurat <- function( } m <- obj[[found]] } else { # Work directly on features - - exp <- Seurat::GetAssayData(obj, assay=assay, slot=slot) + exp <- Seurat::GetAssayData(obj, layer=slot, assay=assay) feats <- rownames(exp) - found <- intersect(signature.names, feats) notfound <- setdiff(signature.names, found) @@ -435,7 +433,6 @@ SmoothKNN.Seurat <- function( assay, nf) warning(mess, immediate.=TRUE, call.=FALSE, noBreaks.=TRUE) } - m <- t(exp[found, , drop=FALSE]) } ncells <- ncol(obj) diff --git a/man/AddModuleScore_UCell.Rd b/man/AddModuleScore_UCell.Rd index 761edbb..261f64b 100644 --- a/man/AddModuleScore_UCell.Rd +++ b/man/AddModuleScore_UCell.Rd @@ -53,8 +53,7 @@ importance to negative genes} \item{assay}{Pull out data from this assay of the Seurat object (if NULL, use \code{DefaultAssay(obj)})} -\item{slot}{Pull out data from this slot of the Seurat object (will -become "layer" in Seurat v5)} +\item{slot}{Pull out data from this slot (layer in v5) of the Seurat object} \item{ties.method}{How ranking ties should be resolved - passed on to \link[data.table:frank]{data.table::frank}}