Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

replace minDistToCells by distToCells #125

Open
wants to merge 1 commit into
base: devel
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ export(buildSpatialGraph)
export(countInteractions)
export(detectCommunity)
export(detectSpatialContext)
export(distToCells)
export(filterPixels)
export(filterSpatialContext)
export(findBorderCells)
export(minDistToCells)
export(patchDetection)
export(patchSize)
export(plotSpatial)
Expand All @@ -30,6 +30,9 @@ importFrom(BiocParallel,SerialParam)
importFrom(BiocParallel,bplapply)
importFrom(DT,datatable)
importFrom(EBImage,Image)
importFrom(MatrixGenerics,rowMaxs)
importFrom(MatrixGenerics,rowMeans)
importFrom(MatrixGenerics,rowMedians)
importFrom(MatrixGenerics,rowMins)
importFrom(RTriangle,pslg)
importFrom(RTriangle,triangulate)
Expand Down
113 changes: 57 additions & 56 deletions R/minDistToCells.R → R/distToCells.R
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#' @title Function to calculate minimal distance to cells of interest
#'
#' @description Function to return the distance of the closest cell of interest
#' @title Function to calculate distance to cells of interest
#'
#' @description Function to return the min, max, mean or median distance to the cells of interest
#' for each cell in the data. In the case of patched/clustered cells negative
#' distances are returned by default which indicate the distance of the cells
#' of interest to the closest cell that is not of the type of cells of
#' of interest to the cells that are not of the type of cells of
#' interest.
#'
#' @param object a \code{SingleCellExperiment} or \code{SpatialExperiment}
Expand All @@ -13,6 +13,8 @@
#' distances will be calculated.
#' @param name character specifying the name of the \code{colData} entry to safe
#' the distances in.
#' @param metric one of "min", "max", "mean" or "meadian" specifying the distance metric to use when computing
#' the distances.
brunopalau marked this conversation as resolved.
Show resolved Hide resolved
#' @param coords character vector of length 2 specifying the names of the
#' \code{colData} (for a \code{SingleCellExperiment} object) or the
#' \code{spatialCoords} entries of the cells' x and y locations.
Expand All @@ -22,26 +24,26 @@
#' returned for the distances of patched/spatially clustered cells.
#' @param BPPARAM a \code{\link[BiocParallel]{BiocParallelParam-class}} object
#' defining how to parallelize computations.
#'
#'
#' @section Ordering of the output object:
#' The \code{minDistToCells} function operates on individual images.
#' Therefore the returned object is grouped by entries in \code{img_id}.
#' Therefore the returned object is grouped by entries in \code{img_id}.
#' This means all cells of a given image are grouped together in the object.
#' The ordering of cells within each individual image is the same as the ordering
#' of these cells in the input object.
#'
#' @return returns an object of \code{class(object)} containing a new column
#'
#' @return returns an object of \code{class(object)} containing a new column
#' entry to \code{colData(object)[[name]]}. Cells in the object are grouped
#' by entries in \code{img_id}.
#'
#'
#' @examples
#' library(cytomapper)
#' data(pancreasSCE)
#'
#'
#' # Build interaction graph
#' pancreasSCE <- buildSpatialGraph(pancreasSCE, img_id = "ImageNb",
#' type = "expansion",threshold = 20)
#'
#'
#' # Detect patches of "celltype_B" cells
#' pancreasSCE <- patchDetection(pancreasSCE,
#' img_id = "ImageNb",
Expand All @@ -50,86 +52,85 @@
#' min_patch_size = 20,
#' expand_by = 1)
#'
#' plotSpatial(pancreasSCE,
#' img_id = "ImageNb",
#' plotSpatial(pancreasSCE,
#' img_id = "ImageNb",
#' node_color_by = "patch_id",
#' scales = "free")
#'
#' # Distance to celltype_B patches
#' pancreasSCE <- minDistToCells(pancreasSCE,
#' pancreasSCE <- distToCells(pancreasSCE,
#' x_cells = !is.na(pancreasSCE$patch_id),
#' coords = c("Pos_X","Pos_Y"),
#' metric = "min",
#' img_id = "ImageNb")
#'
#' plotSpatial(pancreasSCE,
#' img_id = "ImageNb",
#' node_color_by = "distToCells",
#' scales = "free")
#'
#' @author Daniel Schulz (\email{daniel.schulz@@uzh.ch})
#' @author Daniel Schulz & Bruno Palau (\email{daniel.schulz@@uzh.ch})
#' @importFrom distances distances distance_columns
brunopalau marked this conversation as resolved.
Show resolved Hide resolved
#' @importFrom MatrixGenerics rowMins
#' @importFrom MatrixGenerics rowMins rowMaxs rowMeans rowMedians
#' @export
minDistToCells <- function(object,
x_cells,
img_id,
name = "distToCells",
coords = c("Pos_X","Pos_Y"),
return_neg = TRUE,
BPPARAM = SerialParam()){

.valid.minDistToCells.input(object,x_cells,name,coords,img_id,return_neg)

distToCells <- function (object,
x_cells,
img_id,
name = "distToCells",
coords = c("Pos_X","Pos_Y"),
metric="min",
return_neg = TRUE,
BPPARAM = SerialParam()){
.valid.distToCells.input(object, x_cells, name, coords, metric,
img_id, return_neg)
cur_meta <- metadata(object)
metadata(object) <- list()

cur_intmeta <- int_metadata(object)

object$x_cells <- x_cells

cur_out <- bplapply(
unique(colData(object)[[img_id]]),
function(x){

cur_obj <- object[,as.character(colData(object)[[img_id]]) == x]

function(x) {
cur_obj <- object[, as.character(colData(object)[[img_id]]) == x]
cur_obj[[name]] <- NA
if (sum(cur_obj$x_cells) == 0 | sum(cur_obj$x_cells) == ncol(cur_obj)) {
if (sum(cur_obj$x_cells) == 0 | sum(cur_obj$x_cells) ==
ncol(cur_obj)) {
return(cur_obj)
}

patch_cells <- which(cur_obj$x_cells)
non_patch_cells <- which(!cur_obj$x_cells)

if (is(object, "SpatialExperiment")) {
dist_mat <- distances(spatialCoords(cur_obj))
} else {
dist_mat <- distances(as.matrix(colData(cur_obj)[,coords]))
}

pos_dist <- distance_columns(dist_mat,column_indices = patch_cells)
dist_to_patch <- rowMins(pos_dist)
neg_dist <- distance_columns(dist_mat,column_indices = non_patch_cells)
dist_from_patch <- rowMins(neg_dist)

# cells that had a 0 distance to the cells of interest can be substitutes
# with the negative distances from the cells of interest
if(return_neg == TRUE) {
dist_to_patch[dist_to_patch == 0] <- -dist_from_patch[dist_to_patch == 0]
else {
dist_mat <- distances::distances(as.matrix(colData(cur_obj)[,
coords]))
brunopalau marked this conversation as resolved.
Show resolved Hide resolved
}
pos_dist <- distance_columns(dist_mat, column_indices = patch_cells)
neg_dist <- distance_columns(dist_mat, column_indices = non_patch_cells)
dist_to_patch <- switch(metric,
mean = rowMeans(pos_dist),
median = rowMedians(pos_dist),
min = rowMins(pos_dist),
max = rowMaxs(pos_dist))


if (return_neg == TRUE) {
dist_from_patch <- switch(metric,
mean = rowMeans(neg_dist),
median = rowMedians(neg_dist),
min = rowMins(neg_dist),
max = rowMaxs(neg_dist))

dist_to_patch[cur_obj$x_cells] <- -dist_from_patch[cur_obj$x_cells]
}
cur_obj[[name]] <- dist_to_patch

brunopalau marked this conversation as resolved.
Show resolved Hide resolved
return(cur_obj)
}, BPPARAM = BPPARAM)

cur_out <- do.call("cbind", cur_out)

cur_out$x_cells <- NULL

metadata(cur_out) <- cur_meta
int_metadata(cur_out) <- cur_intmeta

message("The returned object is ordered by the '", img_id, "' entry.")

message("The returned object is ordered by the '", img_id,
"' entry.")
return(cur_out)
}
}
Loading
Loading