
phenoscapR provides a complete toolkit for reading, processing, analysing,
and visualising single-cell spatial biology data from multiplexed imaging
platforms. It handles the full workflow from raw cell segmentation CSV files
through quality control, marker normalisation, cell phenotyping, spatial
statistics, and publication-ready visualisation — using an efficient
data.table backend and a clean S4 object model (SpatialCellData).
SpatialCellData S4 class stores counts, normalised data, coordinates,
metadata, and spatial results in one objectNCells(), Markers(), Coords(), Meta(),
GetData(), Idents(), [, [[, $
qc_filter() / QCFilter())normalise_markers() / NormaliseData())QCPlot())phenotype_cells() /
PhenotypeCells())summarise_phenotypes() /
PhenotypeSummary())ExactPatientTests())AdjustPatientFamilies())phenoscapR requires R 4.1.0 or newer and is not on CRAN yet. Install it from GitHub:
if (!requireNamespace("pak", quietly = TRUE)) install.packages("pak")
pak::pak("CTTIR/phenoscapR")
Optional canonical cell-table imports and SONG embeddings require packages available from the CTTIR R-universe:
# For FromCellspec()
install.packages("cellspecR", repos = c("https://cttir.r-universe.dev", getOption("repos")))
# For RunSONG()
install.packages("songR", repos = c("https://cttir.r-universe.dev", getOption("repos")))
These packages are optional. Calling the corresponding function without its dependency reports an error; phenoscapR does not install packages automatically.
The package ships a synthetic two-sample example dataset, so you can run the whole workflow without any files of your own:
library(phenoscapR)
data(phenoscapR_example)
obj <- phenoscapR_example
obj <- NormaliseData(obj, method = "zscore")
obj <- PhenotypeCells(obj, thresholds = list(CD20 = 1, CD3 = 1, CD8 = 1,
CD68 = 1, PanCK = 1, FoxP3 = 1))
# Per-sample spatial structure
im <- InteractionMatrix(obj, radius = 40)
InteractionPlot(im)
# Single-tissue point-pattern statistics
a <- obj[obj$sample_id == "tonsil_A", ]
RipleysK(a, correction = "border")
NeighbourhoodEnrichment(a, radius = 40, n_perm = 199)
CellMap(a)
A typical real analysis starts from your own segmentation output:
# 1. Read cell segmentation CSV (or a directory of them)
obj <- ReadSpatial("path/to/segmentation.csv", sample_id = "sample1")
# 2. Quality control
obj <- QCFilter(obj, min_area = 50, max_area = 500)
# 3. Normalise marker intensities
obj <- NormaliseData(obj, method = "zscore")
# 4. Assign phenotypes by marker thresholds
obj <- PhenotypeCells(obj, thresholds = list(CD3 = 0.5, CD8 = 0.3,
CD20 = 0.4, PanCK = 0.6))
# 5. Spatial analysis
obj <- FindNeighbours(obj, k = 5)
obj <- CellDensity(obj, radius = 50)
obj <- DelaunayNetwork(obj)
ne <- NeighbourhoodEnrichment(obj[obj$sample_id == "sample1", ],
radius = 50, n_perm = 100)
# 6. Visualise
CellMap(obj)
FeaturePlot(obj, features = c("CD3", "CD8"))
MarkerHeatmap(obj)
InteractionPlot(InteractionMatrix(obj, radius = 50))
SpatialNetworkPlot(obj)
Coordinate columns must contain actual numeric values; factor labels are not
silently converted to integer codes. CSV readers preserve leading zeros in
declared and reserved identifier columns: 001 and 1 remain distinct. QuPath Image names are retained in
source_image. If different Image labels collapse to the same legacy sample
identifier, import stops so you can supply distinct identities explicitly.
as_SpatialCellData() retains available normalized assays when importing from
Seurat or SpatialExperiment. Seurat's marker-name rewriting is refused on
export; use SpatialExperiment when those exact names must be preserved.
SaveFigure() requires distinct PDF and PNG destinations in existing folders.
It renders both formats before replacing either file. A reported rendering
failure leaves previous files intact; a replacement failure attempts restoration
and reports the path of any original backup it cannot restore. This recovery
does not cover process termination or another program writing the same paths.
All neighbour-based statistics route through a kd-tree search engine
(RANN when installed, with an exact base-R fallback otherwise), so a
20,000-cell section runs each statistic in seconds instead of building a
multi-gigabyte distance matrix.
phenoscapR ships a Hugo Coder–themed Shiny app for the bundled synthetic teaching data and known simulated phenotypes. Explore QC, spatial statistics, cellular neighbourhoods, spatial domains, PCA/UMAP, and differential abundance with a light/dark toggle. It does not import user objects or export results; use the package functions for those workflows. Each example section is one sample in its own condition, so the displayed differential-abundance results are a demonstration, not replicated group inference.
# one-time: install the optional app dependencies
install.packages(c("shiny", "bslib", "sass", "thematic", "reactable",
"bsicons", "brand.yml"))
phenoscapR::run_app()
Branding requires bslib >= 0.9.0. UMAP additionally requires uwot; selecting
UMAP without it shows an installation hint, while PCA remains available.
If a QC filter removes every cell, widen it or use Reset cell-area filter;
the same session recovers without restarting the app.
The app's visual design is adapted from the Hugo Coder theme (MIT) — colour tokens and flat aesthetic only, no source copied.
Full documentation and vignettes are available at https://cttir.github.io/phenoscapR/
| Vignette | Description |
|---|---|
| Getting Started | End-to-end workflow with simulated data |
| The SpatialCellData Object | S4 class internals, accessors, and subsetting |
| Advanced Spatial Analysis | Ripley's K, Moran's I, neighbourhood enrichment, and choosing a statistic |
| Visualisation Gallery | Every plotting function, demonstrated on the example data |
Bug reports and feature requests are welcome at https://github.com/CTTIR/phenoscapR/issues.
citation("phenoscapR")
R. Heller, E. Chteinberg, H. Witte (2026). phenoscapR: Read, Analyse, and Visualise Single-Cell Spatial Biology Data. R package version 0.2.0.9001. https://cttir.github.io/phenoscapR/
@Manual{,
title = {phenoscapR: Read, Analyse, and Visualise Single-Cell Spatial Biology Data},
author = {R. Heller and E. Chteinberg and H. Witte},
year = {2026},
note = {R package version 0.2.0.9001},
url = {https://cttir.github.io/phenoscapR/},
}
MIT © R. Heller, E. Chteinberg and H. Witte
Editable R sources and regeneration instructions are in tools/branding.