Are myeloid cells migrating closer to the epithelia in crohn’s disease?
We can use spicyR to test if there is a change in the relative closeness of different celltypes (e.g. myeloid and epithelia) across different condition.
See: spicyR vignette
SpicyR can work with a SFE object, but not in this specific case (It lacks image data, and some coordinates are negative). So instead, we will build a table of the relevant input data.
For every cell, it requires the following
The centroid coordinates of each cell are available with the spatialCoords function
head(spatialCoords(sfe))
## CenterX_global_px CenterY_global_px
## 1000_1 20114.5556 172987.6
## 1000_2 16544.1111 172548.4
## 1000_4 687.8889 169392.8
## 1001_1 18325.5556 173004.6
## 1001_2 17019.1111 172531.4
## 1001_3 10338.0000 170686.6
Everything else we need is stored in the ColData(). We can join those two tables together, and then rename some columns according to what spicyR expects.
#epi => myeloid
spicy_cell_info <- as.data.frame(colData(sfe))[,c('cell', 'tissue_sample', 'celltype_subset', 'group', 'fov_name') ]
spicy_cell_info <- cbind(spicy_cell_info, spatialCoords(sfe))
spicy_cell_info <- spicy_cell_info %>%
dplyr::rename(
imageID = fov_name, #there are 4 fovs per tissue sample. In xenium data, that would be one per slide. And in other experiments, many samples per image.
x=CenterX_global_px,
y=CenterY_global_px
)
spicy_cell_info$imageID <- droplevels(spicy_cell_info$imageID)
Offset any negative X/Y coordinates to positive. The absolute positions don’t matter.
# remove negative values - not supported by spicyR
# Else yields error: Error in owinInternalRect(xrange, yrange, ..., unitname = unitname): xrange should be a vector of length 2 giving (xmin, xmax)
min_x <- min(spicy_cell_info$x)
min_y <- min(spicy_cell_info$y)
if (min_x < 0) {spicy_cell_info$x = spicy_cell_info$x + -(min_x) + 1 }
if (min_y < 0) {spicy_cell_info$y = spicy_cell_info$y + -(min_y) + 1 }
spicy_res <- spicy(
cells = spicy_cell_info ,
subject = 'tissue_sample',
cellType = 'celltype_subset',
sigma = 50, # tissue is not homogeneous see: https://www.bioconductor.org/packages/release/workflows/vignettes/spicyWorkflow/inst/doc/spicyWorkflow.html#14_spicyR:_Test_spatial_relationships
condition = "group",
from = "epi",
to = "myeloids"
)
## Dropping unused levels. Using group = HC as base comparison group. If this is
## not the desired base group, please convert cells$group into a factor and change
## the order of levels(cells$group) so that the base group is at index 1.
## Warning: The `BPPARAM` argument of `getPairwise()` is deprecated as of spicyR 1.18.0.
## i Please use the `cores` argument instead.
## i The deprecated feature was likely used in the spicyR package.
## Please report the issue at <https://github.com/SydneyBioX/spicyR/issues>.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
NB: Garrido-Trigo et al did a detailed exploration of localisation of macrophage and neutrophil subtypes in their data. We are testing a toy subset with some very broad celltypes!
topPairs(spicy_res)
We can plot the ‘L-function’ between these groups per condition. There is an L value for each sample, which represents the ‘closeness’ of the celltype pair in that sample. Higher values indicates co-location.
spicyBoxPlot(spicy_res,
from = "epi",
to = "myeloids")
If we omit the pair of celltypes - all combinations will be tested.
spicy_res <- spicy(
cells = spicy_cell_info ,
subject = 'tissue_sample',
cellType = 'celltype_subset',
sigma = 50, # tissue is not homogeneous see: https://www.bioconductor.org/packages/release/workflows/vignettes/spicyWorkflow/inst/doc/spicyWorkflow.html#14_spicyR:_Test_spatial_relationships
condition = "group"
)
## Dropping unused levels. Using group = HC as base comparison group. If this is
## not the desired base group, please convert cells$group into a factor and change
## the order of levels(cells$group) so that the base group is at index 1.
And there is a very nice visualisation. The size of the circle scales with significant, and the colour indicates the magnitude of the ‘L’ Value.
signifPlot(spicy_res)
We should interpret this carefully (especially for such a small dataset) - is it actually interesting biology?
p1 <- plotSpatialFeature(sfe.sample.HC, "celltype_subset",colGeometryName = "cellSeg") +
theme(legend.title=element_blank()) +
ggtitle(sample)
p2 <- plotSpatialFeature(sfe.sample.CD, "celltype_subset", colGeometryName = "cellSeg") +
theme(legend.title=element_blank()) +
ggtitle(sample)
p1 / p2