From d5ed45d8f71280726381bc9020eb1bca44317a93 Mon Sep 17 00:00:00 2001 From: Ryan Corces Date: Fri, 15 Apr 2022 09:29:29 -0700 Subject: [PATCH 1/4] make .safeSubset flexible to matrix and dgCMatrix input rbind fails if mat isnt a sparseMatrix. this change makes safeSubset flexible to accept either matrix or dgCMatrix input --- R/HiddenUtils.R | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/R/HiddenUtils.R b/R/HiddenUtils.R index 57fdad35..f5129b98 100644 --- a/R/HiddenUtils.R +++ b/R/HiddenUtils.R @@ -188,8 +188,18 @@ idxNotIn <- which(subsetRows %ni% rownames(mat)) if(length(idxNotIn) > 0){ subsetNamesNotIn <- subsetRows[idxNotIn] - matNotIn <- Matrix::sparseMatrix(i=1,j=1,x=0,dims=c(length(idxNotIn), ncol = ncol(mat))) + + #check matrix class and make a matching empty matrix for the idxNotIn rows + if (class(mat)[[1]] == "dgCMatrix") { + matNotIn <- Matrix::sparseMatrix(i = 1, j = 1, x = 0, dims = c(length(idxNotIn), ncol = ncol(mat))) + } else if (class(mat)[[1]] == "matrix") { + matNotIn <- matrix(nrow = length(idxNotIn), ncol = ncol(mat), 0) + } else{ + stop("Error! Argument 'mat' in .safeSubset is not either of class matrix or class dgCMatrix!") + } + rownames(matNotIn) <- subsetNamesNotIn + colnames(matNotIn) <- colnames(mat) mat <- rbind(mat, matNotIn) } mat <- mat[subsetRows,] @@ -199,7 +209,16 @@ idxNotIn <- which(subsetCols %ni% colnames(mat)) if(length(idxNotIn) > 0){ subsetNamesNotIn <- subsetCols[idxNotIn] - matNotIn <- Matrix::sparseMatrix(i=1,j=1,x=0,dims=c(nrow(mat), ncol = length(idxNotIn))) + + #check matrix class and make a matching empty matrix for the idxNotIn rows + if (class(mat)[[1]] == "dgCMatrix") { + matNotIn <- Matrix::sparseMatrix(i = 1, j = 1, x = 0, dims = c(nrow(mat), ncol = length(idxNotIn))) + } else if (class(mat)[[1]] == "matrix") { + matNotIn <- matrix(nrow = nrow(mat), ncol = length(idxNotIn), 0) + } else{ + stop("Error! Argument 'mat' in .safeSubset is not either of class matrix or class dgCMatrix!") + } + rownames(matNotIn) <- rownames(mat) colnames(matNotIn) <- subsetNamesNotIn mat <- cbind(mat, matNotIn) } From 3663b50248fac50da5bdd0106f14cede5f933bc6 Mon Sep 17 00:00:00 2001 From: Ryan Corces Date: Fri, 15 Apr 2022 09:31:03 -0700 Subject: [PATCH 2/4] force a matrix to be passed to safeSubset related to https://github.com/GreenleafLab/ArchR/commit/d5ed45d8f71280726381bc9020eb1bca44317a93 --- R/BulkProjection.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/BulkProjection.R b/R/BulkProjection.R index 882dd9a4..c80352d2 100644 --- a/R/BulkProjection.R +++ b/R/BulkProjection.R @@ -81,7 +81,7 @@ projectBulkATAC <- function( # Create Bulk Matrix ################################################## bulkMat <- .safeSubset( - mat = .getAssay(subATAC, "counts"), + mat = as.matrix(.getAssay(subATAC, "counts")), subsetRows = paste0("f", seq_along(rDGR)) ) .logThis(bulkMat, "bulkATACMat", logFile = logFile) From a7abaa429d567482b09982a35cbdff3c61769938 Mon Sep 17 00:00:00 2001 From: Ryan Corces Date: Fri, 15 Apr 2022 09:33:59 -0700 Subject: [PATCH 3/4] params must be a list, not a vector the params section of ArchRProj@embeddings needs to be a list rather than a vector. If a vector, when you try to pass a vector to dimsToUse, you cant have a vector of a vector so this gets converted to dimsToUse1, dimsToUse2, dimsToUse3 etc instead of dimsToUse = c(1,2,3). Discussed in https://github.com/GreenleafLab/ArchR/issues/1379#issuecomment-1099899524 --- R/Embedding.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/Embedding.R b/R/Embedding.R index c71026f4..f32930b5 100644 --- a/R/Embedding.R +++ b/R/Embedding.R @@ -170,7 +170,7 @@ addUMAP <- function( ArchRProj@embeddings[[name]] <- SimpleList( df = dfEmbedding, - params = c( + params = list( embeddingParams, dimsToUse = dimsToUse, scaleDims = scaleDims, @@ -189,7 +189,7 @@ addUMAP <- function( embeddingParams$X <- NULL ArchRProj@embeddings[[name]] <- SimpleList( df = dfEmbedding, - params = c( + params = list( embeddingParams, dimsToUse = dimsToUse, scaleDims = scaleDims, From 9db334ef3180f32e056f40b3e7c688194948d968 Mon Sep 17 00:00:00 2001 From: Ryan Corces Date: Fri, 15 Apr 2022 09:54:54 -0700 Subject: [PATCH 4/4] fix logic of dimsToUse in projectBulkATAC dimsToUse has to be the intersection of the dimensions that pass corCutOff and the dimensions originally listed in dimsToUse. also, the column subsetting of simRD has to happen before the second if statement to check if the dimensions match, otherwise this if statement will always fail and exit with an error --- R/BulkProjection.R | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/R/BulkProjection.R b/R/BulkProjection.R index c80352d2..c60f4e10 100644 --- a/R/BulkProjection.R +++ b/R/BulkProjection.R @@ -145,13 +145,15 @@ projectBulkATAC <- function( if(!is.null(corCutOff)){ if(scaleDims){ corToDepth <- rD$corToDepth$scaled - dimsToUse <- dimsToUse[corToDepth < corCutOff] + dimsToUse <- dimsToUse[intersect(dimsToUse, which(corToDepth < corCutOff))] }else{ corToDepth <- rD$corToDepth$none - dimsToUse <- dimsToUse[corToDepth < corCutOff] + dimsToUse <- dimsToUse[intersect(dimsToUse, which(corToDepth < corCutOff))] } } + simRD <- simRD[, dimsToUse, drop = FALSE] + if(embedding$params$nc != ncol(simRD)){ .logMessage("Error! Inconsistency found with matching LSI dimensions to those used in addUMAP or addTSNE", "\nReturning with simulated reduced dimension coordinates...", verbose = TRUE, logFile = logFile) @@ -161,8 +163,6 @@ projectBulkATAC <- function( return(out) } - simRD <- simRD[, dimsToUse, drop = FALSE] - } ##################################################