Differential Communication Analysis
Zaoqu Liu
2026-01-26
Source:vignettes/differential.Rmd
differential.RmdIntroduction
Differential communication analysis is essential for understanding how cell-cell signaling changes between biological conditions, such as:
- Disease vs. Normal: Altered communication in cancer, inflammation, or autoimmune diseases
- Treatment response: Changes after drug treatment or immunotherapy
- Developmental stages: Communication dynamics during differentiation
NOVA provides comprehensive tools for comparing communication networks between conditions.
Simulating Two Conditions
We’ll create two simulated datasets representing control and treatment conditions.
set.seed(42)
# Common parameters
n_genes <- 200
n_cells <- 400
gene_names <- paste0("Gene", 1:n_genes)
clusters <- c("T_cells", "B_cells", "Macrophages", "Fibroblasts")
# Get LR database genes
lr_db <- GetLRDatabase("lrc2p")
ligands <- unique(lr_db$ligand)[1:25]
receptors <- unique(lr_db$receptor)[1:25]
# Function to create expression matrix
create_expr <- function(n_cells, seed_offset = 0, fold_changes = NULL) {
set.seed(42 + seed_offset)
cell_names <- paste0("Cell", 1:n_cells)
expr <- matrix(0, nrow = n_genes, ncol = n_cells,
dimnames = list(gene_names, cell_names))
# Base expression
expressed <- sample(length(expr), size = length(expr) * 0.25)
expr[expressed] <- abs(rnorm(length(expressed), mean = 2, sd = 1))
# Map genes
rownames(expr)[1:25] <- ligands
rownames(expr)[26:50] <- receptors
# Apply fold changes if provided
if (!is.null(fold_changes)) {
for (gene in names(fold_changes)) {
if (gene %in% rownames(expr)) {
expr[gene, ] <- expr[gene, ] * fold_changes[gene]
}
}
}
# Create annotation
cluster_assign <- sample(clusters, n_cells, replace = TRUE)
names(cluster_assign) <- cell_names
ann <- data.frame(cell = cell_names, cluster = cluster_assign)
list(expr = Matrix::Matrix(expr, sparse = TRUE), annotation = ann)
}
# Create control condition
ctrl <- create_expr(400)
# Create treatment condition with altered expression
# Simulate upregulation of some genes in treatment
treatment_fc <- setNames(rep(1.5, 10), ligands[1:10])
treat <- create_expr(400, seed_offset = 100, fold_changes = treatment_fc)Running Individual Analyses
# Analyze control
ctrl_result <- ExtractEdges(
expression = ctrl$expr,
annotation = ctrl$annotation,
species = "human",
database = "lrc2p",
min_pct = 0.05
)
# Analyze treatment
treat_result <- ExtractEdges(
expression = treat$expr,
annotation = treat$annotation,
species = "human",
database = "lrc2p",
min_pct = 0.05
)
cat("Control edges:", nrow(ctrl_result$edges), "\n")
cat("Treatment edges:", nrow(treat_result$edges), "\n")Visualization
Differential Heatmap
PlotDiffHeatmap(diff_result, metric = "log2fc")Volcano Plot
PlotVolcano(diff_result,
log2fc_threshold = 0.5,
label_top = 10,
title = "Treatment vs Control")Summarization Functions
By Cluster Pair
# Summarize changes by cluster pairs
cluster_summary <- SummarizeByCluster(diff_result)
head(cluster_summary)By LR Pair
# Summarize changes by ligand-receptor pairs
lr_summary <- SummarizeByLR(diff_result)
head(lr_summary)Interpreting Results
Exporting Results
# Export to Excel
ExportDiff(diff_result, "differential_analysis.xlsx")
# Export to CSV
write.csv(diff_result$changed_edges, "changed_edges.csv", row.names = FALSE)Best Practices
2. Multiple Testing Consideration
For large-scale analyses, consider adjusting for multiple testing:
# Example: Bonferroni correction
n_tests <- nrow(diff_result$changed_edges)
alpha_adjusted <- 0.05 / n_testsSession Info
sessionInfo()
#> R version 4.4.0 (2024-04-24)
#> Platform: aarch64-apple-darwin20
#> Running under: macOS 15.6.1
#>
#> Matrix products: default
#> BLAS: /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRblas.0.dylib
#> LAPACK: /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRlapack.dylib; LAPACK version 3.12.0
#>
#> locale:
#> [1] C
#>
#> time zone: Asia/Shanghai
#> tzcode source: internal
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] ggplot2_4.0.1 NOVA_1.0.0
#>
#> loaded via a namespace (and not attached):
#> [1] Matrix_1.7-4 gtable_0.3.6 jsonlite_2.0.0 dplyr_1.1.4
#> [5] compiler_4.4.0 Rcpp_1.1.1 tidyselect_1.2.1 parallel_4.4.0
#> [9] dichromat_2.0-0.1 jquerylib_0.1.4 systemfonts_1.3.1 scales_1.4.0
#> [13] textshaping_1.0.4 yaml_2.3.12 fastmap_1.2.0 lattice_0.22-7
#> [17] R6_2.6.1 generics_0.1.4 knitr_1.51 htmlwidgets_1.6.4
#> [21] tibble_3.3.1 desc_1.4.3 bslib_0.9.0 pillar_1.11.1
#> [25] RColorBrewer_1.1-3 rlang_1.1.7 cachem_1.1.0 xfun_0.56
#> [29] fs_1.6.6 sass_0.4.10 S7_0.2.1 otel_0.2.0
#> [33] cli_3.6.5 withr_3.0.2 pkgdown_2.2.0 magrittr_2.0.4
#> [37] digest_0.6.39 grid_4.4.0 lifecycle_1.0.5 vctrs_0.7.1
#> [41] data.table_1.18.0 evaluate_1.0.5 glue_1.8.0 farver_2.1.2
#> [45] ragg_1.5.0 rmarkdown_2.30 tools_4.4.0 pkgconfig_2.0.3
#> [49] htmltools_0.5.9