From 3c9b51392f662d57815fbfd7fc636bd27467a0af Mon Sep 17 00:00:00 2001 From: bbimber Date: Wed, 20 Dec 2023 15:46:49 -0800 Subject: [PATCH 1/3] Add new LogNormalizeUsingAlternateAssay method --- NAMESPACE | 1 + R/Preprocessing.R | 36 ++++++++++++++++++++++++++ man/LogNormalizeUsingAlternateAssay.Rd | 28 ++++++++++++++++++++ tests/testthat/test-seurat.R | 20 +++++++++++++- 4 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 man/LogNormalizeUsingAlternateAssay.Rd diff --git a/NAMESPACE b/NAMESPACE index 0a2bd9d6..bb5b032d 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -31,6 +31,7 @@ export(GetSeed) export(GetXYDataFromPlot) export(HighlightCellsOnSeuratPlot) export(InspectSeurat) +export(LogNormalizeUsingAlternateAssay) export(MakeEnrichmentDotPlot) export(MergeSeuratObjs) export(NanoString_Housekeeping_Normalization) diff --git a/R/Preprocessing.R b/R/Preprocessing.R index 2b7d770d..93d5974b 100644 --- a/R/Preprocessing.R +++ b/R/Preprocessing.R @@ -293,4 +293,40 @@ PerformEmptyDrops <- function(seuratRawData, emptyDropNIters, fdrThreshold=0.001 } stop(paste0('Unable to find matrix file in: ', dataDir, ' or ', dirWithFeatureMatrix)) +} + +#' @title LogNormalizeUsingAlternateAssay +#' +#' @param seuratObject The seurat object +#' @param assayToNormalize The name of the assay to normalize +#' @param assayForLibrarySize The name of the assay from which to derive library sizes. This will be added to the library size of assayToNormalize. +#' @param scale.factor A scale factor to be applied in normalization +#' @param maxLibrarySizeRatio This normalization relies on the assumption that the library size of the assay being normalized in negligible relative to the assayForLibrarySize. To verify this holds true, the method will error if librarySize(assayToNormalize)/librarySize(assayForLibrarySize) exceeds this value +#' @export +LogNormalizeUsingAlternateAssay <- function(seuratObj, assayToNormalize, assayForLibrarySize = 'RNA', scale.factor = 1e4, maxLibrarySizeRatio = 0.006) { + toNormalize <- Seurat::GetAssayData(seuratObj, assayToNormalize, slot = 'counts') + assayForLibrarySizeData <- Seurat::GetAssayData(seuratObj, assay = assayForLibrarySize, slot = 'counts') + + if (any(colnames(toNormalize) != colnames(assayForLibrarySize))) { + stop(paste0('The assayToNormalize and assayForLibrarySize do not have the same cell names!')) + } + + margin <- 2 + ncells <- dim(x = toNormalize)[margin] + + for (i in seq_len(length.out = ncells)) { + x <- toNormalize[, i] + librarySize <- sum(x) + sum(assayForLibrarySizeData[, i]) + + if ((sum(x) / librarySize) > maxLibrarySizeRatio) { + stop(paste0('The ratio of library sizes was above maxLibrarySizeRatio for cell: ', colnames(assayForLibrarySizeData)[i], '. was: ', (sum(x) / librarySize), ' (', sum(x), ' / ', librarySize, ')')) + } + + xnorm <- log1p(x = x / librarySize * scale.factor) + toNormalize[, i] <- xnorm + } + + seuratObj <- Seurat::SetAssayData(seuratObj, assay = assayToNormalize, slot = 'data', new.data = toNormalize) + + return(seuratObj) } \ No newline at end of file diff --git a/man/LogNormalizeUsingAlternateAssay.Rd b/man/LogNormalizeUsingAlternateAssay.Rd new file mode 100644 index 00000000..87a59456 --- /dev/null +++ b/man/LogNormalizeUsingAlternateAssay.Rd @@ -0,0 +1,28 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/Preprocessing.R +\name{LogNormalizeUsingAlternateAssay} +\alias{LogNormalizeUsingAlternateAssay} +\title{LogNormalizeUsingAlternateAssay} +\usage{ +LogNormalizeUsingAlternateAssay( + seuratObj, + assayToNormalize, + assayForLibrarySize = "RNA", + scale.factor = 10000, + maxLibrarySizeRatio = 0.006 +) +} +\arguments{ +\item{assayToNormalize}{The name of the assay to normalize} + +\item{assayForLibrarySize}{The name of the assay from which to derive library sizes. This will be added to the library size of assayToNormalize.} + +\item{scale.factor}{A scale factor to be applied in normalization} + +\item{maxLibrarySizeRatio}{This normalization relies on the assumption that the library size of the assay being normalized in negligible relative to the assayForLibrarySize. To verify this holds true, the method will error if librarySize(assayToNormalize)/librarySize(assayForLibrarySize) exceeds this value} + +\item{seuratObject}{The seurat object} +} +\description{ +LogNormalizeUsingAlternateAssay +} diff --git a/tests/testthat/test-seurat.R b/tests/testthat/test-seurat.R index adf89042..a6cdf07b 100644 --- a/tests/testthat/test-seurat.R +++ b/tests/testthat/test-seurat.R @@ -1,4 +1,4 @@ -library(DropletUtils); +library(DropletUtils) context("scRNAseq") @@ -124,4 +124,22 @@ test_that("Serat SCTransform works as expected", { expect_equal(length(rownames(seuratObjSCT@assays$SCT@scale.data)), length(rownames(seuratObjSCT@assays$SCT@counts))) expect_equal(ncol(seuratObjSCT), ncol(seuratObj)) +}) + + +test_that("LogNormalizeUsingAlternateAssay works as expected", { + seuratObj <- suppressWarnings(Seurat::UpdateSeuratObject(readRDS('../testdata/seuratOutput.rds'))) + + assayToAdd <- Seurat::GetAssayData(seuratObj, assay = 'RNA', layer = 'counts') + assayToAdd <- assayToAdd[1:10,] + assayToAdd <- assayToAdd / 50 + rownames(assayToAdd) <- paste0('Feature', LETTERS[1:10]) + + seuratObj[['Norm']] <- Seurat::CreateAssayObject(assayToAdd) + + seuratObj <- LogNormalizeUsingAlternateAssay(seuratObj, assayToNormalize = 'Norm', assayForLibrarySize = 'RNA') + + nd <- Seurat::GetAssayData(seuratObj, assay = 'Norm', layer = 'data') + expect_equal(max(nd[,2]), 0.3087937) + expect_equal(max(nd[,100]), 0.7821186) }) \ No newline at end of file From 6d8ab15f2089ff26ff57de12cd453e57f3f240f3 Mon Sep 17 00:00:00 2001 From: bbimber Date: Wed, 20 Dec 2023 16:02:37 -0800 Subject: [PATCH 2/3] Update test --- R/Preprocessing.R | 2 +- man/LogNormalizeUsingAlternateAssay.Rd | 2 +- tests/testthat/test-seurat.R | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/R/Preprocessing.R b/R/Preprocessing.R index 93d5974b..c75a9e77 100644 --- a/R/Preprocessing.R +++ b/R/Preprocessing.R @@ -303,7 +303,7 @@ PerformEmptyDrops <- function(seuratRawData, emptyDropNIters, fdrThreshold=0.001 #' @param scale.factor A scale factor to be applied in normalization #' @param maxLibrarySizeRatio This normalization relies on the assumption that the library size of the assay being normalized in negligible relative to the assayForLibrarySize. To verify this holds true, the method will error if librarySize(assayToNormalize)/librarySize(assayForLibrarySize) exceeds this value #' @export -LogNormalizeUsingAlternateAssay <- function(seuratObj, assayToNormalize, assayForLibrarySize = 'RNA', scale.factor = 1e4, maxLibrarySizeRatio = 0.006) { +LogNormalizeUsingAlternateAssay <- function(seuratObj, assayToNormalize, assayForLibrarySize = 'RNA', scale.factor = 1e4, maxLibrarySizeRatio = 0.01) { toNormalize <- Seurat::GetAssayData(seuratObj, assayToNormalize, slot = 'counts') assayForLibrarySizeData <- Seurat::GetAssayData(seuratObj, assay = assayForLibrarySize, slot = 'counts') diff --git a/man/LogNormalizeUsingAlternateAssay.Rd b/man/LogNormalizeUsingAlternateAssay.Rd index 87a59456..b20f29fa 100644 --- a/man/LogNormalizeUsingAlternateAssay.Rd +++ b/man/LogNormalizeUsingAlternateAssay.Rd @@ -9,7 +9,7 @@ LogNormalizeUsingAlternateAssay( assayToNormalize, assayForLibrarySize = "RNA", scale.factor = 10000, - maxLibrarySizeRatio = 0.006 + maxLibrarySizeRatio = 0.01 ) } \arguments{ diff --git a/tests/testthat/test-seurat.R b/tests/testthat/test-seurat.R index a6cdf07b..3f944fe4 100644 --- a/tests/testthat/test-seurat.R +++ b/tests/testthat/test-seurat.R @@ -131,8 +131,8 @@ test_that("LogNormalizeUsingAlternateAssay works as expected", { seuratObj <- suppressWarnings(Seurat::UpdateSeuratObject(readRDS('../testdata/seuratOutput.rds'))) assayToAdd <- Seurat::GetAssayData(seuratObj, assay = 'RNA', layer = 'counts') - assayToAdd <- assayToAdd[1:10,] - assayToAdd <- assayToAdd / 50 + assayToAdd <- floor(assayToAdd[1:10,] / 5) + rownames(assayToAdd) <- paste0('Feature', LETTERS[1:10]) seuratObj[['Norm']] <- Seurat::CreateAssayObject(assayToAdd) @@ -140,6 +140,6 @@ test_that("LogNormalizeUsingAlternateAssay works as expected", { seuratObj <- LogNormalizeUsingAlternateAssay(seuratObj, assayToNormalize = 'Norm', assayForLibrarySize = 'RNA') nd <- Seurat::GetAssayData(seuratObj, assay = 'Norm', layer = 'data') - expect_equal(max(nd[,2]), 0.3087937) - expect_equal(max(nd[,100]), 0.7821186) + expect_equal(max(nd[,4]), 3.442982, tolerance = 0.000001) + expect_equal(max(nd[,101]), 2.823479, tolerance = 0.000001) }) \ No newline at end of file From 8b28097726e58ba4c7828a544445f4f4c68bb492 Mon Sep 17 00:00:00 2001 From: bbimber Date: Wed, 20 Dec 2023 16:38:19 -0800 Subject: [PATCH 3/3] Fix docs --- R/Preprocessing.R | 2 +- man/LogNormalizeUsingAlternateAssay.Rd | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/R/Preprocessing.R b/R/Preprocessing.R index c75a9e77..1c3c1329 100644 --- a/R/Preprocessing.R +++ b/R/Preprocessing.R @@ -297,7 +297,7 @@ PerformEmptyDrops <- function(seuratRawData, emptyDropNIters, fdrThreshold=0.001 #' @title LogNormalizeUsingAlternateAssay #' -#' @param seuratObject The seurat object +#' @param seuratObj The seurat object #' @param assayToNormalize The name of the assay to normalize #' @param assayForLibrarySize The name of the assay from which to derive library sizes. This will be added to the library size of assayToNormalize. #' @param scale.factor A scale factor to be applied in normalization diff --git a/man/LogNormalizeUsingAlternateAssay.Rd b/man/LogNormalizeUsingAlternateAssay.Rd index b20f29fa..4bd2e980 100644 --- a/man/LogNormalizeUsingAlternateAssay.Rd +++ b/man/LogNormalizeUsingAlternateAssay.Rd @@ -13,6 +13,8 @@ LogNormalizeUsingAlternateAssay( ) } \arguments{ +\item{seuratObj}{The seurat object} + \item{assayToNormalize}{The name of the assay to normalize} \item{assayForLibrarySize}{The name of the assay from which to derive library sizes. This will be added to the library size of assayToNormalize.} @@ -20,8 +22,6 @@ LogNormalizeUsingAlternateAssay( \item{scale.factor}{A scale factor to be applied in normalization} \item{maxLibrarySizeRatio}{This normalization relies on the assumption that the library size of the assay being normalized in negligible relative to the assayForLibrarySize. To verify this holds true, the method will error if librarySize(assayToNormalize)/librarySize(assayForLibrarySize) exceeds this value} - -\item{seuratObject}{The seurat object} } \description{ LogNormalizeUsingAlternateAssay