Overview

Part 2 of 2 — CNS-focused immunosuppressive deep dive.

Building on the global CellChat landscape in 12a, this script focuses on the immunosuppressive communication networks that define the CNS leukaemia niche:

  1. Galectin-9 / TIM-3 axis — B-ALL and Vγ6Vδ4 as dual immunosuppressive senders
  2. TREM2 / APP myeloid programming — Stroma → microglia/macrophage tolerogenic signals
  3. Niche retention circuits — CXCL12/CXCR4 (B-ALL), CXCL16/CXCR6 (Vγ6Vδ4)
  4. TGFβ network — immunosuppressive signalling from multiple sources
  5. Cell-type focused analysis — Vγ6Vδ4, B-ALL, stroma, microglia-like communication
  6. Pathway summary tables — CNS-enriched and CNS-only pathways
  7. Communication patterns — coordinated signalling programmes

Setup — Load Cached Objects

library(CellChat)
library(Seurat)
library(qs2)
library(dplyr)
library(tidyr)
library(patchwork)
library(ggplot2)
library(ComplexHeatmap)
library(knitr)
library(NMF)

if (!requireNamespace("ggalluvial", quietly = TRUE)) {
  cat("NOTE: ggalluvial not installed — river plots will be skipped\n")
}

base_path <- "/exports/eddie/scratch/aduguid3"
cache_dir <- file.path(base_path, "harmony_clustering")
combined       <- qs_read(file.path(cache_dir, "12_combined_seurat.qs"))
cellchat_bm    <- qs_read(file.path(cache_dir, "12_cellchat_bm_v1.qs"))
cellchat_cns   <- qs_read(file.path(cache_dir, "12_cellchat_cns_v1.qs"))
cellchat_merged <- qs_read(file.path(cache_dir, "12_cellchat_merged_v1.qs"))

cellchat_cns <- netAnalysis_computeCentrality(cellchat_cns)
cellchat_bm  <- netAnalysis_computeCentrality(cellchat_bm)

cns_net <- subsetCommunication(cellchat_cns)
bm_net  <- subsetCommunication(cellchat_bm)

cat("CNS interactions:", nrow(cns_net), "\n")
## CNS interactions: 6600
cat("BM interactions: ", nrow(bm_net), "\n")
## BM interactions:  6162

Step 1 — Galectin-9 / TIM-3 Immunosuppressive Axis

Galectin-9 (LGALS9) emerged as the dominant outgoing signal from B-ALL and is also produced by Vγ6Vδ4 cells. Galectin-9 engages TIM-3 (HAVCR2) on T cells to induce exhaustion/apoptosis, and signals through CD45 and CD44 to broadly suppress immune activation.

Step 1a — All Galectin Interactions in CNS

gal_cns <- cns_net %>%
  filter(pathway_name == "GALECTIN") %>%
  arrange(desc(prob))

cat("Total GALECTIN interactions in CNS:", nrow(gal_cns), "\n\n")
## Total GALECTIN interactions in CNS: 389
# Summarise by sender
gal_cns %>%
  group_by(source) %>%
  summarise(
    n_targets = n_distinct(target),
    n_LR = n(),
    total_prob = round(sum(prob), 3),
    .groups = "drop"
  ) %>%
  arrange(desc(total_prob)) %>%
  kable(caption = "GALECTIN senders in CNS — ranked by total probability")
GALECTIN senders in CNS — ranked by total probability
source n_targets n_LR total_prob
B-ALL 19 47 3.089
Microglia-like 18 34 1.524
Basophils 18 28 0.884
Macrophages 18 26 0.690
CD8_Teff 17 25 0.630
CD8_Tpex 17 25 0.594
Other_gd 17 25 0.572
Neutrophils 16 23 0.487
Stroma 14 19 0.267
DCs 14 19 0.261
CD4_T 12 15 0.145
CD8_Tex 12 15 0.135
NKT-like 12 15 0.132
Pre-B 12 15 0.130
Vg4 12 15 0.121
CD8_Naive 12 15 0.120
Other 12 14 0.103
Vg6Vd4 12 14 0.089

Step 1b — Galectin-9 Specific L-R Pairs

gal_lr <- cns_net %>%
  filter(pathway_name == "GALECTIN") %>%
  group_by(interaction_name) %>%
  summarise(
    n_pairs = n(),
    total_prob = round(sum(prob), 3),
    top_sender = names(sort(table(source), decreasing = TRUE))[1],
    .groups = "drop"
  ) %>%
  arrange(desc(total_prob))

gal_lr %>% kable(caption = "GALECTIN L-R pairs ranked by total probability (CNS)")
GALECTIN L-R pairs ranked by total probability (CNS)
interaction_name n_pairs total_prob top_sender
LGALS9_CD44 125 3.139 B-ALL
LGALS9_IGHM 144 2.696 B-ALL
LGALS9_CD45 22 2.460 B-ALL
LGALS9_HAVCR2 90 1.185 B-ALL
LGALS9_P4HB 8 0.495 B-ALL

Step 1c — LGALS9 → HAVCR2 (TIM-3) Interactions

The key immunosuppressive interaction — Galectin-9 engaging TIM-3 on T cells.

tim3_interactions <- cns_net %>%
  filter(grepl("LGALS9.*HAVCR2|HAVCR2.*LGALS9", interaction_name)) %>%
  arrange(desc(prob))

if (nrow(tim3_interactions) > 0) {
  cat("LGALS9 → HAVCR2 (TIM-3) interactions in CNS:", nrow(tim3_interactions), "\n\n")
  tim3_interactions %>%
    select(source, target, interaction_name, prob, pval) %>%
    kable(caption = "Galectin-9 → TIM-3 interactions (CNS)")
} else {
  cat("No direct LGALS9-HAVCR2 interactions — checking all HAVCR2 targets:\n")
  cns_net %>%
    filter(grepl("HAVCR2", interaction_name)) %>%
    select(source, target, interaction_name, pathway_name, prob) %>%
    arrange(desc(prob)) %>%
    kable()
}
## LGALS9 → HAVCR2 (TIM-3) interactions in CNS: 90
Galectin-9 → TIM-3 interactions (CNS)
source target interaction_name prob pval
B-ALL Microglia-like LGALS9_HAVCR2 0.0536680 0
B-ALL Monocytes LGALS9_HAVCR2 0.0414412 0
B-ALL CD8_Tpex LGALS9_HAVCR2 0.0389816 0
Microglia-like Microglia-like LGALS9_HAVCR2 0.0387106 0
Basophils Microglia-like LGALS9_HAVCR2 0.0364071 0
Macrophages Microglia-like LGALS9_HAVCR2 0.0325265 0
CD8_Teff Microglia-like LGALS9_HAVCR2 0.0320830 0
CD8_Tpex Microglia-like LGALS9_HAVCR2 0.0302065 0
Microglia-like Monocytes LGALS9_HAVCR2 0.0297842 0
Other_gd Microglia-like LGALS9_HAVCR2 0.0290987 0
Basophils Monocytes LGALS9_HAVCR2 0.0279964 0
Microglia-like CD8_Tpex LGALS9_HAVCR2 0.0279962 0
Basophils CD8_Tpex LGALS9_HAVCR2 0.0263128 0
Neutrophils Microglia-like LGALS9_HAVCR2 0.0262552 0
Macrophages Monocytes LGALS9_HAVCR2 0.0249890 0
CD8_Teff Monocytes LGALS9_HAVCR2 0.0246456 0
Macrophages CD8_Tpex LGALS9_HAVCR2 0.0234820 0
CD8_Tpex Monocytes LGALS9_HAVCR2 0.0231937 0
CD8_Teff CD8_Tpex LGALS9_HAVCR2 0.0231588 0
Other_gd Monocytes LGALS9_HAVCR2 0.0223372 0
CD8_Tpex CD8_Tpex LGALS9_HAVCR2 0.0217925 0
Other_gd CD8_Tpex LGALS9_HAVCR2 0.0209867 0
Neutrophils Monocytes LGALS9_HAVCR2 0.0201407 0
Neutrophils CD8_Tpex LGALS9_HAVCR2 0.0189204 0
B-ALL CD8_Tex LGALS9_HAVCR2 0.0186428 0
Stroma Microglia-like LGALS9_HAVCR2 0.0169414 0
DCs Microglia-like LGALS9_HAVCR2 0.0165711 0
Microglia-like CD8_Tex LGALS9_HAVCR2 0.0133097 0
Stroma Monocytes LGALS9_HAVCR2 0.0129671 0
DCs Monocytes LGALS9_HAVCR2 0.0126826 0
Basophils CD8_Tex LGALS9_HAVCR2 0.0124981 0
Stroma CD8_Tpex LGALS9_HAVCR2 0.0121760 0
DCs CD8_Tpex LGALS9_HAVCR2 0.0119086 0
CD4_T Microglia-like LGALS9_HAVCR2 0.0117292 0
Macrophages CD8_Tex LGALS9_HAVCR2 0.0111365 0
CD8_Teff CD8_Tex LGALS9_HAVCR2 0.0109813 0
CD8_Tex Microglia-like LGALS9_HAVCR2 0.0109398 0
NKT-like Microglia-like LGALS9_HAVCR2 0.0106975 0
Pre-B Microglia-like LGALS9_HAVCR2 0.0104786 0
B-ALL CD8_Teff LGALS9_HAVCR2 0.0103425 0
CD8_Tpex CD8_Tex LGALS9_HAVCR2 0.0103258 0
Other_gd CD8_Tex LGALS9_HAVCR2 0.0099397 0
Vg4 Microglia-like LGALS9_HAVCR2 0.0097979 0
CD8_Naive Microglia-like LGALS9_HAVCR2 0.0096620 0
CD4_T Monocytes LGALS9_HAVCR2 0.0089665 0
Neutrophils CD8_Tex LGALS9_HAVCR2 0.0089511 0
Other Microglia-like LGALS9_HAVCR2 0.0088531 0
CD4_T CD8_Tpex LGALS9_HAVCR2 0.0084174 0
CD8_Tex Monocytes LGALS9_HAVCR2 0.0083614 0
NKT-like Monocytes LGALS9_HAVCR2 0.0081758 0
Pre-B Monocytes LGALS9_HAVCR2 0.0080080 0
CD8_Tex CD8_Tpex LGALS9_HAVCR2 0.0078491 0
Vg6Vd4 Microglia-like LGALS9_HAVCR2 0.0076801 0
NKT-like CD8_Tpex LGALS9_HAVCR2 0.0076747 0
Pre-B CD8_Tpex LGALS9_HAVCR2 0.0075172 0
Vg4 Monocytes LGALS9_HAVCR2 0.0074866 0
CD8_Naive Monocytes LGALS9_HAVCR2 0.0073825 0
Microglia-like CD8_Teff LGALS9_HAVCR2 0.0073660 0
Vg4 CD8_Tpex LGALS9_HAVCR2 0.0070275 0
CD8_Naive CD8_Tpex LGALS9_HAVCR2 0.0069298 0
Basophils CD8_Teff LGALS9_HAVCR2 0.0069143 0
Other Monocytes LGALS9_HAVCR2 0.0067632 0
Other CD8_Tpex LGALS9_HAVCR2 0.0063481 0
Macrophages CD8_Teff LGALS9_HAVCR2 0.0061572 0
CD8_Teff CD8_Teff LGALS9_HAVCR2 0.0060710 0
Vg6Vd4 Monocytes LGALS9_HAVCR2 0.0058655 0
Stroma CD8_Tex LGALS9_HAVCR2 0.0057396 0
CD8_Tpex CD8_Teff LGALS9_HAVCR2 0.0057069 0
DCs CD8_Tex LGALS9_HAVCR2 0.0056128 0
Vg6Vd4 CD8_Tpex LGALS9_HAVCR2 0.0055052 0
Other_gd CD8_Teff LGALS9_HAVCR2 0.0054926 0
Neutrophils CD8_Teff LGALS9_HAVCR2 0.0049441 0
CD4_T CD8_Tex LGALS9_HAVCR2 0.0039599 0
CD8_Tex CD8_Tex LGALS9_HAVCR2 0.0036914 0
NKT-like CD8_Tex LGALS9_HAVCR2 0.0036091 0
Pre-B CD8_Tex LGALS9_HAVCR2 0.0035347 0
Vg4 CD8_Tex LGALS9_HAVCR2 0.0033036 0
CD8_Naive CD8_Tex LGALS9_HAVCR2 0.0032575 0
Stroma CD8_Teff LGALS9_HAVCR2 0.0031657 0
DCs CD8_Teff LGALS9_HAVCR2 0.0030955 0
Other CD8_Tex LGALS9_HAVCR2 0.0029831 0
Vg6Vd4 CD8_Tex LGALS9_HAVCR2 0.0025859 0
CD4_T CD8_Teff LGALS9_HAVCR2 0.0021823 0
CD8_Tex CD8_Teff LGALS9_HAVCR2 0.0020341 0
NKT-like CD8_Teff LGALS9_HAVCR2 0.0019886 0
Pre-B CD8_Teff LGALS9_HAVCR2 0.0019476 0
Vg4 CD8_Teff LGALS9_HAVCR2 0.0018201 0
CD8_Naive CD8_Teff LGALS9_HAVCR2 0.0017946 0
Other CD8_Teff LGALS9_HAVCR2 0.0016433 0
Vg6Vd4 CD8_Teff LGALS9_HAVCR2 0.0014242 0
# Compare with BM
tim3_bm <- bm_net %>%
  filter(grepl("LGALS9.*HAVCR2|HAVCR2.*LGALS9", interaction_name))
cat("\nSame interactions in BM:", nrow(tim3_bm), "\n")
## 
## Same interactions in BM: 72
if (nrow(tim3_bm) > 0) {
  tim3_bm %>%
    select(source, target, interaction_name, prob) %>%
    arrange(desc(prob)) %>%
    kable(caption = "Galectin-9 → TIM-3 interactions (BM)")
}
Galectin-9 → TIM-3 interactions (BM)
source target interaction_name prob
B-ALL CD8_Tex LGALS9_HAVCR2 0.0629273
Basophils CD8_Tex LGALS9_HAVCR2 0.0573296
Neutrophils CD8_Tex LGALS9_HAVCR2 0.0398187
B-ALL Monocytes LGALS9_HAVCR2 0.0387143
Stroma CD8_Tex LGALS9_HAVCR2 0.0386844
Progenitors CD8_Tex LGALS9_HAVCR2 0.0361347
Basophils Monocytes LGALS9_HAVCR2 0.0351896
Other_gd CD8_Tex LGALS9_HAVCR2 0.0316515
CD8_Tpex CD8_Tex LGALS9_HAVCR2 0.0266629
Neutrophils Monocytes LGALS9_HAVCR2 0.0242671
Stroma Monocytes LGALS9_HAVCR2 0.0235649
Progenitors Monocytes LGALS9_HAVCR2 0.0219890
Other_gd Monocytes LGALS9_HAVCR2 0.0192258
DCs CD8_Tex LGALS9_HAVCR2 0.0187730
Microglia-like CD8_Tex LGALS9_HAVCR2 0.0181322
CD8_Tpex Monocytes LGALS9_HAVCR2 0.0161630
B-ALL CD8_Teff LGALS9_HAVCR2 0.0157444
Macrophages CD8_Tex LGALS9_HAVCR2 0.0157131
CD8_Teff CD8_Tex LGALS9_HAVCR2 0.0146490
Basophils CD8_Teff LGALS9_HAVCR2 0.0142799
CD4_T CD8_Tex LGALS9_HAVCR2 0.0142431
B-ALL CD8_Tpex LGALS9_HAVCR2 0.0141021
Pre-B CD8_Tex LGALS9_HAVCR2 0.0140108
CD8_Naive CD8_Tex LGALS9_HAVCR2 0.0136071
Other CD8_Tex LGALS9_HAVCR2 0.0134957
NKT-like CD8_Tex LGALS9_HAVCR2 0.0132489
Basophils CD8_Tpex LGALS9_HAVCR2 0.0127884
CD8_Tex CD8_Tex LGALS9_HAVCR2 0.0114925
DCs Monocytes LGALS9_HAVCR2 0.0113439
Vg4 CD8_Tex LGALS9_HAVCR2 0.0111247
Microglia-like Monocytes LGALS9_HAVCR2 0.0109539
Neutrophils CD8_Teff LGALS9_HAVCR2 0.0097818
Stroma CD8_Teff LGALS9_HAVCR2 0.0094947
Macrophages Monocytes LGALS9_HAVCR2 0.0094832
Progenitors CD8_Teff LGALS9_HAVCR2 0.0088512
CD8_Teff Monocytes LGALS9_HAVCR2 0.0088372
Neutrophils CD8_Tpex LGALS9_HAVCR2 0.0087559
CD4_T Monocytes LGALS9_HAVCR2 0.0085909
Stroma CD8_Tpex LGALS9_HAVCR2 0.0084987
Pre-B Monocytes LGALS9_HAVCR2 0.0084501
CD8_Naive Monocytes LGALS9_HAVCR2 0.0082052
Other Monocytes LGALS9_HAVCR2 0.0081377
NKT-like Monocytes LGALS9_HAVCR2 0.0079881
Progenitors CD8_Tpex LGALS9_HAVCR2 0.0079221
Other_gd CD8_Teff LGALS9_HAVCR2 0.0077259
CD8_Tex Monocytes LGALS9_HAVCR2 0.0069242
Other_gd CD8_Tpex LGALS9_HAVCR2 0.0069141
Vg4 Monocytes LGALS9_HAVCR2 0.0067016
CD8_Tpex CD8_Teff LGALS9_HAVCR2 0.0064830
CD8_Tpex CD8_Tpex LGALS9_HAVCR2 0.0058010
DCs CD8_Teff LGALS9_HAVCR2 0.0045367
Microglia-like CD8_Teff LGALS9_HAVCR2 0.0043797
DCs CD8_Tpex LGALS9_HAVCR2 0.0040587
Microglia-like CD8_Tpex LGALS9_HAVCR2 0.0039181
Macrophages CD8_Teff LGALS9_HAVCR2 0.0037883
CD8_Teff CD8_Teff LGALS9_HAVCR2 0.0035289
CD4_T CD8_Teff LGALS9_HAVCR2 0.0034300
Macrophages CD8_Tpex LGALS9_HAVCR2 0.0033889
Pre-B CD8_Teff LGALS9_HAVCR2 0.0033735
CD8_Naive CD8_Teff LGALS9_HAVCR2 0.0032752
Other CD8_Teff LGALS9_HAVCR2 0.0032482
NKT-like CD8_Teff LGALS9_HAVCR2 0.0031881
CD8_Teff CD8_Tpex LGALS9_HAVCR2 0.0031567
CD4_T CD8_Tpex LGALS9_HAVCR2 0.0030682
Pre-B CD8_Tpex LGALS9_HAVCR2 0.0030176
CD8_Naive CD8_Tpex LGALS9_HAVCR2 0.0029297
Other CD8_Tpex LGALS9_HAVCR2 0.0029055
NKT-like CD8_Tpex LGALS9_HAVCR2 0.0028518
CD8_Tex CD8_Teff LGALS9_HAVCR2 0.0027618
Vg4 CD8_Teff LGALS9_HAVCR2 0.0026726
CD8_Tex CD8_Tpex LGALS9_HAVCR2 0.0024703
Vg4 CD8_Tpex LGALS9_HAVCR2 0.0023905

Step 1d — B-ALL Galectin Output

ball_gal <- cns_net %>%
  filter(source == "B-ALL", pathway_name == "GALECTIN") %>%
  arrange(desc(prob))

cat("B-ALL GALECTIN outgoing in CNS:", nrow(ball_gal), "\n\n")
## B-ALL GALECTIN outgoing in CNS: 47
ball_gal %>%
  select(source, target, interaction_name, prob, pval) %>%
  head(25) %>%
  kable(caption = "Top 25 B-ALL → GALECTIN interactions (CNS)")
Top 25 B-ALL → GALECTIN interactions (CNS)
source target interaction_name prob pval
B-ALL Monocytes LGALS9_CD45 0.1424436 0
B-ALL CD8_Tpex LGALS9_CD45 0.1370330 0
B-ALL CD8_Teff LGALS9_CD45 0.1357315 0
B-ALL CD8_Tex LGALS9_CD45 0.1353338 0
B-ALL CD4_T LGALS9_CD45 0.1281408 0
B-ALL Other LGALS9_CD45 0.1278967 0
B-ALL CD8_Naive LGALS9_CD45 0.1278645 0
B-ALL Pre-B LGALS9_IGHM 0.1256823 0
B-ALL NKT-like LGALS9_CD45 0.1192309 0
B-ALL DCs LGALS9_CD45 0.1158341 0
B-ALL Vg4 LGALS9_CD45 0.1048894 0
B-ALL Other_gd LGALS9_CD45 0.1021184 0
B-ALL Pre-B LGALS9_CD45 0.1016737 0
B-ALL Vg6Vd4 LGALS9_CD45 0.1004244 0
B-ALL B-ALL LGALS9_CD45 0.0917183 0
B-ALL Monocytes LGALS9_CD44 0.0871337 0
B-ALL Stroma LGALS9_P4HB 0.0835998 0
B-ALL Basophils LGALS9_P4HB 0.0748385 0
B-ALL Neutrophils LGALS9_P4HB 0.0683865 0
B-ALL Other LGALS9_IGHM 0.0597214 0
B-ALL DCs LGALS9_IGHM 0.0565070 0
B-ALL Microglia-like LGALS9_HAVCR2 0.0536680 0
B-ALL CD8_Naive LGALS9_IGHM 0.0536433 0
B-ALL Neutrophils LGALS9_CD44 0.0521016 0
B-ALL Other LGALS9_CD44 0.0518921 0

Step 1e — Vg6Vd4 Galectin Output

vg6_gal <- cns_net %>%
  filter(source == "Vg6Vd4", pathway_name == "GALECTIN") %>%
  arrange(desc(prob))

if (nrow(vg6_gal) > 0) {
  cat("Vg6Vd4 GALECTIN outgoing in CNS:", nrow(vg6_gal), "\n\n")
  vg6_gal %>%
    select(source, target, interaction_name, prob, pval) %>%
    kable(caption = "Vg6Vd4 → GALECTIN interactions (CNS)")
} else {
  cat("No GALECTIN interactions from Vg6Vd4\n")
}
## Vg6Vd4 GALECTIN outgoing in CNS: 14
Vg6Vd4 → GALECTIN interactions (CNS)
source target interaction_name prob pval
Vg6Vd4 Pre-B LGALS9_IGHM 0.0192403 0.00
Vg6Vd4 Monocytes LGALS9_CD44 0.0128589 0.02
Vg6Vd4 Other LGALS9_IGHM 0.0085935 0.00
Vg6Vd4 DCs LGALS9_IGHM 0.0081073 0.00
Vg6Vd4 Microglia-like LGALS9_HAVCR2 0.0076801 0.00
Vg6Vd4 CD8_Naive LGALS9_IGHM 0.0076764 0.00
Vg6Vd4 Monocytes LGALS9_HAVCR2 0.0058655 0.00
Vg6Vd4 CD8_Tpex LGALS9_HAVCR2 0.0055052 0.00
Vg6Vd4 Neutrophils LGALS9_IGHM 0.0036530 0.00
Vg6Vd4 CD8_Tex LGALS9_HAVCR2 0.0025859 0.00
Vg6Vd4 Microglia-like LGALS9_IGHM 0.0023398 0.00
Vg6Vd4 CD4_T LGALS9_IGHM 0.0018786 0.00
Vg6Vd4 NKT-like LGALS9_IGHM 0.0017911 0.00
Vg6Vd4 CD8_Teff LGALS9_HAVCR2 0.0014242 0.00

Step 1f — Galectin Network Visualisation

tryCatch({
  netVisual_aggregate(cellchat_cns, signaling = "GALECTIN", layout = "circle")
}, error = function(e) cat("GALECTIN circle plot failed:", e$message, "\n"))

tryCatch({
  netVisual_aggregate(cellchat_bm, signaling = "GALECTIN", layout = "circle")
}, error = function(e) cat("GALECTIN circle plot (BM) failed:", e$message, "\n"))

tryCatch({
  ht <- netVisual_heatmap(cellchat_cns, signaling = "GALECTIN",
                          color.heatmap = "Reds")
  if (inherits(ht, c("HeatmapList", "Heatmap"))) ComplexHeatmap::draw(ht)
}, error = function(e) cat("GALECTIN heatmap failed:", e$message, "\n"))

tryCatch({
  print(netAnalysis_contribution(cellchat_cns, signaling = "GALECTIN") +
          ggtitle("GALECTIN L-R contribution — CNS"))
}, error = function(e) cat("Contribution plot failed:", e$message, "\n"))

Step 2 — TREM2 / APP Myeloid Programming

Stroma sends APP → TREM2/TYROBP and ApoE → TREM2/TYROBP to microglia-like cells and macrophages. TREM2 signalling promotes a homeostatic/tolerogenic macrophage state — potentially shielding the leukaemia from immune attack.

Step 2a — APP Pathway

app_in_cns <- "APP" %in% cellchat_cns@netP$pathways
app_in_bm  <- "APP" %in% cellchat_bm@netP$pathways

cat("APP pathway — CNS:", app_in_cns, "| BM:", app_in_bm, "\n\n")
## APP pathway — CNS: TRUE | BM: TRUE
if (app_in_cns) {
  netVisual_aggregate(cellchat_cns, signaling = "APP", layout = "circle")
}

if (app_in_cns) {
  print(netAnalysis_contribution(cellchat_cns, signaling = "APP") +
          ggtitle("APP L-R contribution — CNS"))
}

app_int <- cns_net %>%
  filter(pathway_name == "APP") %>%
  arrange(desc(prob))

if (nrow(app_int) > 0) {
  app_int %>%
    select(source, target, interaction_name, prob, pval) %>%
    head(20) %>%
    kable(caption = "Top 20 APP pathway interactions (CNS)")
}
Top 20 APP pathway interactions (CNS)
source target interaction_name prob pval
Stroma DCs APP_CD74 0.2961797 0
Stroma Pre-B APP_CD74 0.2893632 0
Stroma Plasma_B APP_CD74 0.2013547 0
Stroma Microglia-like APP_TREM2_TYROBP 0.1883189 0
DCs DCs APP_CD74 0.1527674 0
Stroma Other APP_CD74 0.1497289 0
DCs Pre-B APP_CD74 0.1485548 0
Neutrophils DCs APP_CD74 0.1354687 0
Microglia-like DCs APP_CD74 0.1327085 0
Neutrophils Pre-B APP_CD74 0.1316590 0
Stroma Macrophages APP_TREM2_TYROBP 0.1299598 0
Microglia-like Pre-B APP_CD74 0.1289648 0
Macrophages DCs APP_CD74 0.1234323 0
Monocytes DCs APP_CD74 0.1200592 0
Macrophages Pre-B APP_CD74 0.1199142 0
Monocytes Pre-B APP_CD74 0.1166244 0
DCs Plasma_B APP_CD74 0.0974970 0
DCs Microglia-like APP_TREM2_TYROBP 0.0904237 0
Neutrophils Plasma_B APP_CD74 0.0858229 0
Microglia-like Plasma_B APP_CD74 0.0839759 0

Step 2b — ApoE Pathway

apoe_in_cns <- "ApoE" %in% cellchat_cns@netP$pathways

cat("ApoE pathway in CNS:", apoe_in_cns, "\n\n")
## ApoE pathway in CNS: TRUE
if (apoe_in_cns) {
  netVisual_aggregate(cellchat_cns, signaling = "ApoE", layout = "circle")
}

apoe_int <- cns_net %>%
  filter(pathway_name == "ApoE") %>%
  arrange(desc(prob))

if (nrow(apoe_int) > 0) {
  apoe_int %>%
    select(source, target, interaction_name, prob, pval) %>%
    kable(caption = "ApoE pathway interactions (CNS)")
}
ApoE pathway interactions (CNS)
source target interaction_name prob pval
Macrophages Microglia-like APOE_TREM2_TYROBP 0.2692462 0
Monocytes Microglia-like APOE_TREM2_TYROBP 0.2058687 0
Macrophages Macrophages APOE_TREM2_TYROBP 0.1917321 0
Stroma Microglia-like APOE_TREM2_TYROBP 0.1462329 0
Monocytes Macrophages APOE_TREM2_TYROBP 0.1430293 0
Stroma Macrophages APOE_TREM2_TYROBP 0.0993201 0
Pre-B Microglia-like APOE_TREM2_TYROBP 0.0897621 0
Pre-B Macrophages APOE_TREM2_TYROBP 0.0596989 0
Microglia-like Microglia-like APOE_TREM2_TYROBP 0.0503086 0
Microglia-like Macrophages APOE_TREM2_TYROBP 0.0329804 0
Basophils Microglia-like APOE_TREM2_TYROBP 0.0261705 0
Basophils Macrophages APOE_TREM2_TYROBP 0.0170075 0

Step 2c — TREM2 Target Gene Expression

trem2_genes <- c("Trem2", "Tyrobp", "App", "Apoe", "Lpl", "Cst7", "Spp1")
trem2_present <- trem2_genes[trem2_genes %in% rownames(combined)]

# Detection in CNS myeloid populations
myeloid_groups <- c("Microglia-like", "Macrophages", "Monocytes", "DCs")
cns_meta <- combined@meta.data[combined$Tissue == "CNS" &
                                 combined$cellchat_group %in% myeloid_groups, ]
cns_counts <- GetAssayData(combined, layer = "counts")[, rownames(cns_meta)]

results <- list()
for (gene in trem2_present) {
  det <- tapply(cns_counts[gene, ], cns_meta$cellchat_group,
                function(x) round(mean(x > 0) * 100, 1))
  for (grp in names(det)) {
    results[[length(results) + 1]] <- data.frame(
      Gene = gene, Group = grp, Pct = det[grp], stringsAsFactors = FALSE
    )
  }
}

trem2_df <- bind_rows(results) %>%
  pivot_wider(names_from = Gene, values_from = Pct, values_fill = 0)

trem2_mat <- as.matrix(trem2_df[, -1])
rownames(trem2_mat) <- trem2_df$Group

ht <- Heatmap(trem2_mat,
              name = "% Detected",
              column_title = "TREM2 programme — CNS myeloid cells",
              col = circlize::colorRamp2(c(0, 10, 40, 80),
                                          c("white", "lightyellow", "orange", "red")),
              cluster_rows = FALSE, cluster_columns = FALSE,
              cell_fun = function(j, i, x, y, width, height, fill) {
                grid.text(sprintf("%.1f", trem2_mat[i, j]), x, y,
                          gp = gpar(fontsize = 9))
              })
ComplexHeatmap::draw(ht)

Step 3 — Niche Retention Circuits

Two parallel retention systems keep B-ALL and Vγ6Vδ4 in the CNS:

  • CXCL12 → CXCR4: Stroma → B-ALL (niche retention)
  • CXCL16 → CXCR6: Stroma → Vγ6Vδ4 (tissue residency)

Step 3a — CXCL Pathway Detail

cxcl_int <- cns_net %>%
  filter(pathway_name == "CXCL") %>%
  arrange(desc(prob))

cat("All CXCL interactions in CNS:", nrow(cxcl_int), "\n\n")
## All CXCL interactions in CNS: 33
cxcl_int %>%
  select(source, target, interaction_name, prob, pval) %>%
  kable(caption = "All CXCL interactions (CNS)")
All CXCL interactions (CNS)
source target interaction_name prob pval
Macrophages CD8_Tpex CXCL4_CXCR3 0.0908567 0
Stroma Monocytes CXCL12_CXCR4 0.0876590 0
Macrophages CD4_T CXCL4_CXCR3 0.0744119 0
Macrophages CD8_Teff CXCL4_CXCR3 0.0717662 0
Macrophages CD8_Tex CXCL4_CXCR3 0.0450944 0
Stroma Neutrophils CXCL12_CXCR4 0.0395500 0
Stroma B-ALL CXCL12_CXCR4 0.0389521 0
Stroma Vg6Vd4 CXCL16_CXCR6 0.0369221 0
Stroma Vg4 CXCL12_CXCR4 0.0368038 0
Stroma Pre-B CXCL12_CXCR4 0.0353603 0
Stroma Vg4 CXCL16_CXCR6 0.0325817 0
Stroma CD8_Tex CXCL16_CXCR6 0.0304104 0
Macrophages Vg6Vd4 CXCL16_CXCR6 0.0282805 0
Stroma NKT-like CXCL16_CXCR6 0.0265831 0
Stroma Basophils CXCL12_CXCR4 0.0262778 0
Stroma CD8_Teff CXCL16_CXCR6 0.0259910 0
Macrophages Vg4 CXCL16_CXCR6 0.0249296 0
Macrophages CD8_Tex CXCL16_CXCR6 0.0232560 0
Stroma CD4_T CXCL12_CXCR4 0.0230100 0
Stroma CD8_Tpex CXCL16_CXCR6 0.0220625 0
Macrophages Vg6Vd4 CXCL4_CXCR3 0.0215555 0
Stroma Other_gd CXCL16_CXCR6 0.0210682 0
Macrophages NKT-like CXCL16_CXCR6 0.0203103 0
Macrophages NKT-like CXCL4_CXCR3 0.0202821 0
Macrophages CD8_Teff CXCL16_CXCR6 0.0198551 0
Stroma DCs CXCL12_CXCR4 0.0171118 0
Macrophages CD8_Tpex CXCL16_CXCR6 0.0168380 0
Macrophages Other_gd CXCL16_CXCR6 0.0160753 0
Macrophages Other CXCL4_CXCR3 0.0131770 0
Stroma Stroma CXCL12_ACKR3 0.0101097 0
Stroma CD4_T CXCL16_CXCR6 0.0066057 0
Stroma Plasma_B CXCL12_CXCR4 0.0064916 0
Macrophages CD4_T CXCL16_CXCR6 0.0050226 0

Step 3b — CXCL12/CXCR4 in BM vs CNS

cxcl12_cns <- cns_net %>%
  filter(grepl("CXCL12.*CXCR4", interaction_name)) %>%
  select(source, target, interaction_name, prob) %>%
  mutate(Tissue = "CNS")

cxcl12_bm <- bm_net %>%
  filter(grepl("CXCL12.*CXCR4", interaction_name)) %>%
  select(source, target, interaction_name, prob) %>%
  mutate(Tissue = "BM")

cxcl12_all <- bind_rows(cxcl12_cns, cxcl12_bm) %>% arrange(Tissue, desc(prob))

if (nrow(cxcl12_all) > 0) {
  cxcl12_all %>%
    kable(caption = "CXCL12 → CXCR4 interactions — BM vs CNS")
} else {
  cat("No CXCL12-CXCR4 interactions detected\n")
}
CXCL12 → CXCR4 interactions — BM vs CNS
source target interaction_name prob Tissue
Stroma Basophils CXCL12_CXCR4 0.0235702 BM
Stroma Progenitors CXCL12_CXCR4 0.0222942 BM
Stroma Neutrophils CXCL12_CXCR4 0.0124922 BM
Stroma B-ALL CXCL12_CXCR4 0.0104463 BM
Stroma Monocytes CXCL12_CXCR4 0.0088057 BM
Stroma Pre-B CXCL12_CXCR4 0.0086065 BM
Stroma NKT-like CXCL12_CXCR4 0.0065604 BM
Stroma Other_gd CXCL12_CXCR4 0.0031240 BM
Stroma Stroma CXCL12_CXCR4 0.0024642 BM
Stroma Monocytes CXCL12_CXCR4 0.0876590 CNS
Stroma Neutrophils CXCL12_CXCR4 0.0395500 CNS
Stroma B-ALL CXCL12_CXCR4 0.0389521 CNS
Stroma Vg4 CXCL12_CXCR4 0.0368038 CNS
Stroma Pre-B CXCL12_CXCR4 0.0353603 CNS
Stroma Basophils CXCL12_CXCR4 0.0262778 CNS
Stroma CD4_T CXCL12_CXCR4 0.0230100 CNS
Stroma DCs CXCL12_CXCR4 0.0171118 CNS
Stroma Plasma_B CXCL12_CXCR4 0.0064916 CNS

Step 3c — CXCL16/CXCR6 (Vγ6Vδ4 Retention)

cxcl16_int <- cns_net %>%
  filter(grepl("CXCL16.*CXCR6", interaction_name)) %>%
  arrange(desc(prob))

if (nrow(cxcl16_int) > 0) {
  cat("CXCL16 → CXCR6 interactions in CNS:\n\n")
  cxcl16_int %>%
    select(source, target, interaction_name, prob, pval) %>%
    kable()
} else {
  cat("No CXCL16-CXCR6 interactions detected\n")
}
## CXCL16 → CXCR6 interactions in CNS:
source target interaction_name prob pval
Stroma Vg6Vd4 CXCL16_CXCR6 0.0369221 0
Stroma Vg4 CXCL16_CXCR6 0.0325817 0
Stroma CD8_Tex CXCL16_CXCR6 0.0304104 0
Macrophages Vg6Vd4 CXCL16_CXCR6 0.0282805 0
Stroma NKT-like CXCL16_CXCR6 0.0265831 0
Stroma CD8_Teff CXCL16_CXCR6 0.0259910 0
Macrophages Vg4 CXCL16_CXCR6 0.0249296 0
Macrophages CD8_Tex CXCL16_CXCR6 0.0232560 0
Stroma CD8_Tpex CXCL16_CXCR6 0.0220625 0
Stroma Other_gd CXCL16_CXCR6 0.0210682 0
Macrophages NKT-like CXCL16_CXCR6 0.0203103 0
Macrophages CD8_Teff CXCL16_CXCR6 0.0198551 0
Macrophages CD8_Tpex CXCL16_CXCR6 0.0168380 0
Macrophages Other_gd CXCL16_CXCR6 0.0160753 0
Stroma CD4_T CXCL16_CXCR6 0.0066057 0
Macrophages CD4_T CXCL16_CXCR6 0.0050226 0

Step 3d — Retention Receptor Expression

ret_genes <- c("Cxcl12", "Cxcr4", "Cxcl16", "Cxcr6")
ret_present <- ret_genes[ret_genes %in% rownames(combined)]

key_groups <- c("Stroma", "B-ALL", "Vg6Vd4", "Vg4", "Other_gd",
                "Macrophages", "Microglia-like", "Monocytes")

cns_meta <- combined@meta.data[combined$Tissue == "CNS" &
                                 combined$cellchat_group %in% key_groups, ]
cns_counts <- GetAssayData(combined, layer = "counts")[, rownames(cns_meta)]

results <- list()
for (gene in ret_present) {
  det <- tapply(cns_counts[gene, ], cns_meta$cellchat_group,
                function(x) round(mean(x > 0) * 100, 1))
  for (grp in names(det)) {
    results[[length(results) + 1]] <- data.frame(
      Gene = gene, Group = grp, Pct = det[grp], stringsAsFactors = FALSE
    )
  }
}

ret_df <- bind_rows(results) %>%
  pivot_wider(names_from = Gene, values_from = Pct, values_fill = 0)

ret_mat <- as.matrix(ret_df[, -1])
rownames(ret_mat) <- ret_df$Group

ht <- Heatmap(ret_mat,
              name = "% Detected",
              column_title = "Niche retention receptor expression — CNS",
              col = circlize::colorRamp2(c(0, 10, 30, 60),
                                          c("white", "lightyellow", "orange", "red")),
              cluster_rows = FALSE, cluster_columns = FALSE,
              cell_fun = function(j, i, x, y, width, height, fill) {
                grid.text(sprintf("%.1f", ret_mat[i, j]), x, y,
                          gp = gpar(fontsize = 9))
              })
ComplexHeatmap::draw(ht)

Step 4 — TGFβ Immunosuppressive Network

Step 4a — TGFβ Pathway in CNS

tgfb_in_cns <- grep("TGFb|TGFB", cellchat_cns@netP$pathways,
                     value = TRUE, ignore.case = TRUE)

cat("TGFb pathways in CNS:", paste(tgfb_in_cns, collapse = ", "), "\n\n")
## TGFb pathways in CNS: TGFb
for (p in tgfb_in_cns) {
  netVisual_aggregate(cellchat_cns, signaling = p, layout = "circle")
}

tgfb_int <- cns_net %>%
  filter(grepl("TGFb|TGFB", pathway_name, ignore.case = TRUE)) %>%
  arrange(desc(prob))

if (nrow(tgfb_int) > 0) {
  tgfb_int %>%
    select(source, target, interaction_name, prob, pval) %>%
    head(30) %>%
    kable(caption = "Top 30 TGFβ interactions (CNS)")
}
Top 30 TGFβ interactions (CNS)
source target interaction_name prob pval
Basophils Microglia-like TGFB1_TGFBR1_TGFBR2 0.0782119 0
Microglia-like Microglia-like TGFB1_TGFBR1_TGFBR2 0.0573102 0
Neutrophils Microglia-like TGFB1_TGFBR1_TGFBR2 0.0571360 0
DCs Microglia-like TGFB1_TGFBR1_TGFBR2 0.0557982 0
Monocytes Microglia-like TGFB1_TGFBR1_TGFBR2 0.0525632 0
Other Microglia-like TGFB1_TGFBR1_TGFBR2 0.0453157 0
Basophils Monocytes TGFB1_TGFBR1_TGFBR2 0.0337040 0
Macrophages Microglia-like TGFB1_TGFBR1_TGFBR2 0.0276819 0
B-ALL Microglia-like TGFB1_TGFBR1_TGFBR2 0.0257600 0
Microglia-like Monocytes TGFB1_TGFBR1_TGFBR2 0.0243822 0
Neutrophils Monocytes TGFB1_TGFBR1_TGFBR2 0.0243255 0
DCs Monocytes TGFB1_TGFBR1_TGFBR2 0.0237171 0
Other_gd Microglia-like TGFB1_TGFBR1_TGFBR2 0.0231569 0
Monocytes Monocytes TGFB1_TGFBR1_TGFBR2 0.0222981 0
NKT-like Microglia-like TGFB1_TGFBR1_TGFBR2 0.0197716 0
Pre-B Microglia-like TGFB1_TGFBR1_TGFBR2 0.0191886 0
Other Monocytes TGFB1_TGFBR1_TGFBR2 0.0191856 0
CD8_Tex Microglia-like TGFB1_TGFBR1_TGFBR2 0.0181498 0
Vg6Vd4 Microglia-like TGFB1_TGFBR1_TGFBR2 0.0178296 0
CD8_Teff Microglia-like TGFB1_TGFBR1_TGFBR2 0.0174341 0
CD4_T Microglia-like TGFB1_TGFBR1_TGFBR2 0.0146419 0
CD8_Tpex Microglia-like TGFB1_TGFBR1_TGFBR2 0.0144551 0
Macrophages Monocytes TGFB1_TGFBR1_TGFBR2 0.0115682 0
Vg4 Microglia-like TGFB1_TGFBR1_TGFBR2 0.0111526 0
B-ALL Monocytes TGFB1_TGFBR1_TGFBR2 0.0107526 0
Basophils Basophils TGFB1_TGFBR1_TGFBR2 0.0106710 0
Other_gd Monocytes TGFB1_TGFBR1_TGFBR2 0.0096510 0
Basophils Other TGFB1_TGFBR1_TGFBR2 0.0096267 0
Basophils Stroma TGFB1_ACVR1_TGFBR1 0.0085978 0
NKT-like Monocytes TGFB1_TGFBR1_TGFBR2 0.0082235 0

Step 4b — TGFβ: BM vs CNS Comparison

tgfb_cns_sum <- cns_net %>%
  filter(grepl("TGFb|TGFB", pathway_name, ignore.case = TRUE)) %>%
  group_by(source) %>%
  summarise(cns_prob = round(sum(prob), 3), cns_n = n(), .groups = "drop")

tgfb_bm_sum <- bm_net %>%
  filter(grepl("TGFb|TGFB", pathway_name, ignore.case = TRUE)) %>%
  group_by(source) %>%
  summarise(bm_prob = round(sum(prob), 3), bm_n = n(), .groups = "drop")

tgfb_comp <- full_join(tgfb_cns_sum, tgfb_bm_sum, by = "source") %>%
  mutate(across(where(is.numeric), ~replace_na(., 0))) %>%
  arrange(desc(cns_prob))

tgfb_comp %>%
  kable(caption = "TGFβ sender comparison — CNS vs BM")
TGFβ sender comparison — CNS vs BM
source cns_prob cns_n bm_prob bm_n
Basophils 0.176 11 0.105 12
Microglia-like 0.128 11 0.020 5
Neutrophils 0.127 11 0.103 12
DCs 0.124 11 0.104 12
Monocytes 0.117 11 0.079 12
Other 0.101 11 0.011 4
Macrophages 0.052 7 0.105 12
B-ALL 0.048 7 0.028 7
Other_gd 0.038 5 0.008 3
NKT-like 0.032 5 0.006 3
Pre-B 0.031 5 0.040 9
CD8_Tex 0.030 5 0.001 2
Vg6Vd4 0.029 5 0.000 0
CD8_Teff 0.028 5 0.007 3
Stroma 0.028 28 0.058 11
CD4_T 0.024 5 0.007 3
CD8_Tpex 0.023 5 0.007 3
Vg4 0.018 5 0.007 3
Plasma_B 0.004 4 0.000 2
CD8_Naive 0.000 0 0.008 3
Progenitors 0.000 0 0.103 12

Step 5 — Cell-Type Focused Analysis

Step 5a — Vg6Vd4 Communication

vg6_out <- cns_net %>% filter(source == "Vg6Vd4") %>% arrange(desc(prob))
if (nrow(vg6_out) > 0) {
  cat("Vg6Vd4 → targets in CNS:", nrow(vg6_out), "interactions\n\n")
  vg6_out %>%
    select(source, target, interaction_name, pathway_name, prob, pval) %>%
    head(40) %>%
    kable(caption = "Top 40 Vg6Vd4 outgoing interactions (CNS)")
} else {
  cat("No outgoing interactions from Vg6Vd4\n")
}
## Vg6Vd4 → targets in CNS: 194 interactions
Top 40 Vg6Vd4 outgoing interactions (CNS)
source target interaction_name pathway_name prob pval
Vg6Vd4 CD8_Tpex H2-K1_CD8B1 MHC-I 0.2324739 0
Vg6Vd4 CD8_Tpex H2-D1_CD8B1 MHC-I 0.2310024 0
Vg6Vd4 Stroma PPIA_BSG CypA 0.1891784 0
Vg6Vd4 CD8_Tpex H2-K1_CD8A MHC-I 0.1872090 0
Vg6Vd4 CD8_Tpex H2-D1_CD8A MHC-I 0.1859546 0
Vg6Vd4 CD8_Tex H2-K1_CD8B1 MHC-I 0.1822292 0
Vg6Vd4 CD8_Tex H2-D1_CD8B1 MHC-I 0.1810008 0
Vg6Vd4 CD8_Tex H2-K1_CD8A MHC-I 0.1704870 0
Vg6Vd4 CD8_Tex H2-D1_CD8A MHC-I 0.1693213 0
Vg6Vd4 Monocytes THY1_ADGRE5 ADGRE 0.1442768 0
Vg6Vd4 Microglia-like PPIA_BSG CypA 0.1259764 0
Vg6Vd4 Other SELPLG_SELL SELPLG 0.1248258 0
Vg6Vd4 Monocytes THY1_ITGAM_ITGB2 THY1 0.1176268 0
Vg6Vd4 CD8_Naive SELPLG_SELL SELPLG 0.1119500 0
Vg6Vd4 Basophils THY1_ADGRE5 ADGRE 0.1077053 0
Vg6Vd4 Pre-B CD52_SIGLECG CD52 0.0988059 0
Vg6Vd4 CD8_Tpex H2-Q4_CD8B1 MHC-I 0.0969942 0
Vg6Vd4 CD8_Tpex H2-T23_CD8B1 MHC-I 0.0942558 0
Vg6Vd4 CD8_Tpex H2-Q7_CD8B1 MHC-I 0.0910767 0
Vg6Vd4 Macrophages PTPRC_MRC1 CD45 0.0890579 0
Vg6Vd4 CD8_Tpex THY1_ADGRE5 ADGRE 0.0871154 0
Vg6Vd4 Monocytes THY1_ITGAX_ITGB2 THY1 0.0850646 0
Vg6Vd4 Microglia-like THY1_ITGAM_ITGB2 THY1 0.0837339 0
Vg6Vd4 Basophils THY1_ITGAM_ITGB2 THY1 0.0835026 0
Vg6Vd4 Pre-B SELPLG_SELL SELPLG 0.0793487 0
Vg6Vd4 DCs THY1_ITGAM_ITGB2 THY1 0.0785057 0
Vg6Vd4 CD8_Tpex H2-Q4_CD8A MHC-I 0.0755132 0
Vg6Vd4 CD8_Tpex H2-T23_CD8A MHC-I 0.0733320 0
Vg6Vd4 CD8_Tex H2-Q4_CD8B1 MHC-I 0.0732368 0
Vg6Vd4 CD8_Tex H2-T23_CD8B1 MHC-I 0.0711163 0
Vg6Vd4 CD8_Tpex H2-Q7_CD8A MHC-I 0.0708035 0
Vg6Vd4 CD8_Tex H2-Q7_CD8B1 MHC-I 0.0686585 0
Vg6Vd4 Neutrophils THY1_ITGAM_ITGB2 THY1 0.0683062 0
Vg6Vd4 CD8_Tex THY1_ADGRE5 ADGRE 0.0681645 0
Vg6Vd4 CD8_Tex H2-Q4_CD8A MHC-I 0.0679343 0
Vg6Vd4 CD4_T THY1_ADGRE5 ADGRE 0.0671047 0
Vg6Vd4 CD8_Teff H2-K1_CD8B1 MHC-I 0.0665865 0
Vg6Vd4 CD8_Teff H2-D1_CD8B1 MHC-I 0.0660746 0
Vg6Vd4 CD8_Tex H2-T23_CD8A MHC-I 0.0659564 0
Vg6Vd4 Basophils SELPLG_SELL SELPLG 0.0656115 0
vg6_in <- cns_net %>% filter(target == "Vg6Vd4") %>% arrange(desc(prob))
if (nrow(vg6_in) > 0) {
  cat("Sources → Vg6Vd4 in CNS:", nrow(vg6_in), "interactions\n\n")
  vg6_in %>%
    select(source, target, interaction_name, pathway_name, prob, pval) %>%
    head(30) %>%
    kable(caption = "Top 30 incoming to Vg6Vd4 (CNS)")
}
## Sources → Vg6Vd4 in CNS: 204 interactions
Top 30 incoming to Vg6Vd4 (CNS)
source target interaction_name pathway_name prob pval
Basophils Vg6Vd4 CCL6_CCR2 CCL 0.2034164 0
Monocytes Vg6Vd4 CCL6_CCR2 CCL 0.1263597 0
Macrophages Vg6Vd4 CCL6_CCR2 CCL 0.1252960 0
B-ALL Vg6Vd4 LGALS9_CD45 GALECTIN 0.1004244 0
Stroma Vg6Vd4 PTN_NCL PTN 0.0886199 0
Stroma Vg6Vd4 COL1A2_CD44 COLLAGEN 0.0850295 0
Stroma Vg6Vd4 MDK_NCL MK 0.0814651 0
DCs Vg6Vd4 CCL6_CCR2 CCL 0.0809162 0
Stroma Vg6Vd4 COL6A2_CD44 COLLAGEN 0.0669959 0
Stroma Vg6Vd4 COL1A1_CD44 COLLAGEN 0.0657416 0
Macrophages Vg6Vd4 CCL8_CCR2 CCL 0.0610375 0
Stroma Vg6Vd4 COL6A1_CD44 COLLAGEN 0.0596367 0
Macrophages Vg6Vd4 IGF1_IGF1R IGF 0.0570904 0
Stroma Vg6Vd4 FN1_CD44 FN1 0.0533237 0
Microglia-like Vg6Vd4 JAM1_ITGAL_ITGB2 JAM 0.0515015 0
B-ALL Vg6Vd4 LGALS9_CD44 GALECTIN 0.0501173 0
Basophils Vg6Vd4 CTSG_F2R PARs 0.0463306 0
B-ALL Vg6Vd4 GZMA_F2R PARs 0.0382336 0
Stroma Vg6Vd4 CXCL16_CXCR6 CXCL 0.0369221 0
B-ALL Vg6Vd4 LTB4-LTA4H_LTB4R1 CysLTs 0.0368535 0
Microglia-like Vg6Vd4 LGALS9_CD44 GALECTIN 0.0361118 0
Monocytes Vg6Vd4 Cholesterol-Cholesterol-LIPA_RORA Cholesterol 0.0360642 0
Other Vg6Vd4 GZMA_F2R PARs 0.0354417 0
Basophils Vg6Vd4 LGALS9_CD44 GALECTIN 0.0339574 0
Stroma Vg6Vd4 COL4A1_CD44 COLLAGEN 0.0321864 0
Monocytes Vg6Vd4 SIRPB1A_CD47 SIRP 0.0319590 0
Neutrophils Vg6Vd4 LTB4-LTA4H_LTB4R1 CysLTs 0.0319548 0
Monocytes Vg6Vd4 Cholesterol-Cholesterol-LIPA_RORC Cholesterol 0.0308640 0
Macrophages Vg6Vd4 LGALS9_CD44 GALECTIN 0.0303297 0
Monocytes Vg6Vd4 SIRPB1B_CD47 SIRP 0.0302450 0
tryCatch({
  print(netVisual_bubble(cellchat_cns, sources.use = "Vg6Vd4",
                         remove.isolate = TRUE,
                         title.name = "Vg6Vd4 → targets (CNS)"))
}, error = function(e) cat("Bubble plot failed\n"))

tryCatch({
  print(netVisual_bubble(cellchat_cns, targets.use = "Vg6Vd4",
                         remove.isolate = TRUE,
                         title.name = "Sources → Vg6Vd4 (CNS)"))
}, error = function(e) cat("Bubble plot failed\n"))

Vg6Vd4 Outgoing by Pathway

if (nrow(vg6_out) > 0) {
  vg6_out %>%
    group_by(pathway_name) %>%
    summarise(
      n_targets = n_distinct(target),
      n_LR = n(),
      total_prob = round(sum(prob), 3),
      .groups = "drop"
    ) %>%
    arrange(desc(total_prob)) %>%
    kable(caption = "Vg6Vd4 outgoing pathways ranked (CNS)")
}
Vg6Vd4 outgoing pathways ranked (CNS)
pathway_name n_targets n_LR total_prob
MHC-I 5 57 3.199
ADGRE 12 12 0.755
THY1 7 12 0.704
SELPLG 7 7 0.508
MIF 6 12 0.340
CypA 2 2 0.315
CD45 2 2 0.152
CD52 3 3 0.124
GALECTIN 12 14 0.089
CLEC 4 10 0.087
IL16 3 3 0.070
SEMA4 7 7 0.069
Cholesterol 8 10 0.065
Prostaglandin 8 9 0.064
CysLTs 8 8 0.043
CD48 4 4 0.035
TGFb 4 5 0.029
KLK 4 4 0.022
LIGHT 5 5 0.017
FLT3 3 3 0.015
RANKL 2 2 0.005
DHEA 1 1 0.002
ADGRA 1 1 0.001
BST2 1 1 0.001

Step 5b — All γδ T Cell Communication

gdt_groups <- c("Vg6Vd4", "Vg4", "Other_gd")

gdt_involved <- cns_net %>%
  filter(source %in% gdt_groups | target %in% gdt_groups)

cat("Total interactions involving γδ T cells in CNS:", nrow(gdt_involved), "\n\n")
## Total interactions involving γδ T cells in CNS: 1226
gdt_involved %>%
  group_by(source, target, pathway_name) %>%
  summarise(n_LR = n(), total_prob = round(sum(prob), 4), .groups = "drop") %>%
  arrange(desc(total_prob)) %>%
  head(40) %>%
  kable(caption = "Top 40 γδ T cell interactions — CNS")
Top 40 γδ T cell interactions — CNS
source target pathway_name n_LR total_prob
Vg6Vd4 CD8_Tpex MHC-I 15 1.4473
Vg4 CD8_Tpex MHC-I 17 1.4163
Other_gd CD8_Tpex MHC-I 17 1.3444
Vg6Vd4 CD8_Tex MHC-I 14 1.1868
Vg4 CD8_Tex MHC-I 16 1.1627
Other_gd CD8_Tex MHC-I 16 1.1037
Stroma Vg6Vd4 COLLAGEN 21 0.5507
Vg6Vd4 CD8_Teff MHC-I 14 0.4042
Vg4 CD8_Teff MHC-I 16 0.3949
Other_gd CD8_Teff MHC-I 16 0.3744
Stroma Vg4 COLLAGEN 7 0.3184
Macrophages Vg6Vd4 CCL 5 0.2350
Vg4 Monocytes THY1 2 0.2043
Basophils Vg6Vd4 CCL 1 0.2034
Vg6Vd4 Monocytes THY1 2 0.2027
Stroma Other_gd COLLAGEN 7 0.1939
Vg6Vd4 Stroma CypA 1 0.1892
Other_gd Stroma CypA 1 0.1874
Macrophages Vg4 CCL 5 0.1821
Vg4 Stroma CypA 1 0.1759
Other_gd Monocytes THY1 2 0.1744
Basophils Vg4 CCL 1 0.1623
B-ALL Vg4 GALECTIN 2 0.1523
B-ALL Vg6Vd4 GALECTIN 2 0.1505
Vg4 Monocytes ADGRE 1 0.1454
Vg6Vd4 Monocytes ADGRE 1 0.1443
Macrophages Other_gd CCL 5 0.1358
Vg4 DCs THY1 2 0.1340
Vg6Vd4 DCs THY1 2 0.1329
B-ALL Other_gd GALECTIN 2 0.1308
Monocytes Vg6Vd4 CCL 1 0.1264
Vg6Vd4 Microglia-like CypA 1 0.1260
Other_gd Monocytes ADGRE 1 0.1249
Vg6Vd4 Other SELPLG 1 0.1248
Other_gd Microglia-like CypA 1 0.1247
Basophils Other_gd CCL 1 0.1242
Vg6Vd4 CD8_Naive MHC-I 7 0.1233
Monocytes Other_gd SIRP 3 0.1229
Vg4 Other SELPLG 1 0.1213
Vg4 CD8_Naive MHC-I 8 0.1204

Step 5c — B-ALL Communication

ball_in <- cns_net %>% filter(target == "B-ALL") %>% arrange(desc(prob))
cat("B-ALL incoming in CNS:", nrow(ball_in), "\n\n")
## B-ALL incoming in CNS: 309
ball_in %>%
  select(source, target, interaction_name, pathway_name, prob, pval) %>%
  head(40) %>%
  kable(caption = "Top 40 incoming to B-ALL (CNS)")
Top 40 incoming to B-ALL (CNS)
source target interaction_name pathway_name prob pval
Stroma B-ALL PTN_NCL PTN 0.1279171 0
B-ALL B-ALL PPIA_BSG CypA 0.1218360 0
Stroma B-ALL MDK_NCL MK 0.1180004 0
B-ALL B-ALL LGALS9_CD45 GALECTIN 0.0917183 0
Stroma B-ALL COL1A2_ITGA9_ITGB1 COLLAGEN 0.0603417 0
Monocytes B-ALL SIRPB1A_CD47 SIRP 0.0496955 0
B-ALL B-ALL LGALS9_P4HB GALECTIN 0.0493893 0
Stroma B-ALL COL6A2_ITGA9_ITGB1 COLLAGEN 0.0472735 0
Monocytes B-ALL SIRPB1B_CD47 SIRP 0.0470765 0
Stroma B-ALL COL1A1_ITGA9_ITGB1 COLLAGEN 0.0463701 0
Monocytes B-ALL SIRPB1C_CD47 SIRP 0.0453306 0
Stroma B-ALL FN1_ITGA4_ITGB1 FN1 0.0433364 0
Stroma B-ALL COL6A1_ITGA9_ITGB1 COLLAGEN 0.0419833 0
Stroma B-ALL THBS2_CD47 THBS 0.0407578 0
Stroma B-ALL CXCL12_CXCR4 CXCL 0.0389521 0
Stroma B-ALL MDK_ITGA4_ITGB1 MK 0.0357699 0
Monocytes B-ALL PECAM1_PECAM1 PECAM1 0.0357338 0
Basophils B-ALL PECAM1_PECAM1 PECAM1 0.0255439 0
Stroma B-ALL THBS3_CD47 THBS 0.0252625 0
Pre-B B-ALL PECAM1_PECAM1 PECAM1 0.0238706 0
CD8_Tpex B-ALL THY1_ADGRE5 ADGRE 0.0227994 0
Stroma B-ALL COL4A1_ITGA9_ITGB1 COLLAGEN 0.0224646 0
CD8_Tex B-ALL THY1_ADGRE5 ADGRE 0.0217347 0
Vg4 B-ALL THY1_ADGRE5 ADGRE 0.0207327 0
CD8_Teff B-ALL THY1_ADGRE5 ADGRE 0.0206161 0
Stroma B-ALL LAMB2_ITGA9_ITGB1 LAMININ 0.0205940 0
Vg6Vd4 B-ALL THY1_ADGRE5 ADGRE 0.0205558 0
B-ALL B-ALL THY1_ADGRE5 ADGRE 0.0195692 0
Monocytes B-ALL SEMA4D_CD72 SEMA4 0.0172237 0
B-ALL B-ALL PECAM1_PECAM1 PECAM1 0.0168901 0
Stroma B-ALL FN1_ITGA4_ITGB7 FN1 0.0160582 0
Stroma B-ALL COL4A2_ITGA9_ITGB1 COLLAGEN 0.0152985 0
Stroma B-ALL LAMA4_ITGA9_ITGB1 LAMININ 0.0141585 0
CD8_Tex B-ALL H2-K1_CD8B1 MHC-I 0.0140360 0
CD8_Tpex B-ALL H2-K1_CD8B1 MHC-I 0.0137820 0
CD8_Tpex B-ALL SEMA4D_CD72 SEMA4 0.0137302 0
Stroma B-ALL THBS1_CD47 THBS 0.0137107 0
CD8_Teff B-ALL H2-K1_CD8B1 MHC-I 0.0137012 0
CD4_T B-ALL H2-K1_CD8B1 MHC-I 0.0133907 0
Microglia-like B-ALL SELPLG_SELL SELPLG 0.0133738 0
ball_out <- cns_net %>% filter(source == "B-ALL") %>% arrange(desc(prob))
cat("B-ALL outgoing in CNS:", nrow(ball_out), "\n\n")
## B-ALL outgoing in CNS: 337
ball_out %>%
  select(source, target, interaction_name, pathway_name, prob, pval) %>%
  head(40) %>%
  kable(caption = "Top 40 outgoing from B-ALL (CNS)")
Top 40 outgoing from B-ALL (CNS)
source target interaction_name pathway_name prob pval
B-ALL Stroma PPIA_BSG CypA 0.2283420 0
B-ALL Microglia-like PPIA_BSG CypA 0.1545499 0
B-ALL Monocytes LGALS9_CD45 GALECTIN 0.1424436 0
B-ALL Monocytes THY1_ADGRE5 ADGRE 0.1381902 0
B-ALL CD8_Tpex LGALS9_CD45 GALECTIN 0.1370330 0
B-ALL CD8_Teff LGALS9_CD45 GALECTIN 0.1357315 0
B-ALL CD8_Tex LGALS9_CD45 GALECTIN 0.1353338 0
B-ALL CD4_T LGALS9_CD45 GALECTIN 0.1281408 0
B-ALL Other LGALS9_CD45 GALECTIN 0.1278967 0
B-ALL CD8_Naive LGALS9_CD45 GALECTIN 0.1278645 0
B-ALL Pre-B LGALS9_IGHM GALECTIN 0.1256823 0
B-ALL CD8_Tpex LCK_CD8A_CD8B1 LCK 0.1237069 0
B-ALL B-ALL PPIA_BSG CypA 0.1218360 0
B-ALL NKT-like LGALS9_CD45 GALECTIN 0.1192309 0
B-ALL DCs LGALS9_CD45 GALECTIN 0.1158341 0
B-ALL Monocytes THY1_ITGAM_ITGB2 THY1 0.1125167 0
B-ALL DCs MIF_CD74_CD44 MIF 0.1110026 0
B-ALL Vg4 LGALS9_CD45 GALECTIN 0.1048894 0
B-ALL Basophils THY1_ADGRE5 ADGRE 0.1029759 0
B-ALL CD8_Tex LCK_CD8A_CD8B1 LCK 0.1026416 0
B-ALL Other_gd LGALS9_CD45 GALECTIN 0.1021184 0
B-ALL Pre-B LGALS9_CD45 GALECTIN 0.1016737 0
B-ALL Other MIF_CD74_CD44 MIF 0.1008936 0
B-ALL Vg6Vd4 LGALS9_CD45 GALECTIN 0.1004244 0
B-ALL B-ALL LGALS9_CD45 GALECTIN 0.0917183 0
B-ALL Monocytes LGALS9_CD44 GALECTIN 0.0871337 0
B-ALL Plasma_B MIF_CD74_CD44 MIF 0.0865253 0
B-ALL Pre-B MIF_CD74_CXCR4 MIF 0.0858232 0
B-ALL Pre-B MIF_CD74_CD44 MIF 0.0837749 0
B-ALL Stroma LGALS9_P4HB GALECTIN 0.0835998 0
B-ALL CD8_Tpex THY1_ADGRE5 ADGRE 0.0832058 0
B-ALL Macrophages PTPRC_MRC1 CD45 0.0812482 0
B-ALL Monocytes THY1_ITGAX_ITGB2 THY1 0.0812389 0
B-ALL Microglia-like THY1_ITGAM_ITGB2 THY1 0.0799628 0
B-ALL Basophils THY1_ITGAM_ITGB2 THY1 0.0797410 0
B-ALL DCs THY1_ITGAM_ITGB2 THY1 0.0749508 0
B-ALL Basophils LGALS9_P4HB GALECTIN 0.0748385 0
B-ALL Neutrophils LGALS9_P4HB GALECTIN 0.0683865 0
B-ALL Other SELPLG_SELL SELPLG 0.0680590 0
B-ALL Neutrophils THY1_ITGAM_ITGB2 THY1 0.0651805 0
tryCatch({
  print(netVisual_bubble(cellchat_merged,
                         targets.use = "B-ALL",
                         comparison = c(1, 2),
                         remove.isolate = TRUE,
                         title.name = "Incoming to B-ALL — BM vs CNS",
                         angle.x = 45))
}, error = function(e) cat("Bubble comparison failed:", e$message, "\n"))

Step 5d — Stroma Outgoing (Niche Signals)

stroma_out <- cns_net %>% filter(source == "Stroma") %>% arrange(desc(prob))
cat("Stroma outgoing in CNS:", nrow(stroma_out), "\n\n")
## Stroma outgoing in CNS: 1133
stroma_out %>%
  select(source, target, interaction_name, pathway_name, prob, pval) %>%
  head(40) %>%
  kable(caption = "Top 40 Stroma → target interactions (CNS)")
Top 40 Stroma → target interactions (CNS)
source target interaction_name pathway_name prob pval
Stroma DCs APP_CD74 APP 0.2961797 0
Stroma Pre-B APP_CD74 APP 0.2893632 0
Stroma Plasma_B APP_CD74 APP 0.2013547 0
Stroma Microglia-like APP_TREM2_TYROBP APP 0.1883189 0
Stroma Stroma PPIA_BSG CypA 0.1671204 0
Stroma Other APP_CD74 APP 0.1497289 0
Stroma Microglia-like APOE_TREM2_TYROBP ApoE 0.1462329 0
Stroma Monocytes COL1A2_CD44 COLLAGEN 0.1439247 0
Stroma CD8_Tpex H2-D1_CD8B1 MHC-I 0.1358563 0
Stroma Macrophages APP_TREM2_TYROBP APP 0.1299598 0
Stroma B-ALL PTN_NCL PTN 0.1279171 0
Stroma Monocytes FN1_ITGA4_ITGB1 FN1 0.1186244 0
Stroma B-ALL MDK_NCL MK 0.1180004 0
Stroma CD8_Tpex H2-K1_CD8B1 MHC-I 0.1173175 0
Stroma Monocytes COL6A2_CD44 COLLAGEN 0.1149697 0
Stroma Monocytes COL1A1_CD44 COLLAGEN 0.1129259 0
Stroma CD8_Tpex H2-D1_CD8A MHC-I 0.1067865 0
Stroma CD8_Tex H2-D1_CD8B1 MHC-I 0.1036730 0
Stroma Monocytes COL6A1_CD44 COLLAGEN 0.1029221 0
Stroma Macrophages APOE_TREM2_TYROBP ApoE 0.0993201 0
Stroma Monocytes MDK_ITGA4_ITGB1 MK 0.0992769 0
Stroma Stroma MDK_LRP1 MK 0.0972419 0
Stroma CD8_Tex H2-D1_CD8A MHC-I 0.0963960 0
Stroma CD4_T FN1_ITGA4_ITGB1 FN1 0.0949843 0
Stroma Basophils COL1A2_ITGA2_ITGB1 COLLAGEN 0.0940224 0
Stroma Other_gd PTN_NCL PTN 0.0930765 0
Stroma Monocytes FN1_CD44 FN1 0.0924776 0
Stroma CD8_Tpex H2-K1_CD8A MHC-I 0.0917931 0
Stroma NKT-like PTN_NCL PTN 0.0896040 0
Stroma CD8_Tex H2-K1_CD8B1 MHC-I 0.0890733 0
Stroma Vg4 PTN_NCL PTN 0.0889289 0
Stroma Vg6Vd4 PTN_NCL PTN 0.0886199 0
Stroma Neutrophils COL1A2_CD44 COLLAGEN 0.0882676 0
Stroma Other COL1A2_CD44 COLLAGEN 0.0879262 0
Stroma Monocytes CXCL12_CXCR4 CXCL 0.0876590 0
Stroma CD4_T PTN_NCL PTN 0.0868904 0
Stroma Other_gd MDK_NCL MK 0.0855957 0
Stroma Vg6Vd4 COL1A2_CD44 COLLAGEN 0.0850295 0
Stroma CD8_Teff FN1_ITGA4_ITGB1 FN1 0.0849639 0
Stroma CD8_Naive PTN_NCL PTN 0.0838981 0
tryCatch({
  print(netVisual_bubble(cellchat_cns, sources.use = "Stroma",
                         remove.isolate = TRUE,
                         title.name = "Stroma → targets (CNS)"))
}, error = function(e) cat("Stroma bubble failed\n"))

Stroma Outgoing by Pathway

stroma_out %>%
  group_by(pathway_name) %>%
  summarise(
    n_targets = n_distinct(target),
    n_LR = n(),
    total_prob = round(sum(prob), 3),
    .groups = "drop"
  ) %>%
  arrange(desc(total_prob)) %>%
  head(25) %>%
  kable(caption = "Stroma outgoing pathways ranked (CNS)")
Stroma outgoing pathways ranked (CNS)
pathway_name n_targets n_LR total_prob
COLLAGEN 18 203 6.144
MK 20 52 2.570
FN1 20 64 2.445
APP 19 30 2.005
PTN 20 32 1.766
THBS 20 96 1.510
MHC-I 5 49 1.374
LAMININ 17 104 1.246
ICAM 17 57 0.991
CXCL 16 18 0.524
MIF 6 12 0.499
ADGRE 18 36 0.282
GALECTIN 14 19 0.267
ApoE 2 2 0.246
ANGPTL 9 17 0.226
CypA 1 1 0.167
COMPLEMENT 7 13 0.165
Prostaglandin 8 20 0.103
CX3C 4 4 0.095
SPP1 18 47 0.081
CLEC 4 5 0.076
MHC-II 3 12 0.074
GAS 2 2 0.057
ADGRG 3 6 0.056
PROS 2 2 0.054

Step 5e — Microglia-like Communication

mg_out <- cns_net %>% filter(source == "Microglia-like") %>% arrange(desc(prob))
mg_in  <- cns_net %>% filter(target == "Microglia-like") %>% arrange(desc(prob))

cat("Microglia-like outgoing:", nrow(mg_out), "| incoming:", nrow(mg_in), "\n\n")
## Microglia-like outgoing: 396 | incoming: 269
mg_out %>%
  select(source, target, interaction_name, pathway_name, prob, pval) %>%
  head(30) %>%
  kable(caption = "Top 30 Microglia-like outgoing (CNS)")
Top 30 Microglia-like outgoing (CNS)
source target interaction_name pathway_name prob pval
Microglia-like Other SELPLG_SELL SELPLG 0.1726795 0.00
Microglia-like CD8_Tpex H2-D1_CD8B1 MHC-I 0.1607619 0.00
Microglia-like CD8_Naive SELPLG_SELL SELPLG 0.1557460 0.00
Microglia-like Stroma PPIA_BSG CypA 0.1483455 0.00
Microglia-like CD8_Tpex H2-K1_CD8B1 MHC-I 0.1457623 0.00
Microglia-like Basophils LAIR1_LILRB4A LAIR1 0.1395942 0.00
Microglia-like DCs APP_CD74 APP 0.1327085 0.00
Microglia-like Pre-B APP_CD74 APP 0.1289648 0.00
Microglia-like CD8_Tpex H2-D1_CD8A MHC-I 0.1271469 0.00
Microglia-like CD8_Tex H2-D1_CD8B1 MHC-I 0.1235220 0.00
Microglia-like Monocytes JAM1_ITGAL_ITGB2 JAM 0.1186302 0.00
Microglia-like CD8_Tex H2-D1_CD8A MHC-I 0.1150306 0.00
Microglia-like CD8_Tpex H2-K1_CD8A MHC-I 0.1148545 0.00
Microglia-like Pre-B SELPLG_SELL SELPLG 0.1119993 0.00
Microglia-like CD8_Tex H2-K1_CD8B1 MHC-I 0.1115353 0.00
Microglia-like Monocytes LGALS9_CD45 GALECTIN 0.1055026 0.00
Microglia-like CD8_Tex H2-K1_CD8A MHC-I 0.1037703 0.00
Microglia-like Microglia-like PROS1_MERTK PROS 0.1014361 0.00
Microglia-like CD8_Tpex LGALS9_CD45 GALECTIN 0.1013294 0.01
Microglia-like CD8_Teff LGALS9_CD45 GALECTIN 0.1003276 0.00
Microglia-like CD8_Tex LGALS9_CD45 GALECTIN 0.1000216 0.00
Microglia-like CD4_T LGALS9_CD45 GALECTIN 0.0945003 0.00
Microglia-like Other LGALS9_CD45 GALECTIN 0.0943134 0.02
Microglia-like CD8_Naive LGALS9_CD45 GALECTIN 0.0942887 0.00
Microglia-like Basophils SELPLG_SELL SELPLG 0.0931816 0.00
Microglia-like Pre-B LGALS9_IGHM GALECTIN 0.0926187 0.00
Microglia-like Microglia-like F11R_F11R JAM 0.0861215 0.00
Microglia-like Neutrophils SELPLG_SELL SELPLG 0.0845421 0.00
Microglia-like Plasma_B APP_CD74 APP 0.0839759 0.00
Microglia-like CD8_Tpex JAM1_ITGAL_ITGB2 JAM 0.0830251 0.00
mg_in %>%
  select(source, target, interaction_name, pathway_name, prob, pval) %>%
  head(30) %>%
  kable(caption = "Top 30 incoming to Microglia-like (CNS)")
Top 30 incoming to Microglia-like (CNS)
source target interaction_name pathway_name prob pval
Macrophages Microglia-like APOE_TREM2_TYROBP ApoE 0.2692462 0
CD8_Tpex Microglia-like CCL5_CCR5 CCL 0.2241862 0
CD8_Tex Microglia-like CCL5_CCR5 CCL 0.2092469 0
Monocytes Microglia-like APOE_TREM2_TYROBP ApoE 0.2058687 0
Stroma Microglia-like APP_TREM2_TYROBP APP 0.1883189 0
CD8_Teff Microglia-like CCL5_CCR5 CCL 0.1878446 0
B-ALL Microglia-like PPIA_BSG CypA 0.1545499 0
Stroma Microglia-like APOE_TREM2_TYROBP ApoE 0.1462329 0
Macrophages Microglia-like PPIA_BSG CypA 0.1324007 0
Neutrophils Microglia-like PPIA_BSG CypA 0.1320624 0
Basophils Microglia-like CSF1_CSF1R CSF 0.1298026 0
Vg6Vd4 Microglia-like PPIA_BSG CypA 0.1259764 0
Other_gd Microglia-like PPIA_BSG CypA 0.1246880 0
Other Microglia-like PPIA_BSG CypA 0.1245714 0
Microglia-like Microglia-like PROS1_MERTK PROS 0.1014361 0
CD8_Tpex Microglia-like THY1_ITGAM_ITGB2 THY1 0.0922240 0
DCs Microglia-like APP_TREM2_TYROBP APP 0.0904237 0
Pre-B Microglia-like APOE_TREM2_TYROBP ApoE 0.0897621 0
CD8_Tex Microglia-like THY1_ITGAM_ITGB2 THY1 0.0882101 0
Microglia-like Microglia-like F11R_F11R JAM 0.0861215 0
Vg4 Microglia-like THY1_ITGAM_ITGB2 THY1 0.0844080 0
CD8_Teff Microglia-like THY1_ITGAM_ITGB2 THY1 0.0839640 0
Vg6Vd4 Microglia-like THY1_ITGAM_ITGB2 THY1 0.0837339 0
B-ALL Microglia-like THY1_ITGAM_ITGB2 THY1 0.0799628 0
Neutrophils Microglia-like APP_TREM2_TYROBP APP 0.0795219 0
Basophils Microglia-like TGFB1_TGFBR1_TGFBR2 TGFb 0.0782119 0
Microglia-like Microglia-like APP_TREM2_TYROBP APP 0.0777990 0
Macrophages Microglia-like GAS6_MERTK GAS 0.0744734 0
Macrophages Microglia-like APP_TREM2_TYROBP APP 0.0720421 0
Other_gd Microglia-like THY1_ITGAM_ITGB2 THY1 0.0717990 0

Step 6 — Pathway Summary Tables

Step 6a — Top CNS Pathways

cns_net %>%
  group_by(pathway_name) %>%
  summarise(
    n_interactions = n(),
    total_prob = round(sum(prob), 4),
    mean_prob  = round(mean(prob), 4),
    top_sender = names(sort(table(source), decreasing = TRUE))[1],
    top_receiver = names(sort(table(target), decreasing = TRUE))[1],
    .groups = "drop"
  ) %>%
  arrange(desc(total_prob)) %>%
  head(40) %>%
  kable(caption = "Top 40 pathways by total probability — CNS")
Top 40 pathways by total probability — CNS
pathway_name n_interactions total_prob mean_prob top_sender top_receiver
MHC-I 1101 54.7625 0.0497 CD8_Tpex CD8_Tpex
CCL 299 10.5343 0.0352 Macrophages DCs
GALECTIN 389 9.9747 0.0256 B-ALL Monocytes
ADGRE 329 9.1344 0.0278 CD4_T Basophils
SELPLG 118 7.6787 0.0651 B-ALL Basophils
THY1 120 6.2746 0.0523 B-ALL Other
MIF 240 6.2476 0.0260 B-ALL Neutrophils
COLLAGEN 203 6.1436 0.0303 Stroma Basophils
APP 180 6.0920 0.0338 DCs DCs
CypA 26 4.3411 0.1670 B-ALL Stroma
MHC-II 114 3.3670 0.0295 DCs CD4_T
CD45 38 2.9572 0.0778 B-ALL Macrophages
ICAM 466 2.9208 0.0063 Vg4 Monocytes
MK 52 2.5696 0.0494 Stroma Neutrophils
FN1 64 2.4452 0.0382 Stroma Other
SIRP 80 2.3484 0.0294 Monocytes B-ALL
LCK 30 2.0591 0.0686 B-ALL CD8_Teff
CD52 54 1.8278 0.0338 Basophils DCs
PTN 32 1.7658 0.0552 Stroma Other
CD48 94 1.6484 0.0175 Basophils Monocytes
THBS 96 1.5101 0.0157 Stroma Macrophages
LAMININ 130 1.3777 0.0106 Stroma Basophils
ApoE 12 1.3314 0.1109 Basophils Macrophages
CLEC 150 1.2973 0.0086 DCs NKT-like
TGFb 157 1.1577 0.0074 Stroma Stroma
Prostaglandin 197 1.1056 0.0056 Stroma Basophils
CysLTs 136 1.0691 0.0079 B-ALL Basophils
CXCL 33 1.0153 0.0308 Stroma CD4_T
SEMA4 174 0.9624 0.0055 Basophils Microglia-like
JAM 36 0.8995 0.0250 Microglia-like Microglia-like
Cholesterol 150 0.8885 0.0059 B-ALL Vg4
LAIR1 49 0.8308 0.0170 Basophils DCs
PECAM1 24 0.7999 0.0333 Monocytes Monocytes
L1CAM 54 0.7674 0.0142 Basophils Basophils
IL16 54 0.7614 0.0141 B-ALL CD4_T
CEACAM 32 0.4999 0.0156 B-ALL B-ALL
PARs 40 0.4977 0.0124 B-ALL Vg6Vd4
VCAM 58 0.4566 0.0079 B-ALL Macrophages
PECAM2 60 0.4075 0.0068 B-ALL CD8_Teff
COMPLEMENT 52 0.3852 0.0074 B-ALL Basophils

Step 6b — Top BM Pathways

bm_net %>%
  group_by(pathway_name) %>%
  summarise(
    n_interactions = n(),
    total_prob = round(sum(prob), 4),
    mean_prob  = round(mean(prob), 4),
    top_sender = names(sort(table(source), decreasing = TRUE))[1],
    top_receiver = names(sort(table(target), decreasing = TRUE))[1],
    .groups = "drop"
  ) %>%
  arrange(desc(total_prob)) %>%
  head(40) %>%
  kable(caption = "Top 40 pathways by total probability — BM")
Top 40 pathways by total probability — BM
pathway_name n_interactions total_prob mean_prob top_sender top_receiver
MHC-I 1021 57.0599 0.0559 Progenitors CD8_Tpex
GALECTIN 352 10.8326 0.0308 B-ALL Monocytes
ADGRE 379 9.9951 0.0264 Basophils Basophils
SELPLG 214 9.5173 0.0445 CD4_T Progenitors
CCL 217 6.7551 0.0311 Macrophages DCs
MIF 180 4.8066 0.0267 B-ALL NKT-like
THY1 108 4.0276 0.0373 B-ALL Basophils
VCAM 99 3.9788 0.0402 B-ALL Macrophages
CD45 57 3.7311 0.0655 B-ALL DCs
APP 192 3.5154 0.0183 DCs DCs
MHC-II 148 3.3841 0.0229 DCs CD4_T
CLEC 261 3.2529 0.0125 DCs Other
SIRP 60 2.4253 0.0404 Monocytes B-ALL
LCK 30 2.4218 0.0807 B-ALL CD8_Naive
CD52 76 1.9594 0.0258 Basophils DCs
CD48 127 1.8828 0.0148 Basophils Monocytes
PECAM1 48 1.7549 0.0366 B-ALL B-ALL
CypA 13 1.7364 0.1336 B-ALL Neutrophils
ICAM 410 1.3320 0.0032 Neutrophils Monocytes
SEMA4 190 1.1271 0.0059 CD8_Tpex DCs
Cholesterol 136 1.0596 0.0078 B-ALL Vg4
COLLAGEN 140 0.9854 0.0070 Stroma Stroma
ApoE 12 0.8840 0.0737 Basophils Macrophages
Prostaglandin 171 0.8814 0.0052 Neutrophils Progenitors
TGFb 133 0.8072 0.0061 Basophils Basophils
IL16 72 0.7994 0.0111 B-ALL CD4_T
SPP1 102 0.7668 0.0075 Progenitors Stroma
L1CAM 60 0.7433 0.0124 Basophils Basophils
PECAM2 84 0.6239 0.0074 B-ALL CD8_Tex
SELL 40 0.6032 0.0151 B-ALL Basophils
CXCL 27 0.5641 0.0209 Macrophages NKT-like
LAMININ 116 0.4543 0.0039 Stroma Stroma
CysLTs 90 0.4479 0.0050 B-ALL Basophils
CEACAM 50 0.4472 0.0089 Monocytes Neutrophils
IGF 18 0.4385 0.0244 Macrophages Basophils
LAIR1 49 0.3338 0.0068 Basophils Basophils
CSF 10 0.3259 0.0326 Basophils DCs
CD6 32 0.2737 0.0086 CD4_T CD8_Teff
COMPLEMENT 66 0.2606 0.0039 Stroma Basophils
GRN 30 0.2399 0.0080 Basophils Monocytes

Step 6c — CNS-Enriched Pathways

cns_prob <- cns_net %>%
  group_by(pathway_name) %>%
  summarise(cns_prob = sum(prob), .groups = "drop")

bm_prob <- bm_net %>%
  group_by(pathway_name) %>%
  summarise(bm_prob = sum(prob), .groups = "drop")

pathway_compare <- full_join(cns_prob, bm_prob, by = "pathway_name") %>%
  mutate(
    cns_prob = replace(cns_prob, is.na(cns_prob), 0),
    bm_prob  = replace(bm_prob, is.na(bm_prob), 0),
    log2_fc  = log2((cns_prob + 0.001) / (bm_prob + 0.001)),
    location = case_when(
      cns_prob > 0 & bm_prob == 0 ~ "CNS-only",
      cns_prob == 0 & bm_prob > 0 ~ "BM-only",
      TRUE ~ "Both"
    )
  ) %>%
  arrange(desc(log2_fc))

cat("CNS-only pathways:\n")
## CNS-only pathways:
pathway_compare %>% filter(location == "CNS-only") %>%
  select(pathway_name, cns_prob) %>%
  mutate(cns_prob = round(cns_prob, 4)) %>%
  arrange(desc(cns_prob)) %>%
  kable()
pathway_name cns_prob
MK 2.5696
FN1 2.4452
PTN 1.7658
THBS 1.5101
JAM 0.8995
GAS 0.1618
CD86 0.1248
CX3C 0.0953
DHEAS 0.0900
TNF 0.0600
CD80 0.0572
BST2 0.0479
Glutamate 0.0398
CD200 0.0391
FLRT 0.0229
ncWNT 0.0191
CHEMERIN 0.0158
CLDN 0.0129
ADGRA 0.0104
EGF 0.0104
Histamine 0.0097
BMP 0.0093
SEMA3 0.0087
PLAU 0.0084
PTPRM 0.0070
CDH5 0.0069
LXA4 0.0067
PCDH 0.0061
CADM 0.0054
EPHA 0.0052
SLIT 0.0052
RANKL 0.0048
HSPG 0.0047
Netrin 0.0041
SerotoninDopamin 0.0036
TWEAK 0.0034
ANGPT 0.0029
EPHB 0.0020
PDGF 0.0018
CD137 0.0011
WNT 0.0011
cat("\n\nTop CNS-enriched pathways (present in both):\n")
## 
## 
## Top CNS-enriched pathways (present in both):
pathway_compare %>% filter(location == "Both") %>%
  select(pathway_name, cns_prob, bm_prob, log2_fc) %>%
  mutate(across(where(is.numeric), ~round(., 3))) %>%
  head(20) %>%
  kable()
pathway_name cns_prob bm_prob log2_fc
GAP 0.049 0.002 4.097
ADGRL 0.029 0.002 3.562
KLK 0.147 0.018 2.958
CD39 0.248 0.036 2.735
PROS 0.173 0.025 2.728
COLLAGEN 6.144 0.985 2.639
DHT 0.012 0.002 2.366
PARs 0.498 0.132 1.902
LAMININ 1.378 0.454 1.598
Testosterone 0.044 0.016 1.420
LIGHT 0.031 0.011 1.406
PTPR 0.028 0.010 1.394
CypA 4.341 1.736 1.321
LAIR1 0.831 0.334 1.313
IL4 0.069 0.028 1.271
CysLTs 1.069 0.448 1.253
ANGPTL 0.252 0.111 1.184
ICAM 2.921 1.332 1.132
APRIL 0.023 0.010 1.119
CDH 0.115 0.054 1.074
cat("\n\nTop BM-enriched pathways:\n")
## 
## 
## Top BM-enriched pathways:
pathway_compare %>% filter(location == "Both") %>%
  arrange(log2_fc) %>%
  select(pathway_name, cns_prob, bm_prob, log2_fc) %>%
  mutate(across(where(is.numeric), ~round(., 3))) %>%
  head(20) %>%
  kable()
pathway_name cns_prob bm_prob log2_fc
VCAM 0.457 3.979 -3.120
Desmosterol 0.004 0.023 -2.194
SELL 0.131 0.603 -2.191
CTSG 0.014 0.063 -2.055
SPP1 0.205 0.767 -1.899
NKG2D 0.011 0.040 -1.761
CLEC 1.297 3.253 -1.326
IL1 0.067 0.154 -1.192
IGF 0.195 0.438 -1.168
PECAM1 0.800 1.755 -1.133
DHEA 0.036 0.068 -0.914
IFN-II 0.102 0.186 -0.859
VISFATIN 0.014 0.025 -0.855
SN 0.068 0.115 -0.758
CD40 0.087 0.137 -0.660
CD6 0.174 0.274 -0.647
ADGRG 0.067 0.105 -0.639
PECAM2 0.408 0.624 -0.613
NRXN 0.005 0.009 -0.581
IL6 0.020 0.031 -0.574

Step 7 — Communication Patterns

Step 7a — Outgoing (CNS)

tryCatch(selectK(cellchat_cns, pattern = "outgoing"),
         error = function(e) cat("selectK failed:", e$message, "\n"))

n_out <- 4  # ADJUST based on selectK elbow plot

tryCatch({
  cellchat_cns <- identifyCommunicationPatterns(cellchat_cns,
                                                 pattern = "outgoing", k = n_out)
  if (requireNamespace("ggalluvial", quietly = TRUE)) {
    print(netAnalysis_river(cellchat_cns, pattern = "outgoing", font.size = 3))
  }
  print(netAnalysis_dot(cellchat_cns, pattern = "outgoing"))
}, error = function(e) cat("Outgoing patterns failed:", e$message, "\n"))

## Outgoing patterns failed: Can't find stat called "stratum".

Step 7b — Incoming (CNS)

tryCatch(selectK(cellchat_cns, pattern = "incoming"),
         error = function(e) cat("selectK failed:", e$message, "\n"))

n_in <- 4  # ADJUST based on selectK elbow plot

tryCatch({
  cellchat_cns <- identifyCommunicationPatterns(cellchat_cns,
                                                 pattern = "incoming", k = n_in)
  if (requireNamespace("ggalluvial", quietly = TRUE)) {
    print(netAnalysis_river(cellchat_cns, pattern = "incoming", font.size = 3))
  }
  print(netAnalysis_dot(cellchat_cns, pattern = "incoming"))
}, error = function(e) cat("Incoming patterns failed:", e$message, "\n"))

## Incoming patterns failed: Can't find stat called "stratum".

Step 8 — Immunosuppressive Summary

A consolidated view of all immunosuppressive interactions in the CNS.

Step 8a — Immunosuppressive Interaction Inventory

# Define immunosuppressive pathways/interactions
immunosup_pathways <- c("GALECTIN", "TGFb", "IL10", "ApoE", "APP", "Prostaglandin")

# Also capture specific checkpoint-like interactions
immunosup_lr <- c("LGALS9", "HAVCR2", "TGFB1", "IL10", "PDCD1", "CD274",
                   "CTLA4", "TIGIT", "LAG3")

immunosup_int <- cns_net %>%
  filter(
    pathway_name %in% immunosup_pathways |
    grepl(paste(immunosup_lr, collapse = "|"), interaction_name, ignore.case = TRUE)
  ) %>%
  arrange(desc(prob))

cat("Total immunosuppressive interactions in CNS:", nrow(immunosup_int), "\n\n")
## Total immunosuppressive interactions in CNS: 993
# Summarise by sender
immunosup_int %>%
  group_by(source) %>%
  summarise(
    n_targets = n_distinct(target),
    n_interactions = n(),
    total_prob = round(sum(prob), 3),
    key_pathways = paste(unique(pathway_name), collapse = ", "),
    .groups = "drop"
  ) %>%
  arrange(desc(total_prob)) %>%
  kable(caption = "Immunosuppressive signal senders — CNS")
Immunosuppressive signal senders — CNS
source n_targets n_interactions total_prob key_pathways
B-ALL 19 63 3.225 GALECTIN, Prostaglandin, TGFb
Stroma 20 106 2.655 APP, ApoE, GALECTIN, Prostaglandin, TGFb, CD80
Microglia-like 20 96 2.625 APP, GALECTIN, TGFb, ApoE, CD86, Prostaglandin, ICOS
Macrophages 20 76 2.015 ApoE, APP, GALECTIN, TGFb, Prostaglandin
Neutrophils 20 73 1.529 APP, GALECTIN, TGFb, Prostaglandin
DCs 20 73 1.393 APP, TGFb, GALECTIN, Prostaglandin, ICOS
Monocytes 19 60 1.311 ApoE, APP, TGFb, Prostaglandin, PD-L1
Basophils 20 68 1.197 GALECTIN, TGFb, ApoE, Prostaglandin, PDL2, PD-L1
CD8_Teff 18 39 0.718 GALECTIN, Prostaglandin, TGFb
CD8_Tpex 18 46 0.683 GALECTIN, Prostaglandin, TGFb, CD80
Other_gd 18 39 0.672 GALECTIN, Prostaglandin, TGFb
Pre-B 15 31 0.331 ApoE, GALECTIN, TGFb, Prostaglandin
Other 16 34 0.248 TGFb, GALECTIN, Prostaglandin
CD8_Tex 14 29 0.228 GALECTIN, Prostaglandin, TGFb
NKT-like 14 29 0.225 GALECTIN, Prostaglandin, TGFb
CD4_T 14 29 0.222 GALECTIN, Prostaglandin, TGFb
Vg4 14 29 0.200 GALECTIN, Prostaglandin, TGFb
Vg6Vd4 14 28 0.182 Prostaglandin, GALECTIN, TGFb
CD8_Naive 14 24 0.140 GALECTIN, Prostaglandin
Plasma_B 15 21 0.072 Prostaglandin, PD-L1, TGFb

Step 8b — Immunosuppressive Receivers

immunosup_int %>%
  group_by(target) %>%
  summarise(
    n_senders = n_distinct(source),
    n_interactions = n(),
    total_prob = round(sum(prob), 3),
    key_pathways = paste(unique(pathway_name), collapse = ", "),
    .groups = "drop"
  ) %>%
  arrange(desc(total_prob)) %>%
  kable(caption = "Immunosuppressive signal receivers — CNS")
Immunosuppressive signal receivers — CNS
target n_senders n_interactions total_prob key_pathways
Microglia-like 20 76 2.575 ApoE, APP, TGFb, GALECTIN
Pre-B 19 32 2.207 APP, GALECTIN
Monocytes 20 93 1.872 GALECTIN, APP, TGFb, Prostaglandin, CD80
DCs 20 65 1.855 APP, GALECTIN, Prostaglandin
Other 20 76 1.611 APP, GALECTIN, TGFb, Prostaglandin
Macrophages 8 18 0.971 ApoE, APP
CD8_Tpex 20 59 0.967 GALECTIN, APP, PD-L1, Prostaglandin, PDL2
Basophils 20 96 0.941 GALECTIN, Prostaglandin, APP, TGFb, CD80
Neutrophils 20 76 0.906 GALECTIN, APP, TGFb, Prostaglandin
CD8_Teff 20 64 0.786 GALECTIN, APP, PD-L1, Prostaglandin, PDL2, CD86, CD80, ICOS
Plasma_B 11 23 0.764 APP, GALECTIN, CD86, CD80, ICOS, TGFb
NKT-like 20 45 0.701 GALECTIN, APP, PD-L1, PDL2
CD8_Naive 18 28 0.641 GALECTIN, Prostaglandin, CD86, CD80, ICOS
Stroma 20 88 0.641 GALECTIN, APP, TGFb, Prostaglandin
CD8_Tex 20 30 0.490 GALECTIN, APP, PD-L1, PDL2
Vg6Vd4 12 21 0.465 GALECTIN, APP, PD-L1, PDL2
CD4_T 20 38 0.464 GALECTIN, APP, CD86, PD-L1, CD80, ICOS, PDL2
Vg4 12 19 0.427 GALECTIN, APP, PD-L1, PDL2
Other_gd 13 29 0.382 GALECTIN, APP, TGFb, PD-L1, PDL2
B-ALL 9 17 0.205 GALECTIN, APP, TGFb

Step 8c — Top Immunosuppressive Interactions

immunosup_int %>%
  select(source, target, interaction_name, pathway_name, prob, pval) %>%
  head(40) %>%
  kable(caption = "Top 40 immunosuppressive interactions (CNS)")
Top 40 immunosuppressive interactions (CNS)
source target interaction_name pathway_name prob pval
Stroma DCs APP_CD74 APP 0.2961797 0.00
Stroma Pre-B APP_CD74 APP 0.2893632 0.00
Macrophages Microglia-like APOE_TREM2_TYROBP ApoE 0.2692462 0.00
Monocytes Microglia-like APOE_TREM2_TYROBP ApoE 0.2058687 0.00
Stroma Plasma_B APP_CD74 APP 0.2013547 0.00
Macrophages Macrophages APOE_TREM2_TYROBP ApoE 0.1917321 0.00
Stroma Microglia-like APP_TREM2_TYROBP APP 0.1883189 0.00
DCs DCs APP_CD74 APP 0.1527674 0.00
Stroma Other APP_CD74 APP 0.1497289 0.00
DCs Pre-B APP_CD74 APP 0.1485548 0.00
Stroma Microglia-like APOE_TREM2_TYROBP ApoE 0.1462329 0.00
Monocytes Macrophages APOE_TREM2_TYROBP ApoE 0.1430293 0.00
B-ALL Monocytes LGALS9_CD45 GALECTIN 0.1424436 0.00
B-ALL CD8_Tpex LGALS9_CD45 GALECTIN 0.1370330 0.00
B-ALL CD8_Teff LGALS9_CD45 GALECTIN 0.1357315 0.00
Neutrophils DCs APP_CD74 APP 0.1354687 0.00
B-ALL CD8_Tex LGALS9_CD45 GALECTIN 0.1353338 0.00
Microglia-like DCs APP_CD74 APP 0.1327085 0.00
Neutrophils Pre-B APP_CD74 APP 0.1316590 0.00
Stroma Macrophages APP_TREM2_TYROBP APP 0.1299598 0.00
Microglia-like Pre-B APP_CD74 APP 0.1289648 0.00
B-ALL CD4_T LGALS9_CD45 GALECTIN 0.1281408 0.00
B-ALL Other LGALS9_CD45 GALECTIN 0.1278967 0.00
B-ALL CD8_Naive LGALS9_CD45 GALECTIN 0.1278645 0.00
B-ALL Pre-B LGALS9_IGHM GALECTIN 0.1256823 0.00
Macrophages DCs APP_CD74 APP 0.1234323 0.00
Monocytes DCs APP_CD74 APP 0.1200592 0.00
Macrophages Pre-B APP_CD74 APP 0.1199142 0.00
B-ALL NKT-like LGALS9_CD45 GALECTIN 0.1192309 0.00
Monocytes Pre-B APP_CD74 APP 0.1166244 0.00
B-ALL DCs LGALS9_CD45 GALECTIN 0.1158341 0.00
Microglia-like Monocytes LGALS9_CD45 GALECTIN 0.1055026 0.00
B-ALL Vg4 LGALS9_CD45 GALECTIN 0.1048894 0.00
B-ALL Other_gd LGALS9_CD45 GALECTIN 0.1021184 0.00
B-ALL Pre-B LGALS9_CD45 GALECTIN 0.1016737 0.00
Microglia-like CD8_Tpex LGALS9_CD45 GALECTIN 0.1013294 0.01
B-ALL Vg6Vd4 LGALS9_CD45 GALECTIN 0.1004244 0.00
Microglia-like CD8_Teff LGALS9_CD45 GALECTIN 0.1003276 0.00
Microglia-like CD8_Tex LGALS9_CD45 GALECTIN 0.1000216 0.00
Basophils Monocytes LGALS9_CD45 GALECTIN 0.0996365 0.01

Session Information

sessionInfo()
## R version 4.4.1 (2024-06-14)
## Platform: x86_64-pc-linux-gnu
## Running under: Rocky Linux 9.5 (Blue Onyx)
## 
## Matrix products: default
## BLAS/LAPACK: /opt/intel/oneapi/mkl/2024.0/lib/libmkl_gf_lp64.so.2;  LAPACK version 3.10.1
## 
## locale:
##  [1] LC_CTYPE=en_GB.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=en_GB.UTF-8        LC_COLLATE=en_GB.UTF-8    
##  [5] LC_MONETARY=en_GB.UTF-8    LC_MESSAGES=en_GB.UTF-8   
##  [7] LC_PAPER=en_GB.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=en_GB.UTF-8 LC_IDENTIFICATION=C       
## 
## time zone: Europe/London
## tzcode source: system (glibc)
## 
## attached base packages:
## [1] parallel  grid      stats     graphics  grDevices utils     datasets 
## [8] methods   base     
## 
## other attached packages:
##  [1] doParallel_1.0.17     iterators_1.0.14      foreach_1.5.2        
##  [4] NMF_0.28              cluster_2.1.6         rngtools_1.5.2       
##  [7] registry_0.5-1        knitr_1.51            ComplexHeatmap_2.22.0
## [10] patchwork_1.3.2       tidyr_1.3.1           qs2_0.1.7            
## [13] Seurat_5.4.0          SeuratObject_5.3.0    sp_2.1-4             
## [16] CellChat_2.2.0.9001   Biobase_2.66.0        BiocGenerics_0.52.0  
## [19] ggplot2_4.0.2         igraph_2.2.2          dplyr_1.1.4          
## 
## loaded via a namespace (and not attached):
##   [1] RcppAnnoy_0.0.23       splines_4.4.1          later_1.4.6           
##   [4] tibble_3.3.1           polyclip_1.10-7        ggnetwork_0.5.14      
##   [7] fastDummies_1.7.5      lifecycle_1.0.5        rstatix_0.7.3         
##  [10] globals_0.16.3         lattice_0.22-6         MASS_7.3-60.2         
##  [13] backports_1.4.1        magrittr_2.0.3         plotly_4.12.0         
##  [16] sass_0.4.9             rmarkdown_2.30         jquerylib_0.1.4       
##  [19] yaml_2.3.12            httpuv_1.6.16          otel_0.2.0            
##  [22] collapse_2.1.6         sctransform_0.4.3      spam_2.11-3           
##  [25] spatstat.sparse_3.1-0  reticulate_1.45.0      cowplot_1.2.0         
##  [28] pbapply_1.7-4          RColorBrewer_1.1-3     abind_1.4-5           
##  [31] Rtsne_0.17             purrr_1.0.2            circlize_0.4.17       
##  [34] IRanges_2.40.1         S4Vectors_0.44.0       ggrepel_0.9.6         
##  [37] irlba_2.3.7            listenv_0.9.1          spatstat.utils_3.2-1  
##  [40] goftest_1.2-3          RSpectra_0.16-2        spatstat.random_3.4-4 
##  [43] fitdistrplus_1.2-6     parallelly_1.37.1      svglite_2.2.2         
##  [46] codetools_0.2-20       tidyselect_1.2.1       shape_1.4.6.1         
##  [49] farver_2.1.2           matrixStats_1.5.0      stats4_4.4.1          
##  [52] spatstat.explore_3.7-0 jsonlite_2.0.0         GetoptLong_1.1.0      
##  [55] BiocNeighbors_2.0.1    progressr_0.18.0       Formula_1.2-5         
##  [58] ggridges_0.5.6         ggalluvial_0.12.6      survival_3.6-4        
##  [61] systemfonts_1.3.1      tools_4.4.1            sna_2.8               
##  [64] ica_1.0-3              Rcpp_1.0.12            glue_1.8.0            
##  [67] gridExtra_2.3          xfun_0.56              withr_3.0.2           
##  [70] BiocManager_1.30.27    fastmap_1.2.0          fansi_1.0.6           
##  [73] digest_0.6.35          R6_2.6.1               mime_0.12             
##  [76] textshaping_0.3.7      colorspace_2.1-0       Cairo_1.7-0           
##  [79] scattermore_1.2        tensor_1.5.1           dichromat_2.0-0.1     
##  [82] spatstat.data_3.1-9    utf8_1.2.4             generics_0.1.3        
##  [85] data.table_1.15.4      FNN_1.1.4.1            httr_1.4.7            
##  [88] htmlwidgets_1.6.4      uwot_0.2.4             pkgconfig_2.0.3       
##  [91] gtable_0.3.6           lmtest_0.9-40          S7_0.2.1              
##  [94] htmltools_0.5.8.1      carData_3.0-6          dotCall64_1.2         
##  [97] clue_0.3-67            scales_1.4.0           png_0.1-8             
## [100] spatstat.univar_3.1-6  rstudioapi_0.16.0      reshape2_1.4.4        
## [103] rjson_0.2.23           nlme_3.1-164           coda_0.19-4.1         
## [106] statnet.common_4.13.0  cachem_1.1.0           zoo_1.8-15            
## [109] GlobalOptions_0.1.3    stringr_1.5.1          KernSmooth_2.23-24    
## [112] miniUI_0.1.2           pillar_1.9.0           vctrs_0.6.5           
## [115] RANN_2.6.2             promises_1.5.0         ggpubr_0.6.2          
## [118] stringfish_0.18.0      car_3.1-5              xtable_1.8-4          
## [121] evaluate_1.0.5         cli_3.6.5              compiler_4.4.1        
## [124] rlang_1.1.7            crayon_1.5.2           future.apply_1.11.2   
## [127] ggsignif_0.6.4         labeling_0.4.3         plyr_1.8.9            
## [130] stringi_1.8.4          deldir_2.0-4           viridisLite_0.4.2     
## [133] network_1.20.0         gridBase_0.4-7         lazyeval_0.2.2        
## [136] spatstat.geom_3.7-0    Matrix_1.7-0           RcppHNSW_0.6.0        
## [139] future_1.33.2          shiny_1.12.1           ROCR_1.0-12           
## [142] broom_1.0.5            RcppParallel_5.1.8     bslib_0.7.0