escape turns raw single-cell counts into intuitive, per-cell gene-set scores with a single command and then provides plotting helpers to interrogate them.
The core workflow is:
getGeneSets() or your own
list)runEscape())performNormalization())Counts can arrive as a plain matrix, a Seurat object, a
SingleCellExperiment, or a SpatialExperiment -
spots are treated as cells throughout, so nothing about the workflow
changes for spatial data. Scoring runs on escape’s own engines by
default, with an optional plaid backend for large
objects.
devtools::install_github("BorchLab/escape")
if (!require("BiocManager", quietly = TRUE))
install.packages("BiocManager")
BiocManager::install("escape")Two optional packages unlock features used below. Neither is required for the default workflow:
BiocManager::install("SpatialExperiment") # spatial objects
BiocManager::install("plaid") # the fast scoring backendLoad escape alongside a single-cell container (Seurat or SingleCellExperiment) and a plotting backend:
For the demonstration of escape, we will use the example
“pbmc_small” data from Seurat and also
generate a SingleCellExperiment object from it.
getGeneSets()Gene set enrichment analysis begins by identifying the appropriate
gene sets for your study. The getGeneSets() function
simplifies this process by extracting one or more gene set libraries
from the Molecular Signature Database (MSigDB) and returning them as a
GSEABase GeneSetCollection object. Note that the first time you run
getGeneSets(), it downloads a complete local copy of the
gene sets, which may take a little while. Future calls will use the
cached version, greatly improving performance.
To retrieve gene set collections from MSigDB, specify the library or libraries of interest using the library parameter. For example, to select multiple libraries, use:
In addition, the function supports further subsetting through these parameters:
msigdbr is an alternative R package to access the Molecular Signature Database in R. There is expanded support for species in the package as well as a mix of accessible versus downloadable gene sets, so it can be faster than caching a copy locally.
Several popular methods exist for Gene Set Enrichment Analysis (GSEA). These methods can vary in the underlying assumptions. escape incorporates several methods that are particularly advantageous for single-cell RNA values:
This method calculates the enrichment score using a rank-normalized approach and generating an empirical cumulative distribution function for each individual cell. The enrichment score is defined for a gene set (G) using the number of genes in the gene set (NG) and total number of genes (N).
\[ ES(G,S) \sum_{i = 1}^{n} [P_W^G(G,S,i)-P_{NG}(G,S,i)] \]
Please see the following citation for more information.
GSVA varies slightly by estimating a Poisson-based kernel cumulative density function. But like ssGSEA, the ultimate enrichment score reported is based on the maximum value of the random walk statistic. GSVA appears to have better overall consistency and runs faster than ssGSEA.
\[ ES_{jk}^{max} = V_{jk} [max_{l=1,...,p}|v_{jk}(l)] \]
Please see the following citation for more information.
In contrast to ssGSEA and GSVA, AUCell takes the gene rankings for each cell and step-wise plots the position of each gene in the gene set along the y-axis. The output score is the area under the curve for this approach.
Please see the following citation for more information.
UCell calculates a Mann-Whitney U statistic based on the gene rank list. Importantly, UCell has a cut-off for ranked genes (\[r_{max}\]) at 1500 - this is per design as drop-out in single-cell can alter enrichment results. This also substantially speeds the calculations up.
The enrichment score output is then calculated using the complement of the U statistic scaled by the gene set size and cut-off.
\[ U_j^` = 1-\frac{U_j}{n \bullet r_{max}} \]
Please see the following citation for more information.
Each method above runs on escape’s own engine by default. Setting
backend = "plaid" reroutes the calculation through plaid, which reimplements
these scores as a single sparse matrix operation and uses substantially
less memory. On a 166,000-spot Xenium SpatialExperiment
with three gene sets, UCell scoring took 28.6 s natively and 6.8 s
through plaid, a 4.2x speedup. plaid also provides three scores escape
has no native implementation for, which select the plaid backend on
their own.
| Method | Backends | Measured agreement with the native score | Input assay |
|---|---|---|---|
ssGSEA |
native, plaid | pooled Pearson ~0.85 | counts (native) / logcounts (plaid) |
GSVA |
native, plaid | pooled Pearson ~0.73 | counts (native) / logcounts (plaid) |
AUCell |
native, plaid | pooled Pearson ~0.83 | counts (native) / logcounts (plaid) |
UCell |
native, plaid | pooled Pearson ~0.83 | counts (native) / logcounts (plaid) |
PLAID |
plaid only | n/a - a distinct score | logcounts |
singscore |
plaid only | n/a - no native implementation | logcounts |
scSE |
plaid only | n/a - no native implementation | logcounts |
Those correlations come from a simulated 2000-gene, 120-cell matrix
with two planted gene sets. On narrower matrices they drop:
pbmc_small (230 genes) gives roughly 0.79 for UCell and
0.50 for ssGSEA.
# native (default)
scores <- escape.matrix(pbmc_small, gene.sets = GS.hallmark, method = "UCell")
# same method, plaid engine, log-normalized input picked automatically
fast <- escape.matrix(pbmc_small, gene.sets = GS.hallmark, method = "UCell",
backend = "plaid")
# method-specific tuning goes through backend.args, never through ...
tuned <- escape.matrix(pbmc_small, gene.sets = GS.hallmark, method = "ssGSEA",
backend = "plaid", backend.args = list(alpha = 0.25))Two arguments are easy to confuse. normalize is escape’s
post-hoc drop-out scaling (see performNormalization()
below). backend.args$normalize is plaid’s median
normalization of the raw scores, applied inside the calculation. They
are independent, and turning both on stacks them.
Install plaid with BiocManager::install("plaid"). If it
is missing, the native path is unaffected and any
backend = "plaid" call errors with install instructions.
Anyone using a plaid backend should cite Zito et al.,
Bioinformatics 2025, 41(12):btaf621 in addition to the original
method paper and escape.
input.assay controls which expression matrix is scored.
The default "auto" reads raw counts for the native backend
and log-normalized values for plaid, which is what each expects.
"counts" and "logcounts" resolve to the right
place for both object types - the counts and
data layers in Seurat, the counts and
logcounts assays in a SummarizedExperiment - so the same
call works across classes. Any other string is taken literally as a
layer or assay name.
Note that the four native methods are rank or CDF based, so a
monotone transform of the input generally leaves their scores unchanged.
input.assay matters most for the plaid paths, which average
in log space.
SpatialExperiment objects work anywhere a
SingleCellExperiment does, spots being treated as cells.
Nothing special is required - pass the object straight to
runEscape().
To keep this vignette self-contained, we build a small
SpatialExperiment from pbmc_small with made-up
coordinates rather than downloading a real slide:
library(SpatialExperiment)
set.seed(42)
spe <- SpatialExperiment(
assays = list(counts = counts(sce.pbmc)),
colData = colData(sce.pbmc),
spatialCoords = matrix(runif(2 * ncol(sce.pbmc)), ncol = 2,
dimnames = list(colnames(sce.pbmc), c("x", "y")))
)
spe <- runEscape(spe,
gene.sets = escape.gene.sets,
method = "UCell",
min.size = 3,
new.assay.name = "escape")
spe## class: SpatialExperiment
## dim: 230 80
## metadata(1): escape_backend
## assays(1): counts
## rownames(230): MS4A1 CD79B ... SPON2 S100B
## rowData names(0):
## colnames(80): ATGCCAGAACGACT CATGGCCTGTGCAT ... GGAACACTTCAGAC
## CTTGATTGATCTTC
## colData names(9): orig.ident nCount_RNA ... ident sample_id
## reducedDimNames(0):
## mainExpName: NULL
## altExpNames(1): escape
## spatialCoords names(2) : x y
## imgData names(0):
runEscape() attaches the scores as an altExp named by
new.assay.name and leaves the rest of the object alone
- spatialCoords(), imgData(), and
sample_id all survive unchanged:
## [1] "escape"
## [1] 80 2
The scores themselves carry no spatial information. Coordinates stay
on the parent object, so to plot enrichment against position you pull
both from spe:
scores <- t(assay(altExp(spe, "escape")))
df <- data.frame(spatialCoords(spe),
Proinflammatory = scores[, "Proinflammatory"])
ggplot(df, aes(x = x, y = y, color = Proinflammatory)) +
geom_point(size = 2) +
scale_color_gradientn(colors = hcl.colors(7, "inferno")) +
coord_fixed() +
theme_classic()Objects carrying several sample_id values need no
special treatment. Note that all downstream escape functions -
performNormalization(), performPCA(), and the
visualization gallery below - read the altExp the same way they would
for a SingleCellExperiment, so the rest of this vignette
applies unchanged.
escape has 2 major functions - the first being
escape.matrix(), which serves as the backbone of enrichment
calculations. Using count-level data supplied from a single-cell object
or matrix, escape.matrix() will produce an enrichment score
for the individual cells with the gene sets selected and output the
values as a matrix.
method
groups
min.size
normalize
make.positive
Cautionary note: make.positive was added to allow for differential analysis downstream of enrichment as some methods may produce negative values. It preserves log-fold change, but ultimately modifies the enrichment values and should be used with caution.
backend
backend.args
list(alpha = 0.25). Names are checked
against the target function, so a typo errors rather than being ignored.
Ordinary ... arguments go to the native engines and are
refused on the plaid path.input.assay
enrichment.scores <- escape.matrix(pbmc_small,
gene.sets = escape.gene.sets,
groups = 1000,
min.size = 5)
ggplot(data = as.data.frame(enrichment.scores),
mapping = aes(enrichment.scores[,1], enrichment.scores[,2])) +
geom_point() +
theme_classic() +
xlab(colnames(enrichment.scores)[1]) +
ylab(colnames(enrichment.scores)[2]) Multi-core support is for all methods is available through BiocParallel.
To add more cores, use the argument BPPARAM to
escape.matrix(). Here we will use the
SnowParam() for it’s support across platforms and
explicitly call 2 workers (or cores).
Alternatively, we can use runEscape() to calculate the
enrichment score and directly attach the output to a single-cell object.
The additional parameter for ``runEscape is
new.assay.name, in order to save the enrichment scores
as a custom assay in the single-cell object.
pbmc_small <- runEscape(pbmc_small,
method = "ssGSEA",
gene.sets = escape.gene.sets,
groups = 1000,
min.size = 3,
new.assay.name = "escape.ssGSEA")
sce.pbmc <- runEscape(sce.pbmc,
method = "UCell",
gene.sets = escape.gene.sets,
groups = 1000,
min.size = 5,
new.assay.name = "escape.UCell")We can quickly examine the attached enrichment scores using the
visualization/workflow we prefer - here we will use just
FeaturePlot() from the Seurat R package.
#Define color palette
colorblind_vector <- hcl.colors(n=7, palette = "inferno", fixup = TRUE)
FeaturePlot(pbmc_small, "Proinflammatory") +
scale_color_gradientn(colors = colorblind_vector) +
theme(plot.title = element_blank())Although we glossed over the normalization that can be used in
escape.matrix() and runEscape(), it is worth
mentioning here as normalization can affect all downstream analyses.
There can be inherent bias in enrichment values due to drop out in
single-cell expression data. Cells with larger numbers of features and
counts will likely have higher enrichment values.
performNormalization() will normalize the enrichment values
by calculating the number of genes expressed in each gene set and cell.
This is similar to the normalization in classic GSEA and it will be
stored in a new assay.
pbmc_small <- performNormalization(input.data = pbmc_small,
assay = "escape.ssGSEA",
gene.sets = escape.gene.sets)An alternative for scaling by expressed gene sets would be to use a scaling factor previously calculated during normal single-cell data processing and quality control. This can be done using the scale.factor argument and providing a vector.
pbmc_small <- performNormalization(input.data = pbmc_small,
assay = "escape.ssGSEA",
gene.sets = escape.gene.sets,
scale.factor = pbmc_small$nFeature_RNA)performNormalization() has an additional parameter
make.positive. Across the individual gene sets, if
negative normalized enrichment scores are seen, the minimum value is
added to all values. For example if the normalized enrichment scores
(after the above accounting for drop out) ranges from -50 to 50,
make.positive will adjust the range to 0 to 100 (by
adding 50). This allows for compatible log2-fold change downstream, but
can alter the enrichment score interpretation.
Three details are worth knowing:
performNormalization() ignores whatever
input.assay was used to compute the scores. Detection
is identical in count and log space, so this is deliberate.assay = NULL returns a matrix
rather than attaching a new assay to the object. This is how
escape.matrix(normalize = TRUE) calls it internally.Gene-set names are matched to the enrichment columns literally first,
then against the hyphenated form Seurat produces when it builds an
assay. That means underscored library names such as
HALLMARK_HYPOXIA normalize correctly whether the scores
live in a Seurat assay, an altExp, or a bare matrix.
There are a number of ways to look at the enrichment values
downstream of runEscape() with the myriad plotting and
visualizations functions/packages for single-cell data. escape
include several additional plotting functions to assist in the
analysis.
We can examine the enrichment values across our gene sets by using
heatmapEnrichment(). This visualization will return the
mean of the group.by variable. As a default - all
visualizations of single-cell objects will use the cluster assignment or
active identity as a default for visualizations.
Most of the visualizations in escape have a defined set of parameters.
group.by
facet.by
scale
In addition, heatmapEnrichment() allows for the
reclustering of rows and columns using Euclidean distance of the
enrichment scores and the Ward2 methods for clustering using
cluster.rows and cluster.columns.
heatmapEnrichment(sce.pbmc,
group.by = "ident",
assay = "escape.UCell",
scale = TRUE,
cluster.rows = TRUE,
cluster.columns = TRUE)Each visualization has an additional argument called **palette that
supplies the coloring scheme to be used - available color palettes can
be viewed with hcl.pals().
## [1] "Pastel 1" "Dark 2" "Dark 3" "Set 2"
## [5] "Set 3" "Warm" "Cold" "Harmonic"
## [9] "Dynamic" "Grays" "Light Grays" "Blues 2"
## [13] "Blues 3" "Purples 2" "Purples 3" "Reds 2"
## [17] "Reds 3" "Greens 2" "Greens 3" "Oslo"
## [21] "Purple-Blue" "Red-Purple" "Red-Blue" "Purple-Orange"
## [25] "Purple-Yellow" "Blue-Yellow" "Green-Yellow" "Red-Yellow"
## [29] "Heat" "Heat 2" "Terrain" "Terrain 2"
## [33] "Viridis" "Plasma" "Inferno" "Rocket"
## [37] "Mako" "Dark Mint" "Mint" "BluGrn"
## [41] "Teal" "TealGrn" "Emrld" "BluYl"
## [45] "ag_GrnYl" "Peach" "PinkYl" "Burg"
## [49] "BurgYl" "RedOr" "OrYel" "Purp"
## [53] "PurpOr" "Sunset" "Magenta" "SunsetDark"
## [57] "ag_Sunset" "BrwnYl" "YlOrRd" "YlOrBr"
## [61] "OrRd" "Oranges" "YlGn" "YlGnBu"
## [65] "Reds" "RdPu" "PuRd" "Purples"
## [69] "PuBuGn" "PuBu" "Greens" "BuGn"
## [73] "GnBu" "BuPu" "Blues" "Lajolla"
## [77] "Turku" "Hawaii" "Batlow" "Blue-Red"
## [81] "Blue-Red 2" "Blue-Red 3" "Red-Green" "Purple-Green"
## [85] "Purple-Brown" "Green-Brown" "Blue-Yellow 2" "Blue-Yellow 3"
## [89] "Green-Orange" "Cyan-Magenta" "Tropic" "Broc"
## [93] "Cork" "Vik" "Berlin" "Lisbon"
## [97] "Tofino" "ArmyRose" "Earth" "Fall"
## [101] "Geyser" "TealRose" "Temps" "PuOr"
## [105] "RdBu" "RdGy" "PiYG" "PRGn"
## [109] "BrBG" "RdYlBu" "RdYlGn" "Spectral"
## [113] "Zissou 1" "Cividis" "Roma"
Alternatively, we can add an additional layer to the ggplot object
that is returned by the visualizations using something like
scale_fill_gradientn() for continuous values or
scale_fill_manual() for the categorical variables.
heatmapEnrichment(sce.pbmc,
group.by = "ident",
assay = "escape.UCell") +
scale_fill_gradientn(colors = rev(brewer.pal(11, "RdYlBu"))) We can also focus on individual gene sets - one approach is to use
geyserEnrichment(). Here individual cells are plotted along
the Y-axis with graphical summary where the central dot refers to the
median enrichment value and the thicker/thinner lines demonstrate the
interval summaries referring to the 66% and 95%.
To show the additional parameters that appear in visualizations of individual enrichment gene sets - we can reorder the groups by the mean of the gene set using order.by = “mean”.
geyserEnrichment(pbmc_small,
assay = "escape.ssGSEA",
gene.set.use = "T1-Interferon",
order.by = "mean")What if we had 2 separate samples or groups within the data? Another parameter we can use is facet.by to allow for direct visualization of an additional variable.
geyserEnrichment(pbmc_small,
assay = "escape.ssGSEA",
gene.set.use = "T1-Interferon",
facet.by = "groups")Lastly, we can select the way the color is applied to the plot using the color.by parameter. Here we can set it to the gene set of interest “HALLMARK-INTERFERON-GAMMA-RESPONSE”.
geyserEnrichment(pbmc_small,
assay = "escape.ssGSEA",
gene.set.use = "T1-Interferon",
color.by = "T1-Interferon")Similar to the geyserEnrichment() the
ridgeEnrichment() can display the distribution of
enrichment values across the selected gene set. The central line is at
the median value for the respective grouping.
We can get the relative position of individual cells along the x-axis using the add.rug parameter.
ridgeEnrichment(sce.pbmc,
assay = "escape.UCell",
gene.set.use = "T2_Interferon",
add.rug = TRUE,
scale = TRUE)Another distribution visualization is a violin plot, which we
separate and directly compare using a binary classification. Like
ridgeEnrichment(), this allows for greater use of
categorical variables. For splitEnrichment(), the output
will be two halves of a violin plot based on the
split.by parameter with a central boxplot with the
relative distribution across all samples.
splitEnrichment(pbmc_small,
assay = "escape.ssGSEA",
gene.set.use = "Lipid-mediators",
split.by = "groups")If selecting a split.by variable with more than 2
levels, splitEnrichment() will convert the violin plots to
dodge.
splitEnrichment(pbmc_small,
assay = "escape.ssGSEA",
gene.set.use = "Lipid-mediators",
split.by = "ident",
group.by = "groups")gseaEnrichment() reproduces the two-panel GSEA graphic
from Subramanian et al. (2005): * Panel A – the running enrichment score
(RES) as you “walk” down the ranked list. * Panel B – a rug showing
exact positions of each pathway gene.
It works on escape’s per-cell ranks, but collapses them across cells with a summary statistic (summary.fun = “mean” by default).
How it works:
gseaEnrichment(pbmc_small,
gene.set.use = "T2_Interferon",
gene.sets = escape.gene.sets,
group.by = "ident",
summary.fun = "mean",
nperm = 1000)densityEnrichment() is a method to visualize the mean
rank position of the gene set features along the total feature space by
group. Instead of the classic GSEA running-score, it overlays
kernel-density traces of the gene ranks (1 =
most highly expressed/ranked gene) for every group or cluster. High
densities at the left-hand side mean the pathway is
collectively up-regulated; peaks on the right
imply down-regulation.
Anatomy of the plot
group.by – default is Seurat/SCE cluster.It may be advantageous to look at the distribution of multiple gene
sets - here we can use scatterEnrichment() for a 2 gene set
comparison. The color values are based on the density of points
determined by the number of neighbors, similar to the Nebulosa
R package. We just need to define which gene set to plot on the
x.axis and which to plot on the
y.axis.
scatterEnrichment(pbmc_small,
assay = "escape.ssGSEA",
x.axis = "T2-Interferon",
y.axis = "Lipid-mediators")The scatter plot can also be converted into a hexbin, another method for summarizing the individual cell distributions along the x and y axis, by setting style = “hex”.
scatterEnrichment(sce.pbmc,
assay = "escape.UCell",
x.axis = "T2_Interferon",
y.axis = "Lipid_mediators",
style = "hex")escape has its own PCA function performPCA() which will
work on a single-cell object or a matrix of enrichment values. This is
specifically useful for downstream visualizations as it stores the
eigenvalues and rotations. If we want to look at the relative
contribution to overall variance of each component or a Biplot-like
overlay of the individual features, use performPCA().
Alternatively, other PCA-based functions like Seurat’s
RunPCA() or scater’s ``runPCA() can be used.
These functions are likely faster and would be ideal if we have a larger
number of cells and/or gene sets.
escape has a built in method for plotting PCA
pcaEnrichment() that functions similarly to the
scatterEnrichment() function where x.axis
and y.axis are the components to plot.
pcaEnrichment() can plot additional information on the
principal component analysis.
add.percent.contribution will add the relative percent contribution of the x and y.axis to total variability observed in the PCA.
display.factors will overlay the magnitude and direction that the features/gene sets contribute to the selected components. The number of gene sets is determined by number.of.factors. This can assist in understanding the underlying differences in enrichment across different cells.
pcaEnrichment(pbmc_small,
dimRed = "escape.PCA",
x.axis = "PC1",
y.axis = "PC2",
add.percent.contribution = TRUE,
display.factors = TRUE,
number.of.factors = 10)Functional enrichment is not limited to per-cell scores. Many
workflows start with differential-expression (DE)
statistics (e.g. Seurat’s FindMarkers(), DESeq2’s
results(), edgeR’s topTags()). Those produce a
ranked gene list that can be fed into a classical
Gene-Set Enrichment Analysis (GSEA).
enrichIt() accepts either
The helper automatically chooses the best p-value column in this order:
p_val_adjpadj (DESeq2)FDR (edgeR)p_valenrichIt() workflowDEG.markers <- FindMarkers(pbmc_small,
ident.1 = "0",
ident.2 = "1")
GSEA.results <- enrichIt(input.data = DEG.markers,
gene.sets = escape.gene.sets,
ranking_fun = "signed_log10_p")
head(GSEA.results)## pathway pval padj log2err ES NES size
## <char> <num> <num> <num> <num> <num> <int>
## 1: T2_Interferon 0.2478541 0.8083678 0.08336341 -0.8228147 -1.1007827 10
## 2: M1.Macro 0.3233471 0.8083678 0.06767604 -0.7714736 -1.0683506 15
## 3: Proinflammatory 0.7155963 0.9487459 0.15740290 0.4002094 0.6185734 8
## 4: Lipid_mediators 0.8472554 0.9487459 0.02921031 -0.6849303 -0.8766974 6
## 5: CD8_Activation 0.9487459 0.9487459 0.01770381 -0.5167583 -0.6855810 9
## leadingEdge
## <char>
## 1: HLA-DRB1;HLA-DPB1;HLA-DPA1;HLA-DRA;HLA-DRB5;HLA-DQB1;HLA-DQA1;HLA-DMB;HLA-DMA
## 2: HLA-DRB1;HLA-DPB1;HLA-DPA1;HLA-DRA;HLA-DRB5;CD14;HLA-DQB1;HLA-DQA1;HLA-DMB;HLA-DMA;IL1B
## 3: GZMA;PRF1
## 4: CTSS;CFD;LGALS3;IL1B
## 5: HLA-DRA
## geneRatio
## <num>
## 1: 0.9000000
## 2: 0.7333333
## 3: 0.2500000
## 4: 0.6666667
## 5: 0.1111111
What does the result look like?
The companion enrichItPlot() gives three quick chart
types.
## (2) Dot plot – coloured by –log10 padj, sized by core-hits
enrichItPlot(GSEA.results, "dot", top = 10) ## (3) C-net plot – network of pathways ↔ leading-edge genes
enrichItPlot(GSEA.results, "cnet", top = 5) Differential enrichment analysis can be performed similar to differential gene expression analysis. For the purposes of finding the differential enrichment values, we can first normalize the enrichment values for the ssGSEA calculations. Notice here, we are using make.positive = TRUE in order to adjust any negative values. This is a particular issue when it comes to ssGSEA and GSVA enrichment scores.
pbmc_small <- performNormalization(pbmc_small,
assay = "escape.ssGSEA",
gene.sets = escape.gene.sets,
make.positive = TRUE)
all.markers <- FindAllMarkers(pbmc_small,
assay = "escape.ssGSEA_normalized",
min.pct = 0,
logfc.threshold = 0)
head(all.markers)## p_val avg_log2FC pct.1 pct.2 p_val_adj cluster
## T2-Interferon 2.210898e-09 -0.4499809 1 1 1.989808e-08 0
## CD8-Activation 2.791543e-06 0.9948584 1 1 2.512388e-05 0
## M1.Macro 9.243851e-06 -0.3021382 1 1 8.319466e-05 0
## Cytolytic 1.104433e-04 1.9352033 1 1 9.939895e-04 0
## T1-Interferon 4.895518e-04 -0.4474723 1 1 4.405966e-03 0
## Lipid-mediators 6.294119e-03 -0.2174715 1 1 5.664707e-02 0
## gene
## T2-Interferon T2-Interferon
## CD8-Activation CD8-Activation
## M1.Macro M1.Macro
## Cytolytic Cytolytic
## T1-Interferon T1-Interferon
## Lipid-mediators Lipid-mediators
If you have any questions, comments or suggestions, feel free to visit the github repository.
## R version 4.6.1 (2026-06-24)
## Platform: x86_64-pc-linux-gnu
## Running under: Ubuntu 26.04.1 LTS
##
## Matrix products: default
## BLAS: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
## LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.32.so; LAPACK version 3.12.0
##
## locale:
## [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
## [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
## [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
## [7] LC_PAPER=en_US.UTF-8 LC_NAME=C
## [9] LC_ADDRESS=C LC_TELEPHONE=C
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
##
## time zone: Etc/UTC
## tzcode source: system (glibc)
##
## attached base packages:
## [1] stats4 stats graphics grDevices utils datasets methods
## [8] base
##
## other attached packages:
## [1] SpatialExperiment_1.23.0 ggplot2_4.0.3
## [3] RColorBrewer_1.1-3 Seurat_5.6.0
## [5] SeuratObject_5.4.0 sp_2.2-4
## [7] scran_1.41.1 scuttle_1.23.2
## [9] SingleCellExperiment_1.35.2 SummarizedExperiment_1.43.0
## [11] Biobase_2.73.2 GenomicRanges_1.65.4
## [13] Seqinfo_1.3.2 IRanges_2.47.5
## [15] S4Vectors_0.51.10 BiocGenerics_0.59.12
## [17] generics_0.1.4 MatrixGenerics_1.25.0
## [19] matrixStats_1.5.0 escape_2.9.1
## [21] BiocStyle_2.41.0
##
## loaded via a namespace (and not attached):
## [1] GSVA_2.7.25 spatstat.sparse_3.2-0
## [3] httr_1.4.9 tools_4.6.1
## [5] sctransform_0.4.3 R6_2.6.1
## [7] HDF5Array_1.41.3 uwot_0.2.5
## [9] ggdist_3.3.3 rhdf5filters_1.25.4
## [11] withr_3.0.3 gridExtra_2.3.1
## [13] progressr_1.1.0 cli_3.6.6
## [15] spatstat.explore_3.8-3 fastDummies_1.7.6
## [17] labeling_0.4.3 sass_0.4.10
## [19] S7_0.2.2 spatstat.data_3.1-9
## [21] ggridges_0.5.7 pbapply_1.7-5
## [23] parallelly_1.48.0 limma_3.99.3
## [25] RSQLite_3.53.3 ica_1.0-3
## [27] spatstat.random_3.5-2 dplyr_1.2.1
## [29] distributional_0.9.0 Matrix_1.7-6
## [31] abind_1.4-8 lifecycle_1.0.5
## [33] yaml_2.3.12 edgeR_4.99.10
## [35] rhdf5_2.57.20 SparseArray_1.13.4
## [37] Rtsne_0.17 grid_4.6.1
## [39] blob_1.3.0 promises_1.5.0
## [41] dqrng_0.4.1 crayon_1.5.3
## [43] miniUI_0.1.2 lattice_0.23-1
## [45] beachmat_2.29.3 cowplot_1.2.0
## [47] annotate_1.91.0 KEGGREST_1.53.6
## [49] magick_2.9.1 sys_3.4.3
## [51] maketools_1.3.2 pillar_1.11.1
## [53] knitr_1.52 metapod_1.21.0
## [55] fgsea_1.39.2 rjson_0.2.23
## [57] future.apply_1.21.0 codetools_0.2-20
## [59] fastmatch_1.1-8 glue_1.8.1
## [61] spatstat.univar_3.2-0 data.table_1.18.6.1
## [63] memuse_4.2-3 vctrs_0.7.3
## [65] png_0.1-9 spam_2.11-4
## [67] gtable_0.3.6 cachem_1.1.0
## [69] xfun_0.62 S4Arrays_1.13.2
## [71] mime_0.13 tidygraph_1.3.1
## [73] survival_3.8-12 statmod_1.5.2
## [75] bluster_1.23.1 fitdistrplus_1.2-6
## [77] ROCR_1.0-12 nlme_3.1-171
## [79] bit64_4.8.6 RcppAnnoy_0.0.23
## [81] bslib_0.12.0 irlba_2.4.1
## [83] KernSmooth_2.23-27 otel_0.2.0
## [85] DBI_1.3.0 UCell_2.17.1
## [87] tidyselect_1.2.1 bit_4.6.0
## [89] compiler_4.6.1 graph_1.91.0
## [91] BiocNeighbors_2.7.3 h5mread_1.5.3
## [93] DelayedArray_0.39.8 plotly_4.12.1
## [95] scales_1.4.0 lmtest_0.9-40
## [97] hexbin_1.28.6 stringr_1.6.0
## [99] digest_0.6.39 goftest_1.2-3
## [101] spatstat.utils_3.2-5 rmarkdown_2.32
## [103] XVector_0.53.0 htmltools_0.5.9
## [105] pkgconfig_2.0.3 sparseMatrixStats_1.25.0
## [107] fastmap_1.2.0 rlang_1.3.0
## [109] htmlwidgets_1.6.4 shiny_1.14.0
## [111] DelayedMatrixStats_1.35.0 farver_2.1.2
## [113] jquerylib_0.1.4 zoo_1.9-1
## [115] jsonlite_2.0.0 BiocParallel_1.47.0
## [117] BiocSingular_1.29.2 magrittr_2.0.5
## [119] dotCall64_1.2 patchwork_1.3.2
## [121] Rhdf5lib_2.1.0 Rcpp_1.1.2
## [123] viridis_0.6.5 reticulate_1.47.0
## [125] stringi_1.8.9 ggraph_2.2.2
## [127] MASS_7.3-66 plyr_1.8.9
## [129] parallel_4.6.1 listenv_1.1.0
## [131] ggrepel_0.9.8 deldir_2.0-4
## [133] Biostrings_2.81.9 graphlayouts_1.2.5
## [135] splines_4.6.1 tensor_1.5.1
## [137] locfit_1.5-9.12 igraph_2.3.4
## [139] spatstat.geom_3.8-3 RcppHNSW_0.7.0
## [141] buildtools_1.0.0 reshape2_1.4.5
## [143] ScaledMatrix_1.21.0 XML_3.99-0.25
## [145] evaluate_1.0.5 BiocManager_1.30.27
## [147] tweenr_2.0.3 httpuv_1.6.17
## [149] RANN_2.6.3 tidyr_1.3.2
## [151] purrr_1.2.2 polyclip_1.10-7
## [153] future_1.80.0 scattermore_1.2
## [155] BiocBaseUtils_1.15.1 ggforce_0.5.0
## [157] rsvd_1.0.6 xtable_1.8-8
## [159] RSpectra_0.16-2 later_1.4.8
## [161] viridisLite_0.4.3 ggpointdensity_0.2.1
## [163] tibble_3.3.1 memoise_2.0.1
## [165] AnnotationDbi_1.75.2 cluster_2.1.8.3
## [167] globals_0.20.0 GSEABase_1.75.0