18.2 Lymphoid Trajectory - B Cell Differentiation

As a second example of a trajectory, we will create a B cell trajectory from progenitor cells, through the common lymphoid progenitor and pre-B cell all the way to fully differentiated B cells. Because this analysis is essentially repeated from the monocyte trajectory in the previous section, we do not provide explanations for the code snippets. If you are trying to learn how to perform trajectory analysis, check out the monocyte trajectory section in this chapter instead.

For reference, this is what our clusters look like:

p1 <- plotEmbedding(ArchRProj = projHeme5, colorBy = "cellColData", name = "Clusters", embedding = "UMAP")
## ArchR logging to : ArchRLogs/ArchR-plotEmbedding-978fecc87-Date-2025-02-06_Time-02-58-34.36984.log
## If there is an issue, please report to github with logFile!
## Getting UMAP Embedding
## ColorBy = cellColData
## Plotting Embedding
## 1 
## ArchR logging successful to : ArchRLogs/ArchR-plotEmbedding-978fecc87-Date-2025-02-06_Time-02-58-34.36984.log
p2 <- plotEmbedding(ArchRProj = projHeme5, colorBy = "cellColData", name = "Clusters2", embedding = "UMAP")
## ArchR logging to : ArchRLogs/ArchR-plotEmbedding-9641552fc-Date-2025-02-06_Time-02-58-36.26264.log
## If there is an issue, please report to github with logFile!
## Getting UMAP Embedding
## ColorBy = cellColData
## Plotting Embedding
## 1 
## ArchR logging successful to : ArchRLogs/ArchR-plotEmbedding-9641552fc-Date-2025-02-06_Time-02-58-36.26264.log
ggAlignPlots(p1, p2, type = "h")

18.2.1 Pseudo-time UMAPs and individual feature plots

The trajectory we will use will span from “Progenitor” to a lymphoid progenitor cell (“CLP”) to a “PreB” cell, and finally to a mature “B” cell.

trajectory <- c("Progenitor", "CLP", "PreB", "B")
trajectory
## [1] "Progenitor" "CLP"        "PreB"       "B"
projHeme5 <- addTrajectory(
    ArchRProj = projHeme5, 
    name = "LymphoidU", 
    groupBy = "Clusters2",
    trajectory = trajectory, 
    embedding = "UMAP", 
    force = TRUE
)
## ArchR logging to : ArchRLogs/ArchR-addTrajectory-931ced161-Date-2025-02-06_Time-02-58-39.602988.log
## If there is an issue, please report to github with logFile!
## Filtering outliers
## Initial Alignment Before Spline Fit
## Spline Fit
## KNN to Spline
## ArchR logging successful to : ArchRLogs/ArchR-addTrajectory-931ced161-Date-2025-02-06_Time-02-58-39.602988.log
head(projHeme5$LymphoidU[!is.na(projHeme5$LymphoidU)])
## [1] 79.175800 80.227970 78.956598 80.622534  1.227532 83.954406
p <- plotTrajectory(projHeme5, trajectory = "LymphoidU", colorBy = "cellColData", name = "LymphoidU")
## ArchR logging to : ArchRLogs/ArchR-plotTrajectory-91a0aae5e-Date-2025-02-06_Time-02-58-40.137215.log
## If there is an issue, please report to github with logFile!
## Plotting
## Plotting Trajectory
## Adding Inferred Arrow Trajectory to Plot
## ArchR logging successful to : ArchRLogs/ArchR-plotTrajectory-91a0aae5e-Date-2025-02-06_Time-02-58-40.137215.log
p[[1]]
## Warning: Removed 7969 rows containing non-finite outside the scale range
## (`stat_summary_hex()`).

p1 <- plotTrajectory(projHeme5, trajectory = "LymphoidU", colorBy = "GeneScoreMatrix", name = "PAX5", continuousSet = "horizonExtra")
## Getting ImputeWeights
## ArchR logging to : ArchRLogs/ArchR-plotTrajectory-93ab771fe-Date-2025-02-06_Time-02-58-47.324669.log
## If there is an issue, please report to github with logFile!
## Getting Matrix Values...
## 2025-02-06 02:58:49.01757 :
## 
## Imputing Matrix
## Using weights on disk
## Using weights on disk
## Plotting
## Plotting Trajectory
## Adding Inferred Arrow Trajectory to Plot
## ArchR logging successful to : ArchRLogs/ArchR-plotTrajectory-93ab771fe-Date-2025-02-06_Time-02-58-47.324669.log
p2 <- plotTrajectory(projHeme5, trajectory = "LymphoidU", colorBy = "GeneIntegrationMatrix", name = "PAX5", continuousSet = "blueYellow")
## Getting ImputeWeights
## ArchR logging to : ArchRLogs/ArchR-plotTrajectory-9578dfcfd-Date-2025-02-06_Time-02-58-55.549999.log
## If there is an issue, please report to github with logFile!
## Getting Matrix Values...
## 2025-02-06 02:58:57.241542 :
## 
## Imputing Matrix
## Using weights on disk
## Using weights on disk
## Plotting
## Plotting Trajectory
## Adding Inferred Arrow Trajectory to Plot
## ArchR logging successful to : ArchRLogs/ArchR-plotTrajectory-9578dfcfd-Date-2025-02-06_Time-02-58-55.549999.log
ggAlignPlots(p1[[1]], p2[[1]], type = "h")
## Warning: Removed 7969 rows containing non-finite outside the scale range (`stat_summary_hex()`).
## Removed 7969 rows containing non-finite outside the scale range (`stat_summary_hex()`).

ggAlignPlots(p1[[2]], p2[[2]], type = "h")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'

18.2.2 Pseudo-time heatmaps

trajMM  <- getTrajectory(ArchRProj = projHeme5, name = "LymphoidU", useMatrix = "MotifMatrix", log2Norm = FALSE)
## Creating Trajectory Group Matrix..
## Some values are below 0, this could be a DeviationsMatrix in which scaleTo should be set = NULL.
## Continuing without depth normalization!
## Smoothing...
p1 <- plotTrajectoryHeatmap(trajMM, pal = paletteContinuous(set = "solarExtra"))
## ArchR logging to : ArchRLogs/ArchR-plotTrajectoryHeatmap-932c015a4-Date-2025-02-06_Time-02-59-22.194025.log
## If there is an issue, please report to github with logFile!
## useSeqnames is NULL or greater than 1 with a Sparse.Assays.Matrix trajectory input.
## 2025-02-06 02:59:22.610019 :
## force=FALSE thus continuing with subsetting useSeqnames = z
## 2025-02-06 02:59:22.616315 :
## Preparing Main Heatmap..
## 'magick' package is suggested to install to give better rasterization.
## 
## Set `ht_opt$message = FALSE` to turn off this message.
## ArchR logging successful to : ArchRLogs/ArchR-plotTrajectoryHeatmap-932c015a4-Date-2025-02-06_Time-02-59-22.194025.log
p1

trajGSM <- getTrajectory(ArchRProj = projHeme5, name = "LymphoidU", useMatrix = "GeneScoreMatrix", log2Norm = TRUE)
## Creating Trajectory Group Matrix..
## Smoothing...
p2 <- plotTrajectoryHeatmap(trajGSM,  pal = paletteContinuous(set = "horizonExtra"))
## ArchR logging to : ArchRLogs/ArchR-plotTrajectoryHeatmap-98142466-Date-2025-02-06_Time-02-59-48.722015.log
## If there is an issue, please report to github with logFile!
## Preparing Main Heatmap..
## 'magick' package is suggested to install to give better rasterization.
## 
## Set `ht_opt$message = FALSE` to turn off this message.
## ArchR logging successful to : ArchRLogs/ArchR-plotTrajectoryHeatmap-98142466-Date-2025-02-06_Time-02-59-48.722015.log
p2

trajGIM <- getTrajectory(ArchRProj = projHeme5, name = "LymphoidU", useMatrix = "GeneIntegrationMatrix", log2Norm = FALSE)
## Creating Trajectory Group Matrix..
## Smoothing...
p3 <- plotTrajectoryHeatmap(trajGIM,  pal = paletteContinuous(set = "blueYellow"))
## ArchR logging to : ArchRLogs/ArchR-plotTrajectoryHeatmap-954fc94ba-Date-2025-02-06_Time-03-00-17.387233.log
## If there is an issue, please report to github with logFile!
## Preparing Main Heatmap..
## 'magick' package is suggested to install to give better rasterization.
## 
## Set `ht_opt$message = FALSE` to turn off this message.
## ArchR logging successful to : ArchRLogs/ArchR-plotTrajectoryHeatmap-954fc94ba-Date-2025-02-06_Time-03-00-17.387233.log
p3

trajPM  <- getTrajectory(ArchRProj = projHeme5, name = "LymphoidU", useMatrix = "PeakMatrix", log2Norm = TRUE)
## Creating Trajectory Group Matrix..
## Smoothing...
p4 <- plotTrajectoryHeatmap(trajPM, pal = paletteContinuous(set = "solarExtra"))
## ArchR logging to : ArchRLogs/ArchR-plotTrajectoryHeatmap-94e13eef9-Date-2025-02-06_Time-03-00-50.321903.log
## If there is an issue, please report to github with logFile!
## Preparing Main Heatmap..
## 'magick' package is suggested to install to give better rasterization.
## 
## Set `ht_opt$message = FALSE` to turn off this message.
## ArchR logging successful to : ArchRLogs/ArchR-plotTrajectoryHeatmap-94e13eef9-Date-2025-02-06_Time-03-00-50.321903.log
p4

To save editable vectorized versions of these plots, we use plotPDF().

plotPDF(p1, p2, p3, p4, name = "Plot-LymphoidU-Traj-Heatmaps.pdf", ArchRProj = projHeme5, addDOC = FALSE, width = 6, height = 8)
## Plotting ComplexHeatmap!
## Plotting ComplexHeatmap!
## Plotting ComplexHeatmap!
## Plotting ComplexHeatmap!

18.2.3 Integrative pseudo-time analyses

corGSM_MM <- correlateTrajectories(trajGSM, trajMM)
## ArchR logging to : ArchRLogs/ArchR-correlateTrajectories-9401110d6-Date-2025-02-06_Time-03-01-04.39258.log
## If there is an issue, please report to github with logFile!
## Found 14 Correlated Pairings!
## 2025-02-06 03:01:29.126472 :
corGSM_MM[[1]]$matchname1
##  [1] "PRDM16" "CREM"   "NFE2"   "MAFG"   "RFX2"   "CEBPA"  "SPIB"   "FOSL2" 
##  [9] "BCL11A" "FOXP1"  "GATA2"  "LEF1"   "IRF2"   "PAX5"
corGSM_MM[[1]]
## DataFrame with 14 rows and 12 columns
##          idx1      idx2  matchname1  matchname2         name1        name2
##     <integer> <integer> <character> <character>   <character>  <character>
## 1          82      1081      PRDM16      PRDM16   chr1:PRDM16 z:PRDM16_211
## 2        2503       978        CREM        CREM    chr10:CREM   z:CREM_108
## 3        5181       989        NFE2        NFE2    chr12:NFE2   z:NFE2_119
## 4       10078      1018        MAFG        MAFG chr17:MAFG-DT   z:MAFG_148
## 5       10649      1594        RFX2        RFX2    chr19:RFX2   z:RFX2_724
## ...       ...       ...         ...         ...           ...          ...
## 10      15543      1223       FOXP1       FOXP1    chr3:FOXP1  z:FOXP1_353
## 11      15802      1258       GATA2       GATA2    chr3:GATA2  z:GATA2_388
## 12      16831      1630        LEF1        LEF1     chr4:LEF1   z:LEF1_760
## 13      17102      1504        IRF2        IRF2     chr4:IRF2   z:IRF2_634
## 14      21499      1579        PAX5        PAX5     chr9:PAX5   z:PAX5_709
##     Correlation VarAssay1 VarAssay2     TStat        Pval         FDR
##       <numeric> <numeric> <numeric> <numeric>   <numeric>   <numeric>
## 1      0.522796  0.999438  0.837356   6.07117 2.40966e-08 9.84345e-07
## 2      0.504021  0.832404  0.840230   5.77700 8.99457e-08 2.75332e-06
## 3      0.725487  0.982445  0.993103  10.43532 1.37720e-17 3.21477e-15
## 4      0.561670  0.984477  0.944253   6.72047 1.20473e-09 5.81794e-08
## 5      0.778142  0.972932  0.958046  12.26455 1.64963e-21 5.39100e-19
## ...         ...       ...       ...       ...         ...         ...
## 10     0.564325  0.940589  0.909770   6.76701 9.67927e-10 4.94248e-08
## 11     0.544193  0.916721  0.994828   6.42132 4.85671e-09 2.14483e-07
## 12     0.505344  0.889134  0.866667   5.79736 8.21851e-08 2.68222e-06
## 13     0.590905  0.847235  0.979885   7.25098 9.68055e-11 6.87740e-09
## 14     0.783126  0.968003  0.963793  12.46664 6.17743e-22 2.52348e-19
trajGSM2 <- trajGSM[corGSM_MM[[1]]$name1, ]
trajMM2 <- trajMM[corGSM_MM[[1]]$name2, ]

trajCombined <- trajGSM2
assay(trajCombined, withDimnames=FALSE) <- t(apply(assay(trajGSM2), 1, scale)) + t(apply(assay(trajMM2), 1, scale))

combinedMat <- plotTrajectoryHeatmap(trajCombined, returnMat = TRUE, varCutOff = 0)
## ArchR logging to : ArchRLogs/ArchR-plotTrajectoryHeatmap-968ebab31-Date-2025-02-06_Time-03-01-29.216983.log
## If there is an issue, please report to github with logFile!
## Preparing Main Heatmap..
## 'magick' package is suggested to install to give better rasterization.
## 
## Set `ht_opt$message = FALSE` to turn off this message.
## ArchR logging successful to : ArchRLogs/ArchR-plotTrajectoryHeatmap-968ebab31-Date-2025-02-06_Time-03-01-29.216983.log
rowOrder <- match(rownames(combinedMat), rownames(trajGSM2))

ht1 <- plotTrajectoryHeatmap(trajGSM2,  pal = paletteContinuous(set = "horizonExtra"),  varCutOff = 0, rowOrder = rowOrder)
## ArchR logging to : ArchRLogs/ArchR-plotTrajectoryHeatmap-95c360a13-Date-2025-02-06_Time-03-01-29.912661.log
## If there is an issue, please report to github with logFile!
## Preparing Main Heatmap..
## 'magick' package is suggested to install to give better rasterization.
## 
## Set `ht_opt$message = FALSE` to turn off this message.
## ArchR logging successful to : ArchRLogs/ArchR-plotTrajectoryHeatmap-95c360a13-Date-2025-02-06_Time-03-01-29.912661.log
ht2 <- plotTrajectoryHeatmap(trajMM2,  pal = paletteContinuous(set = "solarExtra"), varCutOff = 0, rowOrder = rowOrder)
## ArchR logging to : ArchRLogs/ArchR-plotTrajectoryHeatmap-9271e68b0-Date-2025-02-06_Time-03-01-30.671831.log
## If there is an issue, please report to github with logFile!
## useSeqnames is NULL or greater than 1 with a Sparse.Assays.Matrix trajectory input.
## 2025-02-06 03:01:31.072151 :
## force=FALSE thus continuing with subsetting useSeqnames = z
## 2025-02-06 03:01:31.077903 :
## Preparing Main Heatmap..
## 'magick' package is suggested to install to give better rasterization.
## 
## Set `ht_opt$message = FALSE` to turn off this message.
## ArchR logging successful to : ArchRLogs/ArchR-plotTrajectoryHeatmap-9271e68b0-Date-2025-02-06_Time-03-01-30.671831.log

ComplexHeatmap::draw(ht1 + ht2)

corGIM_MM <- correlateTrajectories(trajGIM, trajMM)
## ArchR logging to : ArchRLogs/ArchR-correlateTrajectories-9ebe0432-Date-2025-02-06_Time-03-01-32.260076.log
## If there is an issue, please report to github with logFile!
## Found 40 Correlated Pairings!
## 2025-02-06 03:01:51.810945 :
corGIM_MM[[1]]$matchname1
##  [1] "ID3"     "NFIA"    "NFKB2"   "IRF7"    "ETS1"    "NFE2"    "FOXO1"  
##  [8] "IRF9"    "FOS"     "MEF2A"   "IRF8"    "MAFG"    "FOXK2"   "MBD2"   
## [15] "TCF4"    "TCF3"    "NFIC"    "KLF2"    "CEBPA"   "POU2F2"  "RELB"   
## [22] "FOSB"    "SPIB"    "FOSL2"   "REL"     "NFE2L2"  "RUNX1"   "ETS2"   
## [29] "SMARCC1" "FOXP1"   "GATA2"   "HLTF"    "RBPJ"    "LEF1"    "IRF2"   
## [36] "MEF2C"   "IRF1"    "EBF1"    "HOXA9"   "PAX5"
corGIM_MM[[1]]
## DataFrame with 40 rows and 12 columns
##          idx1      idx2  matchname1  matchname2       name1       name2
##     <integer> <integer> <character> <character> <character> <character>
## 1         275       908         ID3         ID3    chr1:ID3    z:ID3_38
## 2         680      1612        NFIA        NFIA   chr1:NFIA  z:NFIA_742
## 3        2428      1584       NFKB2       NFKB2 chr10:NFKB2 z:NFKB2_714
## 4        2625      1505        IRF7        IRF7  chr11:IRF7  z:IRF7_635
## 5        3790      1202        ETS1        ETS1  chr11:ETS1  z:ETS1_332
## ...       ...       ...         ...         ...         ...         ...
## 36      14165      1510       MEF2C       MEF2C  chr5:MEF2C z:MEF2C_640
## 37      14287      1499        IRF1        IRF1   chr5:IRF1  z:IRF1_629
## 38      14558       937        EBF1        EBF1   chr5:EBF1   z:EBF1_67
## 39      15847      1275       HOXA9       HOXA9  chr7:HOXA9 z:HOXA9_405
## 40      17354      1579        PAX5        PAX5   chr9:PAX5  z:PAX5_709
##     Correlation VarAssay1 VarAssay2     TStat        Pval         FDR
##       <numeric> <numeric> <numeric> <numeric>   <numeric>   <numeric>
## 1      0.793690  0.889898  0.990230  12.91604 7.05035e-23 2.23849e-21
## 2      0.788673  0.874254  0.963218  12.69895 2.00673e-22 5.99657e-21
## 3      0.884879  0.945863  0.941954  18.80524 2.77031e-34 1.56368e-32
## 4      0.724828  0.835762  0.940805  10.41534 1.52151e-17 2.37823e-16
## 5      0.534531  0.937692  0.801149   6.26113 1.01495e-08 6.06584e-08
## ...         ...       ...       ...       ...         ...         ...
## 36     0.673779  0.993065  0.935057   9.02664 1.56638e-14 1.72983e-13
## 37     0.685853  0.967421  0.987356   9.32969 3.45083e-15 4.17386e-14
## 38     0.919121  0.979463  0.991954  23.09489 1.98188e-41 2.68187e-39
## 39     0.744585  0.914413  0.805747  11.04227 6.72741e-19 1.22054e-17
## 40     0.805725  0.966561  0.963793  13.46683 5.07101e-24 1.77660e-22
trajGIM2 <- trajGIM[corGIM_MM[[1]]$name1, ]
trajMM2 <- trajMM[corGIM_MM[[1]]$name2, ]

trajCombined <- trajGIM2
assay(trajCombined, withDimnames=FALSE) <- t(apply(assay(trajGIM2), 1, scale)) + t(apply(assay(trajMM2), 1, scale))

combinedMat <- plotTrajectoryHeatmap(trajCombined, returnMat = TRUE, varCutOff = 0)
## ArchR logging to : ArchRLogs/ArchR-plotTrajectoryHeatmap-9a41b982-Date-2025-02-06_Time-03-01-51.901058.log
## If there is an issue, please report to github with logFile!
## Preparing Main Heatmap..
## 'magick' package is suggested to install to give better rasterization.
## 
## Set `ht_opt$message = FALSE` to turn off this message.
## ArchR logging successful to : ArchRLogs/ArchR-plotTrajectoryHeatmap-9a41b982-Date-2025-02-06_Time-03-01-51.901058.log
rowOrder <- match(rownames(combinedMat), rownames(trajGIM2))

ht1 <- plotTrajectoryHeatmap(trajGIM2,  pal = paletteContinuous(set = "blueYellow"),  varCutOff = 0, rowOrder = rowOrder)
## ArchR logging to : ArchRLogs/ArchR-plotTrajectoryHeatmap-94aadbd60-Date-2025-02-06_Time-03-01-52.597862.log
## If there is an issue, please report to github with logFile!
## Preparing Main Heatmap..
## 'magick' package is suggested to install to give better rasterization.
## 
## Set `ht_opt$message = FALSE` to turn off this message.
## ArchR logging successful to : ArchRLogs/ArchR-plotTrajectoryHeatmap-94aadbd60-Date-2025-02-06_Time-03-01-52.597862.log

ht2 <- plotTrajectoryHeatmap(trajMM2, pal = paletteContinuous(set = "solarExtra"), varCutOff = 0, rowOrder = rowOrder)
## ArchR logging to : ArchRLogs/ArchR-plotTrajectoryHeatmap-92feea91d-Date-2025-02-06_Time-03-01-53.351488.log
## If there is an issue, please report to github with logFile!
## useSeqnames is NULL or greater than 1 with a Sparse.Assays.Matrix trajectory input.
## 2025-02-06 03:01:53.760684 :
## force=FALSE thus continuing with subsetting useSeqnames = z
## 2025-02-06 03:01:53.766557 :
## Preparing Main Heatmap..
## 'magick' package is suggested to install to give better rasterization.
## 
## Set `ht_opt$message = FALSE` to turn off this message.
## ArchR logging successful to : ArchRLogs/ArchR-plotTrajectoryHeatmap-92feea91d-Date-2025-02-06_Time-03-01-53.351488.log

ComplexHeatmap::draw(ht1 + ht2)