ripleys_k() calculates the empirical Ripley's K for the cell types given in
mnames. This is useful for exploring the spatial clustering of single cell
types on TMA cores, ROI spots, or whole slide images following phenotyping with
a program such as HALO.
Either estimate CSR by permutation (permute = TRUE) or use the exact CSR
estimate (permute = FALSE). The exact estimate is the K of all cells in the
sample, which is the closed form for the expected K of a randomly chosen subset
of them, so it is both faster and free of Monte Carlo error. Permutations are
still useful if you want the full null distribution rather than its mean –
run 1000 and treat an observed value outside the 95th percentile as
significant.
Exact CSR is filled in either way, so with permute = TRUE you can read
Permuted CSR against it and see directly whether your permutation count was
large enough to converge. They agree exactly in expectation.
Usage
ripleys_k(
mif,
mnames,
r_range = seq(0, 100, 1),
num_permutations = 50,
edge_correction = "translation",
permute = FALSE,
keep_permutation_distribution = FALSE,
workers = 1,
overwrite = FALSE,
xloc = NULL,
yloc = NULL,
big = 10000,
...
)Arguments
- mif
object of class
mifcreated withcreate_mif- mnames
cell phenotype markers to calculate Ripley's K for
- r_range
radius range (including 0)
- num_permutations
number of permutations to use to estimate CSR. Ignored when
permute = FALSE.- edge_correction
edge correction method: one of "translation", "isotropic", "border" or "none". Unlike previous versions this is never silently downgraded for large samples. All four agree with
spatstat.explore::Kest()to floating-point precision; note that"border"reports noExact CSR(see below) and that"none"applies no correction at all and so is biased downward near the window edge.- permute
whether to estimate CSR by permutation (
TRUE) or to use the exact closed-form CSR estimate (FALSE, the default and much faster)- keep_permutation_distribution
whether to keep each permutation's result or average them into a single row per marker and radius
- workers
number of cores to use for calculations
- overwrite
whether to overwrite the
univariate_Countslot withinmif$derived- xloc, yloc
columns giving the cell centre. If left
NULL,XMin,XMax,YMinandYMaxmust be present and the centre is their midpoint.- big
cell count above which the per-pair edge-correction weights are computed in chunks to bound peak memory. This affects memory and speed only: results are identical either way, and the requested
edge_correctionis always honoured.- ...
support for deprecated argument names.
keep_perm_disis accepted as an alias forkeep_permutation_distribution;methodis accepted and ignored (it was never used). Anything else is an error.
The CSR columns, and which to trust
Three references are reported for each radius, and Degree of Clustering X is
always Observed K - X CSR:
Theoretical CSRis \(\pi r^2\), the K of a homogeneous Poisson process. It ignores the shape of the window and the cell density actually present, so it is the weakest of the three on real tissue.Exact CSRis the K of every cell in the sample. Under random labelling of a fixed set of cell locations this is exactly the expected K of a marker-positive subset – not an approximation – for translation, isotropic and none. It is the reference to prefer.Permuted CSRis the mean overnum_permutationsrandom relabellings.
Exact CSR is NA for edge_correction = "border". Border is a reduced-sample
estimator whose denominator counts only the cells still further than r from
the window edge, and that count changes with which cells are marker-positive. So
the cancellation that makes the other three exact does not apply, and the K of
all cells is not the expected K of a subset: measured on 600 cells with 120
positive, it sits about 1% below the mean permuted K at larger radii. Rather
than report a number that is quietly wrong in a column called "Exact", it is
omitted – as it is for NN_G() and pair_correlation(), for the same reason.
Use permute = TRUE with border.
Permutation p-values
Permutations Larger than Observed counts the permutations at least as extreme
as the observation (>=), so ties count toward the count and therefore toward a
larger p-value. Permutation p-value is the standard Monte Carlo p-value,
\((1 + \#\{perm \ge obs\}) / (B + 1)\), where B is the number of
permutations that actually produced a value at that radius. The +1s mean it
can never be exactly 0, which a raw count divided by B can be, and which would
read as infinite significance rather than "nothing in this sample was more
extreme".
Both are NA at radii where Observed K is NA.
Accuracy
Values agree with spatstat.explore::Kest() to floating-point precision. The
observation window is the convex hull of every cell in the sample, and it
is held fixed across all markers and permutations, so K values for different
markers within a sample are directly comparable.
Large samples are handled by only ever materialising the cell pairs closer than
max(r_range), rather than a full n-by-n distance matrix. At 200,000 cells
that is the difference between roughly 75 MB and 319 GB. Because of this,
big no longer changes the statistic – in versions before 2.0.0 exceeding it
silently replaced your edge_correction with "none".
Examples
x <- spatialTIME::create_mif(clinical_data = spatialTIME::example_clinical %>%
dplyr::mutate(deidentified_id = as.character(deidentified_id)),
sample_data = spatialTIME::example_summary %>%
dplyr::mutate(deidentified_id = as.character(deidentified_id)),
spatial_list = spatialTIME::example_spatial[1],
patient_id = "deidentified_id",
sample_id = "deidentified_sample")
x2 = ripleys_k(mif = x,
mnames = "CD3..Opal.570..Positive",
r_range = seq(0, 100, 10),
edge_correction = "translation",
permute = FALSE,
workers = 1,
overwrite = TRUE)
