| name | bio-flow-cytometry-doublet-detection |
| description | Detect and remove doublets from flow and mass cytometry data. Covers FSC/SSC gating and computational doublet detection methods. Use when filtering out cell aggregates before clustering or quantitative analysis. |
| tool_type | r |
| primary_tool | flowCore |
Doublet Detection
FSC-A vs FSC-H Gating (Standard Method)
library(flowCore)
library(ggcyto)
fs <- read.flowSet(list.files('data/', pattern = '\\.fcs$', full.names = TRUE))
singlet_gate <- rectangleGate(
filterId = 'singlets',
'FSC-A' = c(50000, 250000),
'FSC-H' = c(50000, 250000)
)
singlet_polygon <- polygonGate(
filterId = 'singlets',
.gate = data.frame(
'FSC-A' = c(50000, 250000, 250000, 50000),
'FSC-H' = c(40000, 200000, 260000, 60000)
)
)
singlets <- Subset(fs, singlet_gate)
autoplot(fs[[1]], 'FSC-A', 'FSC-H') + geom_gate(singlet_gate)
Automated Singlet Gating with flowDensity
library(flowDensity)
singlet_result <- flowDensity(
fs[[1]],
channels = c('FSC-A', 'FSC-H'),
position = c(TRUE, TRUE),
gates = c(NA, NA)
)
singlets <- getflowFrame(singlet_result)
pct_singlets <- nrow(singlets) / nrow(fs[[1]]) * 100
cat('Singlets:', round(pct_singlets,
flowAI Quality Control
library(flowAI)
fs_qc <- flow_auto_qc(
fs,
folder_results = 'flowAI_results',
fcs_QC = TRUE,
fcs_highQ = TRUE
)
FSC-A/FSC-W Method (Width Parameter)
if ('FSC-W' %in% colnames(fs[[1]])) {
singlet_gate_w <- rectangleGate(
filterId = 'singlets',
'FSC-A' = c(50000, 250000),
'FSC-W' = c(50000, 100000)
)
singlets <- Subset(fs, singlet_gate_w)
}
Ratio-Based Doublet Detection
calculate_fsc_ratio <- function(ff) {
fsc_a <- exprs(ff)[, 'FSC-A']
fsc_h <- exprs(ff)[, 'FSC-H']
ratio <- fsc_a / (fsc_h + 1)
return(ratio)
}
for (i in 1:length(fs)) {
ratio <- calculate_fsc_ratio(fs[[i]])
fs[[i]] <- cbind2(fsi ratio
colnamesfsincolfsi
ratio_cutoff quantileexprsfs
singlet_gate_ratio rectangleGatefilterId ratio_cutoff
SSC-Based Doublet Detection
ssc_singlet_gate <- rectangleGate(
filterId = 'ssc_singlets',
'SSC-A' = c(10000, 200000),
'SSC-H' = c(10000, 200000)
)
combined_gate <- singlet_gate & ssc_singlet_gate
singlets <- Subset(fs, combined_gate)
CyTOF Doublet Detection
library(CATALYST)
sce <- prepData(fs, panel, md)
if ('Event_length' %in% rownames(sce)) {
event_length <- assay(sce)['Event_length', ]
singlet_idx <- event_length < quantile(event_length, 0.95)
sce_singlets <- sce[, singlet_idx]
cat('Removed', sum(!singlet_idx), 'doublets based on event length\n')
}
if (all(c rownamessce
dna_total assaysce assaysce
dna_cutoff quantiledna_total
singlet_idx dna_total dna_cutoff
sce_singlets sce singlet_idx
CATALYST Workflow with Doublet Removal
library(CATALYST)
sce <- prepData(fs, panel, md, transform = TRUE, cofactor = 5)
sce <- filterSCE(sce, !is_doublet(sce))
fsc_a <- colData(sce)$FSC_A
fsc_h <- colData(sce)$FSC_H
fit <- lm(fsc_a ~ fsc_h)
residuals <- abs(fsc_a - predict(fit))
threshold <- quantile(residuals, 0.95)
colData(sce)$doublet <- residuals > threshold
sce_singlets sce colDatascedoublet
cat meancolDatascedoublet
Batch Processing
detect_doublets <- function(ff, method = 'fsc') {
if (method == 'fsc') {
fsc_a <- exprs(ff)[, 'FSC-A']
fsc_h <- exprs(ff)[, 'FSC-H']
fit <- lm(fsc_a ~ fsc_h)
residuals <- abs(fsc_a - predict(fit))
threshold <- quantile(residuals, 0.95)
singlet_idx <- residuals <= threshold
} else if (method == 'ratio') {
ratio <- exprsff exprsff
singlet_idx ratio quantileratio
ffsinglet_idx
fs_singlets fsApplyfs detect_doublets method
doublet_rates sapplyfs i
nrowfs_singletsi nrowfsi
cat meandoublet_rates
Visualization
library(ggplot2)
plot_data <- data.frame(
FSC_A = exprs(fs[[1]])[, 'FSC-A'],
FSC_H = exprs(fs[[1]])[, 'FSC-H']
)
fit <- lm(FSC_A ~ FSC_H, data = plot_data)
plot_data$residual <- abs(plot_data$FSC_A - predict(fit))
plot_data$doublet <- plot_data$residual > quantile(plot_data$residual, 0.95)
ggplot(plot_data aesx FSC_H y FSC_A color doublet
geom_pointalpha size
scale_color_manualvalues
theme_bw
labstitle x y
ggsave width height
Related Skills
Workflow order: cytometry-qc → doublet-detection → bead-normalization → clustering
- cytometry-qc - Run first: identify flow rate and signal issues
- bead-normalization - Run after: correct remaining instrument drift
- fcs-handling - Load FCS files
- gating-analysis - Manual gating workflows
- clustering-phenotyping - Downstream analysis after doublet removal