Content
Description | Installation | Quick start | Contribute | Authors | License | References
Description
Jump to the DamageDetective website
Damaged cells are an artifact of scRNA-seq formed when cells succumb to stress before being sequenced. As a result, the gene expression they capture distorts downstream analysis by introducing technical variability that compromises the annotation of cell types and confounds their expression profiles. Filtering damaged cells is therefore a standard task in scRNA-seq quality control (QC), though it remains poorly standardised in practice.
Current approaches filter damage according to deviations in cell-level QC metrics. This outlier-based detection implicitly assumes that viable cells follow a unimodal distribution across QC metrics where deviation is synonymous with damage—an assumption challenged by true biological heterogeneity. Recent methods address this by defining damage within distinct distributions, representing cell populations, independently. However, this assumes all distinct distributions correspond to viable cell populations and risks leaving abundant damage undetected.
DamageDetective takes a different approach, rather than detecting damage by measuring the extent to which cells deviate from one another, it measures the extent to which cells deviate from artificially damaged profiles of themselves, an approach inspired by top-performing tools in doublet detection, including DoubletFinder. In this case, damaged cell profiles are generated by simulating the loss of cytoplasmic RNA resulting from a loss of plasma membrane integrity—a fundamental characteristic of irreversible cell damage.
Like DoubletFinder, DamageDetective uses principal component analysis to compute the proximity of true cells to artificial cells, calculated as a proportion of a cell’s nearest neighbours that are of artificial origin (pANN). This measure, ranging from 0 to 1, reflects the likelihood that a cell has experienced the same cytoplasmic RNA loss providing an intuitive scale for filtering that is standardised across cell types, sample origin, and experimental design.
Installation
Install DamageDetective from CRAN (R >= 4.4.0),
install.packages('DamageDetective')Or the latest development version on GitHub (R >= 3.5.0),
library(devtools)
devtools::install_github("AlicenJoyHenning/DamageDetective", build_vignettes = TRUE)To verify installation, run the following to see if you can view the package vignette and the function help pages,
library(DamageDetective)
help(package = "DamageDetective")Quick start
Load data
Damage detection is carried out by the detect_damage function that accepts count matrices as input.
To follow with the demonstration, load the internal dummy dataset, test_counts,
library(DamageDetective)
data("test_counts", package = "DamageDetective")
dim(test_counts)Expected outcome,
For examples with true data and more detailed explanations, please refer to the package articles (package tutorials)
Select parameters for damage detection
While detect_damage requires only a count matrix as input, additional parameters control aspects of the function’s computation.
Of these, we recommend ribosome_penalty be adjusted for each dataset using the select_penalty function as shown below,
penalty <- select_penalty(count_matrix = test_counts)
penaltyExpected outcome,
> Testing penalty of 0.1...
> Testing penalty of 0.15...
> Testing penalty of 0.2...
> Testing penalty of 0.25...
> Stopping early: dTNN is no longer improving.
>
> 0.15Run damaged cell detection
This penalty value is used as input for detect_damage to ensure damaged cells simulated best align with dataset-specific ribosomal gene expression patterns. detect_damage will then compute pANN values using the simulated cells in order to filter true cells. This filtering is done using a pANN threshold above which it is most likely for a true cell to be damaged. By default, detect_damage will calculate a filtering threshold dynamically using the distribution of pANN values among true cells.
detection_results <- detect_damage(
count_matrix = test_counts,
ribosome_penalty = penalty,
filter_counts = TRUE
)Expected outcome,
> Clustering cells...
> Simulating damage...
> Computing pANN...
> ... 0.5 suggested threshold.
> Completed.Above, we have specified for filter_counts to be TRUE. This will return the filtered count matrix according to the default pANN threshold. By default, a plot of the cells shaded according to the pANN value is also provided to visualise outcomes, detection_results$plot, but can be avoided using display_plot = FALSE.
# View the resulting count matrix
dim(detection_results$output)Expected outcome,
Adjust additional damaged cell detection parameters
Alternatively, if filter_counts is set to FALSE, the data will not be filtered and a data frame will be given containing the damage scores—pANN values— for each cell. From here, a user can filter their data manually, as is done by filter_counts=TRUE automatically.
# Perform damage detection
detection_results <- detect_damage(
count_matrix = test_counts,
ribosome_penalty = penalty,
filter_counts = FALSE,
seed = 7
)
# View output
print(head(detection_results$output), row.names = FALSE)
# Filter matrix
undamaged_cells <- subset(detection_results$output, DamageDetective < 0.5)
filtered_matrix <- test_counts[, undamaged_cells$Cells]
dim(filtered_matrix)Expected outcome,
> Clustering cells...
> Simulating damage...
> Computing pANN...
> ... 0.5 suggested threshold.
> Completed.
>
> Cells pANN DamageDetective
> TCTGGAAAGCCCAACC_H1B2ln6 0 cell
> CCGTTCATCGTGGGAA_H1B2ln2 0 cell
> CTTCTCTTCAGCCTAA_H1B2ln1 0 cell
> GGATTACAGGGATGGG_H1B2ln1 0 cell
> TCTATTGTCTGGTATG_H1B2ln2 0 cell
> ACGGGTCAGACAAGCC_H1B2ln6 0 cell
>
> 32738 458If a user wishes to adjust the pANN filtering threshold they are able to do so using the filter_threshold parameter, a numeric between 0 and 1 where values greater than 0.5 reflect more permissive filtering and values closer to 0 reflect more stringent filtering.
We recommend the default pANN calculated but suggest that if adjustments are made they are informed by the detect_damage plots, generate_plot = TRUE.
Contribute
We are committed to the improvement of DamageDetective and encourage users to report any bugs or difficulties they encounter. Contributions that refine or challenge the assumptions and heuristics used to detect damaged cells are also welcome. Please reach out via the maintainer’s email listed in the DESCRIPTION file or start a public discussion .
License
DamageDetective is made available for public use through the GNU AGPL-3.0
Authors
Alicen Henning
Stellenbosch University, Cape Town, South Africa
Bioinformatics and Computational Biology
This work was done under the supervision of Prof Marlo Möller, Prof Gian van der Spuy, and Prof André Loxton.
References
McGinnis, C. S., Murrow, L. M., & Gartner, Z. J. (2019). DoubletFinder: Doublet Detection in Single-Cell RNA Sequencing Data Using Artificial Nearest Neighbors. Cell Systems, 8(4), 329-337.e4. https://doi.org/10.1016/j.cels.2019.03.003
Risso D, Cole M (2024). scRNAseq: Collection of Public Single-Cell RNA-Seq Datasets. doi:10.18129/B9.bioc.scRNAseq https://doi.org/10.18129/B9.bioc.scRNAseq, R package version 2.20.0, https://bioconductor.org/packages/scRNAseq.