Skip to content

Commit

Permalink
Merge pull request #25 from AlexsLemonade/jashapiro/single-feature-se…
Browse files Browse the repository at this point in the history
…urat

Add dummy feature for nrow=1 altExps
  • Loading branch information
jashapiro authored Dec 19, 2024
2 parents 2deaa20 + c1ee969 commit 42ede0f
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 3 deletions.
52 changes: 49 additions & 3 deletions R/make-seurat.R
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,22 @@ sce_to_seurat <- function(
# add altExps as needed.
for (alt_exp_name in names(alt_exps)) {
alt_exp <- alt_exps[[alt_exp_name]]
stopifnot(
"All altExps must contain a `counts` assay." = "counts" %in% assayNames(alt_exp)
)

if (!"counts" %in% assayNames(alt_exp)) {
warning(
"The altExp `", alt_exp_name,
"` does not have a `counts` assay, so it will be skipped."
)
next
}

if (nrow(alt_exp) == 1 && seurat_assay_version == "v5") {
warning(
"The altExp `", alt_exp_name, "` has only one feature;",
" for Seurat v5 compatibility, a dummy feature will be added with all zero counts."
)
alt_exp <- add_dummy_feature(alt_exp)
}

# check name compatibility for Seurat
alt_exp_rownames <- rownames(alt_exp)
Expand Down Expand Up @@ -167,3 +180,36 @@ sce_to_seurat <- function(

return(sobj)
}


#' Add a dummy feature to a SingleCellExperiment object with all zeros
#'
#' @param sce A SingleCellExperiment object. Should contain only one row/feature.
#' If larger, it will be returned unmodified.
#' @param feature_name The name to give to the new dummy feature
#'
#' @returns A SingleCellExperiment object with a dummy feature added (all zeros)
add_dummy_feature <- function(sce, feature_name = "null-feature") {
# add a dummy feature an SCE object
if (nrow(sce) > 1) {
message(
"No need for a dummy feature in a SingleCellExperiment object",
" with more than one row. Returning original object."
)
return(sce)
}
if (feature_name %in% rownames(sce)) {
stop("A feature named `", feature_name, "` already exists in the SingleCellExperiment object.")
}

# duplicate the existing row, rename
sce <- sce[c(1, 1), ]
rownames(sce) <- c(rownames(sce)[1], feature_name)
# set all rowData to NA, all assays to 0
rowData(sce)[feature_name, ] <- NA
assays(sce) <- assays(sce) |> purrr::map(\(x) {
x[feature_name, ] <- 0
return(x)
})
return(sce)
}
20 changes: 20 additions & 0 deletions man/add_dummy_feature.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions rOpenScPCA.Rproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Version: 1.0
ProjectId: e30188e8-608a-431a-87d2-5349807b3970

RestoreWorkspace: No
SaveWorkspace: No
Expand Down
41 changes: 41 additions & 0 deletions tests/testthat/test-make-seurat.R
Original file line number Diff line number Diff line change
Expand Up @@ -238,3 +238,44 @@ test_that("Conversion works for non-processed samples", {

expect_null(names(seurat_obj@reductions))
})

test_that("conversion works with 1 feature altExps", {
sce <- readRDS(test_path("data", "scpca_sce.rds"))
altsce <- sce[1, ]
rownames(altsce) <- c("F1")
altExps(sce) <- list(
alt1 = altsce
)

expect_warning(seurat_obj <- sce_to_seurat(sce, use_symbols = FALSE))
expect_s4_class(seurat_obj, "Seurat")

expect_setequal(names(seurat_obj@assays), c("RNA", "spliced", "alt1"))
expect_equal(Seurat::DefaultAssay(seurat_obj), "RNA")

# assay types
expect_s4_class(seurat_obj[["RNA"]], "Assay5")
expect_s4_class(seurat_obj[["spliced"]], "Assay5")
expect_s4_class(seurat_obj[["alt1"]], "Assay5")

expect_equal(nrow(seurat_obj[["alt1"]]), 2)
expect_setequal(rownames(seurat_obj[["alt1"]]), c("F1", "null-feature"))
expect_setequal(colnames(seurat_obj[["alt1"]]), colnames(sce))


# test v3 conversion does not add a row
expect_no_warning(seurat_obj <- sce_to_seurat(sce, use_symbols = FALSE, seurat_assay_version = "v3"))
expect_s4_class(seurat_obj, "Seurat")

expect_setequal(names(seurat_obj@assays), c("RNA", "spliced", "alt1"))
expect_equal(Seurat::DefaultAssay(seurat_obj), "RNA")

# assay types
expect_s4_class(seurat_obj[["RNA"]], "Assay")
expect_s4_class(seurat_obj[["spliced"]], "Assay")
expect_s4_class(seurat_obj[["alt1"]], "Assay")

expect_equal(nrow(seurat_obj[["alt1"]]), 1)
expect_setequal(rownames(seurat_obj[["alt1"]]), c("F1"))
expect_setequal(colnames(seurat_obj[["alt1"]]), colnames(sce))
})

0 comments on commit 42ede0f

Please sign in to comment.