Introduction
This vignette covers advanced usage patterns for recall, including:
- Choosing the optimal null distribution
- Parallel computing configurations
- Count splitting alternative
- Custom parameter tuning
- Integration with downstream analyses
Null Distribution Selection
Available Methods
recall supports multiple methods for generating synthetic null variables:
| Method | Distribution | Correlations | Speed | Best For |
|---|---|---|---|---|
ZIP |
Zero-Inflated Poisson | No | Fast | Most scRNA-seq data |
NB |
Negative Binomial | No | Fast | Overdispersed data |
ZIP-copula |
ZIP + Gaussian copula | Yes | Slow | Correlated genes |
NB-copula |
NB + Gaussian copula | Yes | Slow | Complex datasets |
Poisson-copula |
Poisson + copula | Yes | Medium | Low-variance data |
Gaussian-copula |
Gaussian + copula | Yes | Medium | Normalized data |
Choosing the Right Method
library(recall)
library(Seurat)
# For standard scRNA-seq data with excess zeros
pbmc_zip <- FindClustersRecall(
pbmc,
null_method = "ZIP", # Default, fastest
resolution_start = 0.8
)
# For highly overdispersed data
pbmc_nb <- FindClustersRecall(
pbmc,
null_method = "NB",
resolution_start = 0.8
)
# For data with strong gene-gene correlations
pbmc_copula <- FindClustersRecall(
pbmc,
null_method = "NB-copula",
cores = 4, # Parallel processing recommended
resolution_start = 0.8
)Assessing Data Characteristics
# Check for overdispersion
counts <- GetAssayData(pbmc, layer = "counts")
means <- rowMeans(counts)
vars <- apply(counts, 1, var)
# Overdispersion ratio
overdispersion_ratio <- vars / means
summary(overdispersion_ratio)
# If median ratio >> 1, use NB instead of ZIP
if (median(overdispersion_ratio, na.rm = TRUE) > 2) {
message("Data appears overdispersed. Consider using null_method = 'NB'")
}Parallel Computing
Cross-Platform Configuration
recall automatically handles parallelization across platforms:
-
Linux/macOS: Uses
multicore(fork-based) -
Windows: Uses
multisession(socket-based)
# Automatic platform detection
pbmc <- FindClustersRecall(
pbmc,
cores = parallel::detectCores() - 1, # Leave one core free
shared_memory_max = 16000 * 1024^2 # 16GB for large datasets
)Memory Management
For large datasets, adjust memory settings:
# For datasets with >100,000 cells
pbmc_large <- FindClustersRecall(
large_seurat_obj,
cores = 8,
shared_memory_max = 32000 * 1024^2, # 32GB
null_method = "ZIP" # Use faster method for large data
)Count Splitting Alternative
recall also implements the count splitting approach as an alternative to knockoff filtering:
# Count splitting method (Neufeld et al., 2022)
pbmc_countsplit <- FindClustersCountsplit(
pbmc,
resolution_start = 0.8,
algorithm = "leiden"
)Method Comparison
library(patchwork)
# Run both methods
pbmc_recall <- FindClustersRecall(pbmc, resolution_start = 0.8)
pbmc_countsplit <- FindClustersCountsplit(pbmc, resolution_start = 0.8)
# Compare results
p1 <- DimPlot(pbmc_recall, label = TRUE) +
ggtitle(paste0("recall (", length(unique(Idents(pbmc_recall))), " clusters)"))
p2 <- DimPlot(pbmc_countsplit, group.by = "countsplit_clusters", label = TRUE) +
ggtitle(paste0("Count Split (", length(unique(pbmc_countsplit$countsplit_clusters)), " clusters)"))
p1 + p2Resolution Tuning
Iterative Resolution Reduction
The reduction_percentage parameter controls how quickly
resolution decreases:
# Conservative: Slower reduction, may result in more clusters
pbmc_conservative <- FindClustersRecall(
pbmc,
resolution_start = 1.2,
reduction_percentage = 0.1 # 10% reduction per iteration
)
# Aggressive: Faster reduction, may result in fewer clusters
pbmc_aggressive <- FindClustersRecall(
pbmc,
resolution_start = 1.2,
reduction_percentage = 0.3 # 30% reduction per iteration
)Finding Optimal Starting Resolution
# Sweep different starting resolutions
resolutions <- c(0.4, 0.6, 0.8, 1.0, 1.2, 1.5)
results <- list()
for (res in resolutions) {
pbmc_temp <- FindClustersRecall(pbmc, resolution_start = res)
results[[as.character(res)]] <- list(
n_clusters = length(unique(Idents(pbmc_temp))),
clusters = Idents(pbmc_temp)
)
}
# Summary
sapply(results, function(x) x$n_clusters)Clustering Algorithm Selection
Louvain vs Leiden
# Louvain (default, faster)
pbmc_louvain <- FindClustersRecall(
pbmc,
algorithm = "louvain",
resolution_start = 0.8
)
# Leiden (often finds better partitions)
pbmc_leiden <- FindClustersRecall(
pbmc,
algorithm = "leiden",
resolution_start = 0.8
)Integration with Seurat Workflow
Complete Analysis Pipeline
library(Seurat)
library(recall)
# 1. Load and preprocess
seurat_obj <- CreateSeuratObject(counts = raw_counts)
seurat_obj <- NormalizeData(seurat_obj)
seurat_obj <- FindVariableFeatures(seurat_obj, nfeatures = 2000)
seurat_obj <- ScaleData(seurat_obj)
seurat_obj <- RunPCA(seurat_obj)
seurat_obj <- FindNeighbors(seurat_obj, dims = 1:20)
seurat_obj <- RunUMAP(seurat_obj, dims = 1:20)
# 2. Calibrated clustering with recall
seurat_obj <- FindClustersRecall(
seurat_obj,
resolution_start = 0.8,
null_method = "ZIP",
algorithm = "leiden",
cores = 4
)
# 3. Downstream analysis
markers <- FindAllMarkers(seurat_obj, only.pos = TRUE)
# 4. Visualization
DimPlot(seurat_obj, group.by = "recall_clusters", label = TRUE)Using seurat_workflow Helper
# One-line preprocessing + clustering
seurat_obj <- seurat_workflow(
raw_seurat_obj,
num_variable_features = 2000,
resolution_param = 0.8,
visualization_method = "both", # UMAP and t-SNE
num_dims = 15,
algorithm = "louvain"
)Batch Processing Multiple Samples
# Process multiple samples
sample_list <- list(sample1 = seurat1, sample2 = seurat2, sample3 = seurat3)
results <- lapply(sample_list, function(obj) {
# Preprocess
obj <- NormalizeData(obj)
obj <- FindVariableFeatures(obj)
obj <- ScaleData(obj)
obj <- RunPCA(obj)
obj <- FindNeighbors(obj, dims = 1:10)
# Calibrated clustering
obj <- FindClustersRecall(obj, resolution_start = 0.8, cores = 2)
return(obj)
})Troubleshooting
Common Issues
1. Memory errors with copula methods:
# Reduce features or use simpler method
seurat_obj <- FindVariableFeatures(seurat_obj, nfeatures = 1000) # Reduce features
pbmc <- FindClustersRecall(pbmc, null_method = "ZIP") # Use faster method2. Single cluster warning:
# Increase starting resolution
pbmc <- FindClustersRecall(pbmc, resolution_start = 1.5)3. Slow performance:
# Use parallel processing and simpler null method
pbmc <- FindClustersRecall(
pbmc,
null_method = "ZIP",
cores = parallel::detectCores() - 1
)