-
Notifications
You must be signed in to change notification settings - Fork 931
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature: updates for cellranger 9.0 #9541
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -645,6 +645,138 @@ Load10X_Spatial <- function ( | |
|
||
return(object) | ||
} | ||
#' Add 10X Cell Types to a Seurat Object | ||
#' | ||
#' This function reads cell type annotations from a CSV file and adds them to the metadata of a Seurat object. | ||
#' If the cell type file does not exist, the original Seurat object is returned unchanged. | ||
#' | ||
#' @param data.dir A string specifying the directory containing the "cell_types" folder with the "cell_types.csv" file. | ||
#' @param object A Seurat object to which the cell type annotations will be added. | ||
#' | ||
#' @return A Seurat object with updated metadata including cell type annotations if the file is found. | ||
#' | ||
#' @details | ||
#' The function searches for a CSV file named "cell_types.csv" in the "cell_types" subdirectory within `data.dir`. | ||
#' The CSV file should contain at least a "barcode" column that matches the cell barcodes in the Seurat object. | ||
#' Additional columns in the CSV file will be merged into the Seurat object's metadata. | ||
#' | ||
#' @importFrom utils read.csv | ||
#' @importFrom tibble rownames_to_column column_to_rownames | ||
#' @importFrom base file.path file.exists merge | ||
#' | ||
#' @examples | ||
#' \dontrun{ | ||
#' # Specify the data directory containing the "cell_types" folder | ||
#' data.dir <- "/path/to/data" | ||
#' | ||
#' # Create a Seurat object (example) | ||
#' seurat_obj <- CreateSeuratObject(counts = some_counts_matrix) | ||
#' | ||
#' # Add cell type annotations to the Seurat object | ||
#' seurat_obj <- Add_10X_CellTypes(data.dir, seurat_obj) | ||
#' } | ||
|
||
Add_10X_CellTypes <- function(data.dir, object) { | ||
cell_types_path <- file.path(data.dir, "cell_types", "cell_types.csv") | ||
if (file.exists(cell_types_path)) { | ||
cell.types <- read.csv(cell_types_path) | ||
meta_data_with_barcodes <- tibble::rownames_to_column([email protected], "barcode") | ||
merged_meta_data <- merge( | ||
x = meta_data_with_barcodes, | ||
y = cell.types, | ||
by = "barcode", | ||
all.x = TRUE | ||
) | ||
[email protected] <- tibble::column_to_rownames(merged_meta_data, "barcode") | ||
return(object) | ||
} else { | ||
return(object) | ||
} | ||
} | ||
|
||
#' Load a 10x Genomics Single Cell Experiment into a \code{Seurat} object | ||
#' | ||
#' @inheritParams Read10X | ||
#' @inheritParams SeuratObject::CreateSeuratObject If multiome 10x data the | ||
#' assay param will not be used. The names of each assay contained in the matrix are used. | ||
#' @param data.dir Directory containing the H5 file specified by \code{filename} | ||
#' @param filename Name of H5 file containing the feature barcode matrix | ||
#' @param to.upper Converts all feature names to upper case. This can provide an | ||
#' approximate conversion of mouse to human gene names which can be useful in an | ||
#' explorative analysis. For cross-species comparisons, orthologous genes should | ||
#' be identified across species and used instead. | ||
#' @param ... Arguments passed to \code{\link{Read10X_h5}} | ||
#' | ||
#' @return A \code{Seurat} object | ||
#' | ||
#' | ||
#' @export | ||
#' @concept preprocessing | ||
#' | ||
#' @examples | ||
#' \dontrun{ | ||
#' data_dir <- 'path/to/data/directory' | ||
#' list.files(data_dir) # Should show filtered_feature_bc_matrix.h5 | ||
#' Load10X(data.dir = data_dir) | ||
stephenwilliams22 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
#' } | ||
#' | ||
Load10X <- function(data.dir, filename = "filtered_feature_bc_matrix.h5", | ||
assay = "RNA", to.upper = FALSE, ...) { | ||
|
||
if (length(data.dir) > 1) { | ||
stop("`data.dir` expects a single directory path but received multiple values.") | ||
} | ||
if (!file.exists(data.dir)) { | ||
stop("No such file or directory: '", data.dir, "'") | ||
} | ||
|
||
|
||
filename <- list.files(data.dir, filename, full.names = FALSE, recursive = FALSE) | ||
counts.path <- file.path(data.dir, filename) | ||
if (!file.exists(counts.path)) { | ||
stop("File not found: '", counts.path, "'") | ||
} | ||
|
||
counts <- Read10X_h5(counts.path, ...) | ||
|
||
if (to.upper) { | ||
counts <- imap(counts, ~{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: because this formula operates on the counts matrices only and doesn't use the list's names, I think the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. personally, I like the simplicity and readability of tidy functions. I'll leave it up to the seruat developers to decide if they mind the extra import. I haven't heard any complaints since we wrote this function a few years ago. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not really an issue; the choice one way or another doesn't affect me. (Personally, I agree; I always prefer the purrr functions in my own scripts.) I only wanted to mention it for the attention of the dev team. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 to replacing the
This is also a good point, |
||
rownames(.x) <- toupper(rownames(.x)) | ||
.x | ||
}) | ||
} | ||
|
||
if (is.list(counts)) { | ||
seurat.list <- lapply(names(counts), function(name) { | ||
CreateSeuratObject( | ||
counts = counts[[name]], | ||
assay = name, | ||
project = name | ||
) | ||
}) | ||
|
||
for (i in seq_along(seurat.list)) { | ||
if (Assays(seurat.list[[i]]) %in% c("Gene Expression", "RNA")) { | ||
seurat.list[[i]] <- Add_10X_CellTypes(data.dir, seurat.list[[i]]) | ||
} | ||
} | ||
|
||
merged.object <- merge( | ||
x = seurat.list[[1]], | ||
y = seurat.list[-1], | ||
add.cell.ids = names(counts), | ||
merge.data = FALSE | ||
) | ||
return(merged.object) | ||
|
||
} else { | ||
object <- CreateSeuratObject(counts, assay = assay) | ||
if (Assays(object) %in% c("Gene Expression", "RNA")) { | ||
object <- Add_10X_CellTypes(data.dir, object) | ||
} | ||
Comment on lines
+772
to
+776
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure that It looks like there's just one |
||
return(object) | ||
} | ||
} | ||
|
||
|
||
#' Read10x Probe Metadata | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Preemptive-- this parameter doesn't seem to be implemented yet)
In my opinion, it would be better not to suggest that blind uppercasing is ever an appropriate way of finding mouse-human orthologs, even in an exploratory analysis.
If the user has some good reason to convert all the symbols to uppercase, they can simply use
toupper
and replace the rownames of the object.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This option was put in originally by the seurat team. I'll let them address the usefulness here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The parameter was introduced well before my time but I tend to agree with @rharao.