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

Build the input table for spicyR

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 }

Test proximity of myeloid cells to epithelia

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")

Tests for changes across all celltypes

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