| Title: | A Tool for Spatial Multi-sample Comparisons |
|---|---|
| Description: | spatialFDA is a package to calculate spatial statistics metrics. The package takes a SpatialExperiment object and calculates spatial statistics metrics using the package spatstat. Then it compares the resulting functions across samples/conditions using functional additive models as implemented in the package refund. Furthermore, it provides exploratory visualisations using functional principal component analysis, as well implemented in refund. |
| Authors: | Martin Emons [aut, cre] (ORCID: <https://orcid.org/0009-0000-5219-5311>), Samuel Gunz [aut] (ORCID: <https://orcid.org/0000-0002-8909-0932>), Fabian Scheipl [aut] (ORCID: <https://orcid.org/0000-0001-8172-3603>), Elizabeth Purdom [aut] (ORCID: <https://orcid.org/0000-0001-9455-7990>), Mark D. Robinson [aut, fnd] (ORCID: <https://orcid.org/0000-0002-3048-5518>) |
| Maintainer: | Martin Emons <[email protected]> |
| License: | GPL (>= 3) + file LICENSE |
| Version: | 1.5.0 |
| Built: | 2026-05-29 09:30:08 UTC |
| Source: | https://github.com/bioc/spatialFDA |
Convert SpatialExperiment object to ppp object
.dfToppp(df, marks = NULL, continuous = FALSE, window = NULL).dfToppp(df, marks = NULL, continuous = FALSE, window = NULL)
df |
A dataframe with the x and y coordinates from the corresponding SpatialExperiment and the ColData |
marks |
A vector of marks to be associated with the points, has to be either named 'cell_type' if you want to compare discrete celltypes or else continous gene expression measurements are assumed as marks. |
continuous |
A boolean indicating whether the marks are continuous defaults to FALSE |
window |
An observation window of the point pattern of class |
A ppp object for use with spatstat functions
# retrieve example data from Damond et al. (2019) spe <- .loadExample() speSub <- subset(spe, , image_number == "138") dfSub <- .speToDf(speSub) pp <- .dfToppp(dfSub, marks = "cell_type")# retrieve example data from Damond et al. (2019) spe <- .loadExample() speSub <- subset(spe, , image_number == "138") dfSub <- .speToDf(speSub) pp <- .dfToppp(dfSub, marks = "cell_type")
A function that takes a SpatialExperiment object and computes a spatial
statistics function as implemented in spatstat. The output is a spatstat
object.
.extractMetric( df, selection, fun, marks = NULL, rSeq = NULL, by = NULL, continuous = FALSE, window = NULL, ... ).extractMetric( df, selection, fun, marks = NULL, rSeq = NULL, by = NULL, continuous = FALSE, window = NULL, ... )
df |
A |
selection |
the mark(s) you want to compare |
fun |
the |
marks |
the marks to consider e.g. cell types |
rSeq |
the range of r values to compute the function over |
by |
the spe |
continuous |
A boolean indicating whether the marks are continuous defaults to FALSE |
window |
a observation window for the point pattern of class |
... |
Other parameters passed to |
a spatstat metric object with the fov number, the number of
points and the centroid of the image
# retrieve example data from Damond et al. (2019) spe <- .loadExample() speSub <- subset(spe, , image_number == "138") dfSub <- .speToDf(speSub) metricRes <- .extractMetric(dfSub, c("alpha", "Tc"), fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), by = c("patient_stage", "patient_id", "image_number") )# retrieve example data from Damond et al. (2019) spe <- .loadExample() speSub <- subset(spe, , image_number == "138") dfSub <- .speToDf(speSub) metricRes <- .extractMetric(dfSub, c("alpha", "Tc"), fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), by = c("patient_stage", "patient_id", "image_number") )
load Example dataset from Damond et al. (2019)
.loadExample(full = FALSE).loadExample(full = FALSE)
full |
a boolean indicating whether to load the entire Damond et al. (2019) or only a subset |
A SpatialExperiment object as uploaded to ExperimentHub()
# retrieve the Damond et al. (2019) dataset spe <- .loadExample()# retrieve the Damond et al. (2019) dataset spe <- .loadExample()
Transform a SpatialExperiment into a dataframe
.speToDf(spe).speToDf(spe)
spe |
A SpatialExperiment object subset to a single image |
A dataframe with the x and y coordinates from the corresponding SpatialExperiment and the colData
# retrieve example data from Damond et al. (2019) spe <- .loadExample() speSub <- subset(spe, , image_number == "138") dfSub <- .speToDf(speSub)# retrieve example data from Damond et al. (2019) spe <- .loadExample() speSub <- subset(spe, , image_number == "138") dfSub <- .speToDf(speSub)
A function that takes a SpatialExperiment object as input and calculates a
cross spatial metric as implemented by spatstat per field of view for all
combinations provided by the user.
calcCrossMetricPerFov( spe, selection, subsetby = NULL, fun, marks = NULL, rSeq = NULL, by = NULL, ncores = 1, continuous = FALSE, assay = "exprs", ... )calcCrossMetricPerFov( spe, selection, subsetby = NULL, fun, marks = NULL, rSeq = NULL, by = NULL, ncores = 1, continuous = FALSE, assay = "exprs", ... )
spe |
a |
selection |
the mark(s) you want to compare |
subsetby |
the spe |
fun |
the |
marks |
the marks to consider e.g. cell types |
rSeq |
the range of r values to compute the function over |
by |
the spe |
ncores |
the number of cores to use for parallel processing, default = 1 |
continuous |
A boolean indicating whether the marks are continuous defaults to FALSE |
assay |
the assay which is used if |
... |
Other parameters passed to spatstat.explore functions |
a dataframe of the spatstat metric objects with the radius r, the
theoretical value of a Poisson process, the different border corrections
the fov number, the number of points and the centroid of the image
# retrieve example data from Damond et al. (2019) spe <- .loadExample() metricRes <- calcCrossMetricPerFov(spe, c("alpha", "Tc"), subsetby = "image_number", fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), by = c( "patient_stage", "patient_id", "image_number" ), ncores = 1 )# retrieve example data from Damond et al. (2019) spe <- .loadExample() metricRes <- calcCrossMetricPerFov(spe, c("alpha", "Tc"), subsetby = "image_number", fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), by = c( "patient_stage", "patient_id", "image_number" ), ncores = 1 )
SpatialExperiment object per field of viewA function that takes a SpatialExperiment object as input and calculates a
spatial metric as implemented by spatstat per field of view.
calcMetricPerFov( spe, selection, subsetby, fun, marks = NULL, rSeq = NULL, by = NULL, continuous = FALSE, assay = "exprs", ncores = 1, verbose = TRUE, ... )calcMetricPerFov( spe, selection, subsetby, fun, marks = NULL, rSeq = NULL, by = NULL, continuous = FALSE, assay = "exprs", ncores = 1, verbose = TRUE, ... )
spe |
a |
selection |
the mark(s) you want to compare. NOTE: This is directional. c(A,B) is not the same result as c(B,A). |
subsetby |
the spe |
fun |
the |
marks |
the marks to consider e.g. cell types |
rSeq |
the range of r values to compute the function over |
by |
the spe |
continuous |
A boolean indicating whether the marks are continuous defaults to FALSE |
assay |
the assay which is used if |
ncores |
the number of cores to use for parallel processing, default = 1 |
verbose |
logical indicating whether to print all information or not |
... |
Other parameters passed to |
a dataframe of the spatstat metric objects with the radius r, the
theoretical value of a Poisson process, the different border corrections
the fov number, the number of points and the centroid of the image
# retrieve example data from Damond et al. (2019) spe <- .loadExample() metricRes <- calcMetricPerFov(spe, c("alpha", "Tc"), subsetby = "image_number", fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), by = c( "patient_stage", "patient_id", "image_number" ), ncores = 1 )# retrieve example data from Damond et al. (2019) spe <- .loadExample() metricRes <- calcMetricPerFov(spe, c("alpha", "Tc"), subsetby = "image_number", fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), by = c( "patient_stage", "patient_id", "image_number" ), ncores = 1 )
Coef for functionalGam object
## S3 method for class 'functionalGam' coef(object, ...)## S3 method for class 'functionalGam' coef(object, ...)
object |
a fitted |
... |
see |
coefficicents of the model, see coef.pffr()
Martin Emons, adapted from coef.pffr() by Fabian Scheipl
This function is a wrappere function around spatialInference. It calculates
spatialInference results either for all cell types in marks
(if selection == NULL) or for a custom subset defined in selection.
crossSpatialInference( spe, selection = NULL, fun, marks = NULL, rSeq = NULL, correction, sample_id, image_id, condition, continuous = FALSE, assay = "exprs", transformation = NULL, eps = 0.001, delta = "minNnDist", family = stats::gaussian(link = "log"), verbose = TRUE, ncores = 1, ... )crossSpatialInference( spe, selection = NULL, fun, marks = NULL, rSeq = NULL, correction, sample_id, image_id, condition, continuous = FALSE, assay = "exprs", transformation = NULL, eps = 0.001, delta = "minNnDist", family = stats::gaussian(link = "log"), verbose = TRUE, ncores = 1, ... )
spe |
a |
selection |
the mark(s) you want to compare. NOTE: This is directional. c(A,B) is not the same result as c(B,A). |
fun |
the |
marks |
the marks to consider e.g. cell types |
rSeq |
the range of r values to compute the function over |
correction |
the edge correction to be applied |
sample_id |
the spe |
image_id |
the spe |
condition |
the spe |
continuous |
A boolean indicating whether the marks are continuous defaults to FALSE |
assay |
the assay which is used if |
transformation |
the transformation to be applied as exponential e.g. 1/2 for sqrt |
eps |
some distributional families fail if the response is zero, therefore, zeros can be replaced with a very small value eps |
delta |
the delta value to remove from the beginning of the spatial statistics functions. Can be reasonable if e.g. cells are always spaced by 10 µm. If set to "minNnDist" it will take the mean of the minimum nearest neighbour distance across all images for this cell type pair. |
family |
the distributional family for the functional GAM |
verbose |
logical indicating whether to print all information or not |
ncores |
the number of cores to use for parallel processing, default = 1 |
... |
Other parameters passed to |
a list of objects created by the function spatialInference
with three objects: i) the dataframe with the spatial
statistics results, ii) the designmatrix of the inference and iii) the
fitted pffr object
spe <- .loadExample() #make the condition a factor variable colData(spe)[["patient_stage"]] <- factor(colData(spe)[["patient_stage"]]) #relevel to have non-diabetic as the reference category colData(spe)[["patient_stage"]] <- relevel(colData(spe)[["patient_stage"]], "Non-diabetic") selection <- c("acinar", "ductal") resLs <- crossSpatialInference(spe, selection, fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), correction = "rs", sample_id = "patient_id", image_id = "image_number", condition = "patient_stage", algorithm = "bam", ncores = 1 )spe <- .loadExample() #make the condition a factor variable colData(spe)[["patient_stage"]] <- factor(colData(spe)[["patient_stage"]]) #relevel to have non-diabetic as the reference category colData(spe)[["patient_stage"]] <- relevel(colData(spe)[["patient_stage"]], "Non-diabetic") selection <- c("acinar", "ductal") resLs <- crossSpatialInference(spe, selection, fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), correction = "rs", sample_id = "patient_id", image_id = "image_number", condition = "patient_stage", algorithm = "bam", ncores = 1 )
Reshaping the Result of a Cross Spatial Inference to a Dataframe
extractCrossInferenceData( resLs, QCMetric = "medianMinIntensity", QCThreshold = 0.1 )extractCrossInferenceData( resLs, QCMetric = "medianMinIntensity", QCThreshold = 0.1 )
resLs |
a list with four objects: i) the dataframe with the spatial statistics results transformed and filtered as used for fitting, ii) the raw spatial statistics results, iii) the designmatrix of the inference and iv) the fitted pffr object v) the residual standard error per condition defined as the residual sum of squares divided by the number of datapoints - sum of the estimated degrees of freedom for the model parameters as well as other QC metrics |
QCMetric |
the metric to relate the quality of the fit too. |
QCThreshold |
the threshold on the QC metric. Depends on the function used. |
a dataframe for plotting with ggplot2
spe <- .loadExample() #make the condition a factor variable colData(spe)[["patient_stage"]] <- factor(colData(spe)[["patient_stage"]]) #relevel to have non-diabetic as the reference category colData(spe)[["patient_stage"]] <- relevel(colData(spe)[["patient_stage"]], "Non-diabetic") selection <- c("acinar", "ductal") resLs <- crossSpatialInference(spe, selection, fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), correction = "rs", sample_id = "patient_id", image_id = "image_number", condition = "patient_stage", algorithm = "bam", ncores = 1 ) df <- extractCrossInferenceData(resLs)spe <- .loadExample() #make the condition a factor variable colData(spe)[["patient_stage"]] <- factor(colData(spe)[["patient_stage"]]) #relevel to have non-diabetic as the reference category colData(spe)[["patient_stage"]] <- relevel(colData(spe)[["patient_stage"]], "Non-diabetic") selection <- c("acinar", "ductal") resLs <- crossSpatialInference(spe, selection, fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), correction = "rs", sample_id = "patient_id", image_id = "image_number", condition = "patient_stage", algorithm = "bam", ncores = 1 ) df <- extractCrossInferenceData(resLs)
A function that takes the output of a metric calculation as done by
calcMetricPerFov. The data has to be prepared into the correct format for
the functional analysis by the prepData function. The output is a pffr
object as implemented by refund.
functionalGam( data, x, designmat, weights, formula, family = stats::gaussian(link = "log"), algorithm = "bam", bs.yindex = list(bs = "ps", k = 5, m = c(2, 1)), bs.int = list(bs = "ps", k = 20, m = c(2, 1)), sandwich = "cluster", discrete = TRUE, ... )functionalGam( data, x, designmat, weights, formula, family = stats::gaussian(link = "log"), algorithm = "bam", bs.yindex = list(bs = "ps", k = 5, m = c(2, 1)), bs.int = list(bs = "ps", k = 20, m = c(2, 1)), sandwich = "cluster", discrete = TRUE, ... )
data |
a dataframe with the following columns: Y = functional response; sample_id = sample ID; image_id = image ID; |
x |
the x-axis values of the functional response |
designmat |
a design matrix as defined by model.matrix() |
weights |
weights as the number of points per image. These weights are normalised by the mean of the weights in the fitting process |
formula |
the formula for the model. The colnames of the designmatrix have to correspond to the variables in the formula. |
family |
the distributional family as implemented in
|
algorithm |
algorithm to fit the refund::pffr method. defaults to |
bs.yindex |
a list specifying the spline bases for the index. See |
bs.int |
a list specfying the spline bases for the global function intercept.
See |
sandwich |
string indicating how and if to adjust for heterscedasticity of the residuals with a sandwich correction |
discrete |
option to discretise the function for faster computation. default is
|
... |
Other parameters passed to |
a fitted pffr object which inherits from gam
# load the pancreas dataset library("tidyr") library("dplyr") # retrieve example data from Damond et al. (2019) spe <- .loadExample() # calculate the Gcross metric for alpha and Tc cells metricRes <- calcMetricPerFov(spe, c("alpha", "Tc"), subsetby = "image_number", fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), c("patient_stage", "patient_id", "image_number"), ncores = 1 ) metricRes$ID <- paste0( metricRes$patient_stage, "|", metricRes$patient_id, "|", metricRes$image_number ) dat <- prepData(metricRes, "r", "rs", sample_id = "patient_id", image_id = "image_number", condition = "patient_stage") #' # drop rows with NA dat <- dat |> drop_na() # create a designmatrix condition <- dat$patient_stage # relevel the condition - can set explicit contrasts here condition <- relevel(condition, "Non-diabetic") designmat <- model.matrix(~condition) # colnames don't work with the '-' sign colnames(designmat) <- c( "(Intercept)", "conditionLong_duration", "conditionOnset" ) # fit the model mdl <- functionalGam( data = dat, x = metricRes$r |> unique(), designmat = designmat, weights = dat$npoints, formula = formula(Y ~ conditionLong_duration + conditionOnset + s(patient_id, bs = "re")), algorithm = "bam" ) summary(mdl)# load the pancreas dataset library("tidyr") library("dplyr") # retrieve example data from Damond et al. (2019) spe <- .loadExample() # calculate the Gcross metric for alpha and Tc cells metricRes <- calcMetricPerFov(spe, c("alpha", "Tc"), subsetby = "image_number", fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), c("patient_stage", "patient_id", "image_number"), ncores = 1 ) metricRes$ID <- paste0( metricRes$patient_stage, "|", metricRes$patient_id, "|", metricRes$image_number ) dat <- prepData(metricRes, "r", "rs", sample_id = "patient_id", image_id = "image_number", condition = "patient_stage") #' # drop rows with NA dat <- dat |> drop_na() # create a designmatrix condition <- dat$patient_stage # relevel the condition - can set explicit contrasts here condition <- relevel(condition, "Non-diabetic") designmat <- model.matrix(~condition) # colnames don't work with the '-' sign colnames(designmat) <- c( "(Intercept)", "conditionLong_duration", "conditionOnset" ) # fit the model mdl <- functionalGam( data = dat, x = metricRes$r |> unique(), designmat = designmat, weights = dat$npoints, formula = formula(Y ~ conditionLong_duration + conditionOnset + s(patient_id, bs = "re")), algorithm = "bam" ) summary(mdl)
A function that takes as input the output of calcMetricPerFov which has to
be converted into the correct format by prepData. The output is a list with
the fpca.face output from refund.
functionalPCA(data, r, ...)functionalPCA(data, r, ...)
data |
a data object for functional data analysis containing at least the functional response $Y$. |
r |
the functional domain |
... |
Other parameters passed to |
a list with components of fpca.sc
# load the pancreas dataset library("tidyr") library("stringr") library("dplyr") # retrieve example data from Damond et al. (2019) spe <- .loadExample() # calculate the Gcross metric for alpha and Tc cells metricRes <- calcMetricPerFov(spe, c("alpha", "Tc"), subsetby = "image_number", fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), c("patient_stage", "patient_id", "image_number"), ncores = 1 ) metricRes$ID <- paste0( metricRes$patient_stage, "|", metricRes$patient_id, "|", metricRes$image_number ) # prepare data for FDA dat <- prepData(metricRes, "r", "rs") # drop rows with NA dat <- dat |> drop_na() # create meta info of the IDs splitData <- str_split(dat$ID, "x") dat$condition <- factor(sapply(splitData, function(x) x[1])) dat$patient_id <- factor(sapply(splitData, function(x) x[2])) dat$image_id <- factor(sapply(splitData, function(x) x[3])) # calculate fPCA mdl <- functionalPCA( data = dat, r = metricRes$r |> unique() )# load the pancreas dataset library("tidyr") library("stringr") library("dplyr") # retrieve example data from Damond et al. (2019) spe <- .loadExample() # calculate the Gcross metric for alpha and Tc cells metricRes <- calcMetricPerFov(spe, c("alpha", "Tc"), subsetby = "image_number", fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), c("patient_stage", "patient_id", "image_number"), ncores = 1 ) metricRes$ID <- paste0( metricRes$patient_stage, "|", metricRes$patient_id, "|", metricRes$image_number ) # prepare data for FDA dat <- prepData(metricRes, "r", "rs") # drop rows with NA dat <- dat |> drop_na() # create meta info of the IDs splitData <- str_split(dat$ID, "x") dat$condition <- factor(sapply(splitData, function(x) x[1])) dat$patient_id <- factor(sapply(splitData, function(x) x[2])) dat$image_id <- factor(sapply(splitData, function(x) x[3])) # calculate fPCA mdl <- functionalPCA( data = dat, r = metricRes$r |> unique() )
Helper function for plotCrossMetricPerFov. It applies plotMetricPerFov
to all n marks defined in the variable selection. This gives an
nxn plot of all marks.
plotCrossFOV( subFov, theo, correction, x, imageId, ID = NULL, ncol = NULL, nrow = NULL, legend.position = "none", ... )plotCrossFOV( subFov, theo, correction, x, imageId, ID = NULL, ncol = NULL, nrow = NULL, legend.position = "none", ... )
subFov |
a subset of the |
theo |
logical; if the theoretical line should be plotted |
correction |
the border correction to plot |
x |
the x-axis variable to plot |
imageId |
the ID of the image/fov |
ID |
the (optional) ID for plotting combinations |
ncol |
the number of columns for the facet wrap |
nrow |
the number of rows for the facet wrap |
legend.position |
the position of the legend of the plot |
... |
Other parameters passed to |
a ggplot object
Plotting the Result of a Cross Spatial Inference
plotCrossHeatmap( resLs, adj.pvalue = "BH", coefficientsToPlot = NULL, QCThreshold = 1e-05, QCMetric = "medianMinIntensity", ... )plotCrossHeatmap( resLs, adj.pvalue = "BH", coefficientsToPlot = NULL, QCThreshold = 1e-05, QCMetric = "medianMinIntensity", ... )
resLs |
a list with four objects: i) the dataframe with the spatial statistics results transformed and filtered as used for fitting, ii) the raw spatial statistics results, iii) the designmatrix of the inference and iv) the fitted pffr object v) the residual standard error per condition defined as the residual sum of squares divided by the number of datapoints - sum of the estimated degrees of freedom for the model parameters as well as other QC metrics |
adj.pvalue |
a pvalue adjustment method as passed to stats::p.adjust defaults to Benjamini-Hochberg correction of the false discovery rate. |
coefficientsToPlot |
list of which coefficients to plot in the heatmap defaults to NULL in which case all coefficients are plotted |
QCThreshold |
the threshold on the Quality control metric. Depends on the function used. |
QCMetric |
the metric to relate the quality of the fit too. |
... |
other parameters passed to |
a ggplot2 object
spe <- .loadExample() #make the condition a factor variable colData(spe)[["patient_stage"]] <- factor(colData(spe)[["patient_stage"]]) #relevel to have non-diabetic as the reference category colData(spe)[["patient_stage"]] <- relevel(colData(spe)[["patient_stage"]], "Non-diabetic") selection <- c("acinar", "ductal") resLs <- crossSpatialInference(spe, selection, fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), correction = "rs", sample_id = "patient_id", image_id = "image_number", condition = "patient_stage", algorithm = "bam", ncores = 1 ) p <- plotCrossHeatmap(resLs, adj.pvalue = "BH")spe <- .loadExample() #make the condition a factor variable colData(spe)[["patient_stage"]] <- factor(colData(spe)[["patient_stage"]]) #relevel to have non-diabetic as the reference category colData(spe)[["patient_stage"]] <- relevel(colData(spe)[["patient_stage"]], "Non-diabetic") selection <- c("acinar", "ductal") resLs <- crossSpatialInference(spe, selection, fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), correction = "rs", sample_id = "patient_id", image_id = "image_number", condition = "patient_stage", algorithm = "bam", ncores = 1 ) p <- plotCrossHeatmap(resLs, adj.pvalue = "BH")
This function plots the cross function between two marks output from
calcMetricPerFov. It wraps around helper function and applies this
function to all samples.
plotCrossMetricPerFov( metricDf, theo = NULL, correction = NULL, x = NULL, imageId = NULL, ID = NULL, nrow = NULL, ncol = NULL, legend.position = "none", ... )plotCrossMetricPerFov( metricDf, theo = NULL, correction = NULL, x = NULL, imageId = NULL, ID = NULL, nrow = NULL, ncol = NULL, legend.position = "none", ... )
metricDf |
the metric dataframe as calculated by |
theo |
logical; if the theoretical line should be plotted |
correction |
the border correction to plot |
x |
the x-axis variable to plot |
imageId |
the ID of the image/fov |
ID |
the (optional) ID for plotting combinations |
nrow |
the number of rows for the facet wrap |
ncol |
the number of columns for the facet wrap |
legend.position |
the position of the legend of the plot |
... |
Other parameters passed to |
a ggplot object
# retrieve example data from Damond et al. (2019) spe <- .loadExample() metricRes <- calcCrossMetricPerFov(spe, c("alpha", "Tc"), subsetby = "image_number", fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), by = c( "patient_stage", "patient_id", "image_number" ), ncores = 1 ) metricRes$ID <- paste0( metricRes$patient_stage, "|", metricRes$patient_id ) metricRes <- subset(metricRes, image_number %in% c(138, 139, 140)) p <- plotCrossMetricPerFov(metricRes, theo = TRUE, correction = "rs", x = "r", imageId = "image_number", ID = "ID" ) print(p)# retrieve example data from Damond et al. (2019) spe <- .loadExample() metricRes <- calcCrossMetricPerFov(spe, c("alpha", "Tc"), subsetby = "image_number", fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), by = c( "patient_stage", "patient_id", "image_number" ), ncores = 1 ) metricRes$ID <- paste0( metricRes$patient_stage, "|", metricRes$patient_id ) metricRes <- subset(metricRes, image_number %in% c(138, 139, 140)) p <- plotCrossMetricPerFov(metricRes, theo = TRUE, correction = "rs", x = "r", imageId = "image_number", ID = "ID" ) print(p)
This function creates a functional boxplot of the spatial statistics curves. It creates one functional boxplot per aggregation category, e.g. condition.
plotFbPlot(metricDf, x, y, aggregateBy)plotFbPlot(metricDf, x, y, aggregateBy)
metricDf |
the metric dataframe as calculated by |
x |
the name of the x-axis of the spatial metric |
y |
the name of the y-axis of the spatial metric |
aggregateBy |
the criterion by which to aggregate the curves into a functional boxplot. Can be e.g. the condition of the different samples. |
a list of base R plots
# retrieve example data from Damond et al. (2019) spe <- .loadExample() metricRes <- calcMetricPerFov(spe, c("alpha", "Tc"), subsetby = "image_number", fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), by = c( "patient_stage", "patient_id", "image_number" ), ncores = 1 ) # create a unique ID for the data preparation metricRes$ID <- paste0( metricRes$patient_stage, "|", metricRes$patient_id, "|", metricRes$image_number ) plotFbPlot(metricRes, 'r', 'rs', 'patient_stage')# retrieve example data from Damond et al. (2019) spe <- .loadExample() metricRes <- calcMetricPerFov(spe, c("alpha", "Tc"), subsetby = "image_number", fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), by = c( "patient_stage", "patient_id", "image_number" ), ncores = 1 ) # create a unique ID for the data preparation metricRes$ID <- paste0( metricRes$patient_stage, "|", metricRes$patient_id, "|", metricRes$image_number ) plotFbPlot(metricRes, 'r', 'rs', 'patient_stage')
A function that takes the output from the functionalPCA function and
returns a ggplot object of the first two dimensions of the PCA as biplot.
plotFpca(data, res, colourby = NULL, labelby = NULL)plotFpca(data, res, colourby = NULL, labelby = NULL)
data |
a data object for functional data analysis containing at least the functional response $Y$. |
res |
the output from the fPCA calculation |
colourby |
the variable by which to colour the PCA plot by |
labelby |
the variable by which to label the PCA plot by |
a list with components of fpca.face
# load the pancreas dataset library("tidyr") library("stringr") library("dplyr") # retrieve example data from Damond et al. (2019) spe <- .loadExample() # calculate the Gcross metric for alpha and beta cells metricRes <- calcMetricPerFov(spe, c("alpha", "beta"), subsetby = "image_number", fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), c("patient_stage", "patient_id", "image_number"), ncores = 1 ) metricRes$ID <- paste0( metricRes$patient_stage, "|", metricRes$patient_id, "|", metricRes$image_number ) # prepare data for FDA dat <- prepData(metricRes, "r", "rs") # drop rows with NA dat <- dat |> drop_na() # create meta info of the IDs splitData <- str_split(dat$ID, "|") dat$condition <- factor(sapply(splitData, function(x) x[1])) dat$patient_id <- factor(sapply(splitData, function(x) x[2])) dat$image_id <- factor(sapply(splitData, function(x) x[3])) # calculate fPCA mdl <- functionalPCA( data = dat, r = metricRes$r |> unique() ) p <- plotFpca( data = dat, res = mdl, colourby = "condition", labelby = "patient_id" ) print(p)# load the pancreas dataset library("tidyr") library("stringr") library("dplyr") # retrieve example data from Damond et al. (2019) spe <- .loadExample() # calculate the Gcross metric for alpha and beta cells metricRes <- calcMetricPerFov(spe, c("alpha", "beta"), subsetby = "image_number", fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), c("patient_stage", "patient_id", "image_number"), ncores = 1 ) metricRes$ID <- paste0( metricRes$patient_stage, "|", metricRes$patient_id, "|", metricRes$image_number ) # prepare data for FDA dat <- prepData(metricRes, "r", "rs") # drop rows with NA dat <- dat |> drop_na() # create meta info of the IDs splitData <- str_split(dat$ID, "|") dat$condition <- factor(sapply(splitData, function(x) x[1])) dat$patient_id <- factor(sapply(splitData, function(x) x[2])) dat$image_id <- factor(sapply(splitData, function(x) x[3])) # calculate fPCA mdl <- functionalPCA( data = dat, r = metricRes$r |> unique() ) p <- plotFpca( data = dat, res = mdl, colourby = "condition", labelby = "patient_id" ) print(p)
A function that takes a pffr object as calculated in functionalGam and
plots the functional coefficients. The functions are centered such that their
expected value is zero. Therefore, the scalar intercept has to be added to
the output with the argument shift in order to plot the coefficients in
their original range.
plotMdl(mdl, predictor, shift = NULL)plotMdl(mdl, predictor, shift = NULL)
mdl |
a |
predictor |
predictor to plot |
shift |
the value by which to shift the centered functional intercept. this will most often be the constant intercept |
ggplot object of the functional estimate
library("tidyr") library("stringr") library("dplyr") # retrieve example data from Damond et al. (2019) spe <- .loadExample() metricRes <- calcMetricPerFov(spe, c("alpha", "Tc"), subsetby = "image_number", fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), by = c( "patient_stage", "patient_id", "image_number" ), ncores = 1 ) # create a unique ID for each row metricRes$ID <- paste0( metricRes$patient_stage, "x", metricRes$patient_id, "x", metricRes$image_number ) dat <- prepData(metricRes, "r", "rs", sample_id = "patient_id", image_id = "image_number", condition = "patient_stage") #' # drop rows with NA dat <- dat |> drop_na() # create a designmatrix condition <- dat$patient_stage # relevel the condition - can set explicit contrasts here condition <- relevel(condition, "Non-diabetic") designmat <- model.matrix(~condition) # colnames don't work with the '-' sign colnames(designmat) <- c( "(Intercept)", "conditionLong_duration", "conditionOnset" ) # fit the model mdl <- functionalGam( data = dat, x = metricRes$r |> unique(), designmat = designmat, weights = dat$npoints, formula = formula(Y ~ conditionLong_duration + conditionOnset + s(patient_id, bs = "re")), algorithm = "bam" ) summary(mdl, re.test = FALSE) plotLs <- lapply(colnames(designmat), plotMdl, mdl = mdl, shift = mdl$coefficients[["(Intercept)"]] )library("tidyr") library("stringr") library("dplyr") # retrieve example data from Damond et al. (2019) spe <- .loadExample() metricRes <- calcMetricPerFov(spe, c("alpha", "Tc"), subsetby = "image_number", fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), by = c( "patient_stage", "patient_id", "image_number" ), ncores = 1 ) # create a unique ID for each row metricRes$ID <- paste0( metricRes$patient_stage, "x", metricRes$patient_id, "x", metricRes$image_number ) dat <- prepData(metricRes, "r", "rs", sample_id = "patient_id", image_id = "image_number", condition = "patient_stage") #' # drop rows with NA dat <- dat |> drop_na() # create a designmatrix condition <- dat$patient_stage # relevel the condition - can set explicit contrasts here condition <- relevel(condition, "Non-diabetic") designmat <- model.matrix(~condition) # colnames don't work with the '-' sign colnames(designmat) <- c( "(Intercept)", "conditionLong_duration", "conditionOnset" ) # fit the model mdl <- functionalGam( data = dat, x = metricRes$r |> unique(), designmat = designmat, weights = dat$npoints, formula = formula(Y ~ conditionLong_duration + conditionOnset + s(patient_id, bs = "re")), algorithm = "bam" ) summary(mdl, re.test = FALSE) plotLs <- lapply(colnames(designmat), plotMdl, mdl = mdl, shift = mdl$coefficients[["(Intercept)"]] )
A function that plots the output of the function calcMetricPerFov. The plot
contains one curve per FOV and makes subplots by samples.
plotMetricPerFov( metricDf, theo = FALSE, correction = NULL, x = NULL, imageId = NULL, ID = NULL, nrow = NULL, ncol = NULL, legend.position = "none", ... )plotMetricPerFov( metricDf, theo = FALSE, correction = NULL, x = NULL, imageId = NULL, ID = NULL, nrow = NULL, ncol = NULL, legend.position = "none", ... )
metricDf |
the metric |
theo |
logical; if the theoretical line should be plotted |
correction |
the border correction to plot |
x |
the x-axis variable to plot |
imageId |
the ID of the image/fov |
ID |
the (optional) ID for plotting combinations |
nrow |
the number of rows for the facet wrap |
ncol |
the number of columns for the facet wrap |
legend.position |
the position of the legend of the plot |
... |
Other parameters passed to |
a ggplot object
# retrieve example data from Damond et al. (2019) spe <- .loadExample() metricRes <- calcMetricPerFov(spe, c("alpha", "Tc"), subsetby = "image_number", fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), by = c( "patient_stage", "patient_id", "image_number" ), ncores = 1 ) # ceate a unique plotting ID metricRes$ID <- paste0( metricRes$patient_stage, "|", metricRes$patient_id ) p <- plotMetricPerFov(metricRes, correction = "rs", x = "r", imageId = "image_number", ID = "ID" ) print(p)# retrieve example data from Damond et al. (2019) spe <- .loadExample() metricRes <- calcMetricPerFov(spe, c("alpha", "Tc"), subsetby = "image_number", fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), by = c( "patient_stage", "patient_id", "image_number" ), ncores = 1 ) # ceate a unique plotting ID metricRes$ID <- paste0( metricRes$patient_stage, "|", metricRes$patient_id ) p <- plotMetricPerFov(metricRes, correction = "rs", x = "r", imageId = "image_number", ID = "ID" ) print(p)
Prepare data from calcMetricRes to be in the right format for FDA
prepData(metricRes, x, y, sample_id = NULL, image_id = NULL, condition = NULL)prepData(metricRes, x, y, sample_id = NULL, image_id = NULL, condition = NULL)
metricRes |
a dataframe as calculated by calcMetricRes - requires the columns ID (unique identifier of each row) |
x |
the name of the x-axis of the spatial metric |
y |
the name of the y-axis of the spatial metric |
sample_id |
the spe |
image_id |
the spe |
condition |
the spe |
returns a list with three entries, the unique ID, the functional response Y and the weights
# retrieve example data from Damond et al. (2019) spe <- .loadExample() metricRes <- calcMetricPerFov(spe, c("alpha", "Tc"), subsetby = "image_number", fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), by = c( "patient_stage", "patient_id", "image_number" ), ncores = 1 ) # create a unique ID for each row metricRes$ID <- paste0( metricRes$patient_stage, "|", metricRes$patient_id, "|", metricRes$image_number ) dat <- prepData(metricRes, "r", "rs", sample_id = "patient_id", image_id = "image_number", condition = "patient_stage")# retrieve example data from Damond et al. (2019) spe <- .loadExample() metricRes <- calcMetricPerFov(spe, c("alpha", "Tc"), subsetby = "image_number", fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), by = c( "patient_stage", "patient_id", "image_number" ), ncores = 1 ) # create a unique ID for each row metricRes$ID <- paste0( metricRes$patient_stage, "|", metricRes$patient_id, "|", metricRes$image_number ) dat <- prepData(metricRes, "r", "rs", sample_id = "patient_id", image_id = "image_number", condition = "patient_stage")
this is a function that prints a summary of the fPCA result of class fpca
## S3 method for class 'fpca' print(x, ...)## S3 method for class 'fpca' print(x, ...)
x |
the result of function |
... |
other parameters passed to base generic function |
a formatted overview of the fPCA result
# load the pancreas dataset library("tidyr") library("stringr") library("dplyr") # retrieve example data from Damond et al. (2019) spe <- .loadExample() # calculate the Gcross metric for alpha and beta cells metricRes <- calcMetricPerFov(spe, c("alpha", "beta"), subsetby = "image_number", fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), c("patient_stage", "patient_id", "image_number"), ncores = 1 ) metricRes$ID <- paste0( metricRes$patient_stage, "|", metricRes$patient_id, "|", metricRes$image_number ) # prepare data for FDA dat <- prepData(metricRes, "r", "rs") # drop rows with NA dat <- dat |> drop_na() # create meta info of the IDs splitData <- strsplit(dat$ID, "|", fixed = TRUE) dat$condition <- factor(sapply(splitData, function(x) x[1])) dat$patient_id <- factor(sapply(splitData, function(x) x[2])) dat$image_id <- factor(sapply(splitData, function(x) x[3])) # calculate fPCA mdl <- functionalPCA( data = dat, r = metricRes$r |> unique() ) mdl# load the pancreas dataset library("tidyr") library("stringr") library("dplyr") # retrieve example data from Damond et al. (2019) spe <- .loadExample() # calculate the Gcross metric for alpha and beta cells metricRes <- calcMetricPerFov(spe, c("alpha", "beta"), subsetby = "image_number", fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), c("patient_stage", "patient_id", "image_number"), ncores = 1 ) metricRes$ID <- paste0( metricRes$patient_stage, "|", metricRes$patient_id, "|", metricRes$image_number ) # prepare data for FDA dat <- prepData(metricRes, "r", "rs") # drop rows with NA dat <- dat |> drop_na() # create meta info of the IDs splitData <- strsplit(dat$ID, "|", fixed = TRUE) dat$condition <- factor(sapply(splitData, function(x) x[1])) dat$patient_id <- factor(sapply(splitData, function(x) x[2])) dat$image_id <- factor(sapply(splitData, function(x) x[3])) # calculate fPCA mdl <- functionalPCA( data = dat, r = metricRes$r |> unique() ) mdl
Heuristic for the choice of rMax
rMaxHeuristic(spe, subsetby, marks)rMaxHeuristic(spe, subsetby, marks)
spe |
a |
subsetby |
the spe |
marks |
the marks to consider e.g. cell types |
a ggplot histogram of the bounding radius of all the
# retrieve example data from Damond et al. (2019) spe <- .loadExample() p <- rMaxHeuristic(spe, subsetby = "image_number", marks = "cell_type" )# retrieve example data from Damond et al. (2019) spe <- .loadExample() p <- rMaxHeuristic(spe, subsetby = "image_number", marks = "cell_type" )
A function to perform spatial statistical inference on spatial omics data. This function works so far only on functions of radius "r".
spatialInference( spe, selection, fun, marks = NULL, rSeq = NULL, correction, sample_id, image_id, condition, continuous = FALSE, assay = "exprs", transformation = NULL, weights = "total", eps = 0.001, delta = "minNnDist", family = stats::gaussian(link = "log"), verbose = TRUE, upperDeltaProb = NULL, weightTransform = TRUE, AR1 = FALSE, sandwich = "cluster", ncores = 1, algorithm = "bam", ... )spatialInference( spe, selection, fun, marks = NULL, rSeq = NULL, correction, sample_id, image_id, condition, continuous = FALSE, assay = "exprs", transformation = NULL, weights = "total", eps = 0.001, delta = "minNnDist", family = stats::gaussian(link = "log"), verbose = TRUE, upperDeltaProb = NULL, weightTransform = TRUE, AR1 = FALSE, sandwich = "cluster", ncores = 1, algorithm = "bam", ... )
spe |
a |
selection |
the mark(s) you want to compare. NOTE: This is directional. c(A,B) is not the same result as c(B,A). |
fun |
the |
marks |
the marks to consider e.g. cell types |
rSeq |
the range of r values to compute the function over |
correction |
the edge correction to be applied |
sample_id |
the spe |
image_id |
the spe |
condition |
the spe |
continuous |
A boolean indicating whether the marks are continuous defaults to FALSE |
assay |
the assay which is used if |
transformation |
the transformation to be applied as exponential e.g. 1/2 for sqrt or Fisher's variance-stabilising transformation if "Fisher" |
weights |
the weighting to be applied to the functional GAM. Either NULL (equal weights), total (npoints of total pattern), min (npoints of the smaller subpattern) or max (npoints of the larger subpattern) or a user defined value of same length as the number of curves to be estimated |
eps |
some distributional families fail if the response is zero, therefore, zeros can be replaced with a very small value eps |
delta |
the delta value to remove from the beginning of the spatial statistics functions. Can be reasonable if e.g. cells are always spaced by 10 µm. If set to "minNnDist" it will take the mean of the minimum nearest neighbour distance across all images for this cell type pair. |
family |
the distributional family for the functional GAM |
verbose |
logical indicating whether to print all information or not |
upperDeltaProb |
the quantile to filter out the constant 1 part for |
weightTransform |
logical indicating whether the weights (number of points) should be sqrt transformed |
AR1 |
logical indicating whether to calculate the autocorrelation of the residuals along the domain and account for this in a second fitting step |
sandwich |
string indicating how and if to adjust for heterscedasticity of the residuals with a sandwich correction |
ncores |
the number of cores to use for parallel processing, default = 1 |
algorithm |
algorithm to fit the refund::pffr method. defaults to |
... |
Other parameters passed to |
a list with four objects: i) the dataframe with the spatial statistics results transformed and filtered as used for fitting, ii) the raw spatial statistics results, iii) the designmatrix of the inference and iv) the fitted pffr object v) the residual standard error per condition defined as the residual sum of squares divided by the number of datapoints - sum of the estimated degrees of freedom for the model parameters as well as other QC metrics
spe <- .loadExample() #make the condition a factor variable colData(spe)[["patient_stage"]] <- factor(colData(spe)[["patient_stage"]]) #relevel to have non-diabetic as the reference category colData(spe)[["patient_stage"]] <- relevel(colData(spe)[["patient_stage"]], "Non-diabetic") res <- spatialInference(spe, c("alpha", "Tc"), fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), correction = "rs", sample_id = "patient_id", image_id = "image_number", condition = "patient_stage", ncores = 1, algorithm = "bam" )spe <- .loadExample() #make the condition a factor variable colData(spe)[["patient_stage"]] <- factor(colData(spe)[["patient_stage"]]) #relevel to have non-diabetic as the reference category colData(spe)[["patient_stage"]] <- relevel(colData(spe)[["patient_stage"]], "Non-diabetic") res <- spatialInference(spe, c("alpha", "Tc"), fun = "Gcross", marks = "cell_type", rSeq = seq(0, 50, length.out = 50), correction = "rs", sample_id = "patient_id", image_id = "image_number", condition = "patient_stage", ncores = 1, algorithm = "bam" )
Summary for functionalGam object
## S3 method for class 'functionalGam' summary(object, ...)## S3 method for class 'functionalGam' summary(object, ...)
object |
a fitted |
... |
see |
A list with summary information, see summary.gam()
Martin Emons, adapted from summary.pffr() by Fabian Scheipl