Function to calculate the average number of neighbors B that a cell of type A has using different approaches.

countInteractions(
  object,
  group_by,
  label,
  colPairName,
  method = c("classic", "histocat", "patch"),
  patch_size = NULL
)

Arguments

object

a SingleCellExperiment or SpatialExperiment object .

group_by

a single character indicating the colData(object) entry by which interactions are grouped. This is usually the image ID or patient ID.

label

single character specifying the colData(object) entry which stores the cell labels. These can be cell-types labels or other metadata.

colPairName

single character indicating the colPair(object) entry containing cell-cell interactions in form of an edge list.

method

which cell-cell interaction counting method to use (see details)

patch_size

if method = "patch", a single numeric specifying the minimum number of neighbors of the same type to be considered a patch (see details)

Value

a DataFrame containing one row per group_by entry and unique label entry combination (from_label, to_label). The ct entry stores the interaction count as described in the details. NA is returned if a certain label is not present in this grouping level.

Counting and summarizing cell-cell interactions

In principle, the countInteractions function counts the number of edges (interactions) between each set of unique entries in colData(object)[[label]]. Simplified, it counts for each cell of type A the number of neighbors of type B. This count is averaged within each unique entry colData(object)[[group_by]] in three different ways:

1. method = "classic": The count is divided by the total number of cells of type A. The final count can be interpreted as "How many neighbors of type B does a cell of type A have on average?"

2. method = "histocat": The count is divided by the number of cells of type A that have at least one neighbor of type B. The final count can be interpreted as "How many many neighbors of type B has a cell of type A on average, given it has at least one neighbor of type B?"

3. method = "patch": For each cell, the count is binarized to 0 (less than patch_size neighbors of type B) or 1 (more or equal to patch_size neighbors of type B). The binarized counts are averaged across all cells of type A. The final count can be interpreted as "What fraction of cells of type A have at least a given number of neighbors of type B?"

See also

testInteractions for testing cell-cell interactions per grouping level.

Author

Vito Zanotelli

Jana Fischer

adapted by Nils Eling (nils.eling@dqbm.uzh.ch)

Examples

library(cytomapper)
data(pancreasSCE)

pancreasSCE <- buildSpatialGraph(pancreasSCE, img_id = "ImageNb", 
                                  type = "knn", k = 3)
#> The returned object is ordered by the 'ImageNb' entry.
                               
# Classic style calculation
(out <- countInteractions(pancreasSCE, 
                                group_by = "ImageNb",
                                label = "CellType", 
                                method = "classic",
                                colPairName = "knn_interaction_graph"))
#> DataFrame with 27 rows and 4 columns
#>      group_by from_label   to_label        ct
#>     <integer>   <factor>   <factor> <numeric>
#> 1           1 celltype_A celltype_A  1.823529
#> 2           1 celltype_A celltype_B  0.470588
#> 3           1 celltype_A celltype_C  0.705882
#> 4           1 celltype_B celltype_A  0.875000
#> 5           1 celltype_B celltype_B  0.250000
#> ...       ...        ...        ...       ...
#> 23          3 celltype_B celltype_B  2.363636
#> 24          3 celltype_B celltype_C  0.636364
#> 25          3 celltype_C celltype_A        NA
#> 26          3 celltype_C celltype_B  0.704918
#> 27          3 celltype_C celltype_C  2.295082
                                
# Histocat style calculation
(out <- countInteractions(pancreasSCE, 
                                group_by = "ImageNb",
                                label = "CellType", 
                                method = "histocat",
                                colPairName = "knn_interaction_graph"))
#> DataFrame with 27 rows and 4 columns
#>      group_by from_label   to_label        ct
#>     <integer>   <factor>   <factor> <numeric>
#> 1           1 celltype_A celltype_A   1.93750
#> 2           1 celltype_A celltype_B   1.14286
#> 3           1 celltype_A celltype_C   1.33333
#> 4           1 celltype_B celltype_A   1.16667
#> 5           1 celltype_B celltype_B   1.00000
#> ...       ...        ...        ...       ...
#> 23          3 celltype_B celltype_B   2.36364
#> 24          3 celltype_B celltype_C   1.31250
#> 25          3 celltype_C celltype_A        NA
#> 26          3 celltype_C celltype_B   1.65385
#> 27          3 celltype_C celltype_C   2.45614
                                
# Patch style calculation
(out <- countInteractions(pancreasSCE, 
                                group_by = "ImageNb",
                                label = "CellType", 
                                method = "patch",
                                patch_size = 3,
                                colPairName = "knn_interaction_graph"))
#> DataFrame with 27 rows and 4 columns
#>      group_by from_label   to_label        ct
#>     <integer>   <factor>   <factor> <numeric>
#> 1           1 celltype_A celltype_A  0.235294
#> 2           1 celltype_A celltype_B  0.000000
#> 3           1 celltype_A celltype_C  0.000000
#> 4           1 celltype_B celltype_A  0.000000
#> 5           1 celltype_B celltype_B  0.000000
#> ...       ...        ...        ...       ...
#> 23          3 celltype_B celltype_B 0.5151515
#> 24          3 celltype_B celltype_C 0.0000000
#> 25          3 celltype_C celltype_A        NA
#> 26          3 celltype_C celltype_B 0.0655738
#> 27          3 celltype_C celltype_C 0.5737705