Skip to content

Commit

Permalink
subset and spdep updates
Browse files Browse the repository at this point in the history
- update `filterGiotto()` for updated `subsetGiotto()` in GiottoClass
- small updates to spdep.R
- remote spdep compatibility code from `evaluate_autocor_input()` since it is all performed in spdep.R
  • Loading branch information
jiajic committed Oct 4, 2023
1 parent 5d00e4e commit 48e7a71
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 75 deletions.
96 changes: 73 additions & 23 deletions R/auxiliary_giotto.R
Original file line number Diff line number Diff line change
Expand Up @@ -403,16 +403,22 @@ filterCombinations <- function(gobject,
#' @name filterGiotto
#' @description filter Giotto object based on expression threshold
#' @param gobject giotto object
#' @param spat_unit spatial unit
#' @param feat_type feature type
#' @param spat_unit character. spatial unit. If more than one is provided then
#' the first will be filtered, the filtering results will be applied across the
#' other spat_units provided
#' @param feat_type character. feature type. If more than one is provided then
#' the first will be filtered, the filtering results will be applied across the
#' other feat_types provided.
#' @param expression_values expression values to use
#' @param expression_threshold threshold to consider a gene expressed
#' @param feat_det_in_min_cells minimum # of cells that need to express a feature
#' @param min_det_feats_per_cell minimum # of features that need to be detected in a cell
#' @param all_spat_units apply features to remove filtering results from current
#' spatial unit/feature type combination across ALL spatial units (default = TRUE)
#' @param all_feat_types apply cells to remove filtering results from current
#' spatial unit/feature type combination across ALL feature types (default = TRUE)
#' @param all_spat_units deprecated. Use spat_unit_fsub = ":all:"
#' @param all_feat_types deprecated. Use feat_type_ssub = ":all:"
#' @param spat_unit_fsub character vector. (default = ':all:') limit features
#' to remove results to selected spat_units
#' @param feat_type_ssub character vector. (default = ':all:') limit cells to
#' remove results to selected feat_types
#' @param poly_info polygon information to use
#' @param tag_cells tag filtered cells in metadata vs. remove cells
#' @param tag_cell_name column name for tagged cells in metadata
Expand All @@ -435,8 +441,10 @@ filterGiotto = function(gobject,
expression_threshold = 1,
feat_det_in_min_cells = 100,
min_det_feats_per_cell = 100,
all_spat_units = TRUE,
all_feat_types = TRUE,
spat_unit_fsub = ":all:",
feat_type_ssub = ":all:",
all_spat_units = NULL,
all_feat_types = NULL,
poly_info = NULL,
tag_cells = FALSE,
tag_cell_name = 'tag',
Expand All @@ -447,6 +455,28 @@ filterGiotto = function(gobject,
# data.table vars
cell_ID = feat_ID = NULL

# handle deprecations
if (!is.null(all_spat_units)) {
if (all_spat_units) spat_unit_fsub = ":all:"
else spat_unit_fsub = spat_unit

warning(wrap_txt(
'filterGiotto:
all_spat_units param is deprecated.
Please use spat_unit_fsub = \":all:\" instead. (this is the default)'
))
}
if (!is.null(all_feat_types)) {
if (all_feat_types) feat_type_ssub = ":all:"
else feat_type_ssub = feat_type

warning(wrap_txt(
'filterGiotto:
all_feat_types param is deprecated.
Please use feat_type_ssub = \":all:\" instead. (this is the default)'
))
}


# Set feat_type and spat_unit
spat_unit = set_default_spat_unit(gobject = gobject,
Expand All @@ -459,15 +489,33 @@ filterGiotto = function(gobject,
poly_info = spat_unit
}

if (verbose && length(spat_unit) > 1L) {
wrap_msg("More than one spat_unit provided.\n",
paste0("[", spat_unit[[1L]], "]"),
"filtering results will be applied across spat_units:", spat_unit)
}
if (verbose && length(feat_type) > 1L) {
wrap_msg("More than one feat_type provided.\n",
paste0("[", feat_type[[1L]], "]"),
"filtering results will be applied across spat_units:", feat_type)
}


# expression values to be used
values = match.arg(expression_values, unique(c('raw', 'normalized', 'scaled', 'custom', expression_values)))

expr_values = get_expression_values(gobject = gobject,
spat_unit = spat_unit,
feat_type = feat_type,
values = values,
output = 'matrix')
# get expression values to perform filtering on
# Only the first spat_unit and feat_type provided are filtered.
# IF there are additional spat_units and feat_types provided, then the filtering
# results from this round will be applied to the other provided spat_units
# and feat_types as well.
expr_values = get_expression_values(
gobject = gobject,
spat_unit = spat_unit[[1L]],
feat_type = feat_type[[1L]],
values = values,
output = 'matrix'
)

# approach:
# 1. first remove genes that are not frequently detected
Expand Down Expand Up @@ -507,15 +555,17 @@ filterGiotto = function(gobject,


# update feature metadata
newGiottoObject = subsetGiotto(gobject = gobject,
feat_type = feat_type,
spat_unit = spat_unit,
cell_ids = selected_cell_ids,
feat_ids = selected_feat_ids,
all_spat_units = all_spat_units,
all_feat_types = all_feat_types,
poly_info = poly_info,
verbose = verbose)
newGiottoObject = subsetGiotto(
gobject = gobject,
feat_type = feat_type,
spat_unit = spat_unit,
cell_ids = selected_cell_ids,
feat_ids = selected_feat_ids,
spat_unit_fsub = spat_unit_fsub,
feat_type_ssub = feat_type_ssub,
poly_info = poly_info,
verbose = verbose
)

## print output ##
removed_feats = length(filter_index_feats[filter_index_feats == FALSE])
Expand All @@ -524,7 +574,7 @@ filterGiotto = function(gobject,
removed_cells = length(filter_index_cells[filter_index_cells == FALSE])
total_cells = length(filter_index_cells)

if(verbose == TRUE) {
if(isTRUE(verbose)) {
cat('\n')
cat('Feature type: ', feat_type, '\n')

Expand Down
8 changes: 0 additions & 8 deletions R/spatial_enrichment.R
Original file line number Diff line number Diff line change
Expand Up @@ -1950,7 +1950,6 @@ evaluate_autocor_input = function(gobject,
spat_unit,
feat_type,
feats,
method,
data_to_use,
expression_values,
meta_cols,
Expand All @@ -1961,8 +1960,6 @@ evaluate_autocor_input = function(gobject,
weight_matrix,
verbose = TRUE) {

package_check('spdep')

cell_ID = NULL

# 1. Get spatial network to either get or generate a spatial weight matrix
Expand Down Expand Up @@ -2068,11 +2065,6 @@ evaluate_autocor_input = function(gobject,
errWidth = TRUE))
}

## convert to listw for spdep
if(!inherits(weight_matrix, 'listw')) {
weight_matrix = spdep::mat2listw(weight_matrix)
}


# return formatted values
# provenance included if available
Expand Down
81 changes: 45 additions & 36 deletions R/spdep.R
Original file line number Diff line number Diff line change
Expand Up @@ -37,24 +37,25 @@ spdepAutoCorr <- function (gobject,
}

# Evaluate spatial autocorrelation using Giotto
resultSpdepCor <- evaluate_autocor_input(gobject = gobject,
use_ext_vals = FALSE,
use_sn = TRUE,
use_expr = TRUE,
use_meta = FALSE,
spat_unit = spat_unit,
feat_type = feat_type,
feats = NULL,
method = "moran",
data_to_use = "expression",
expression_values = expression_values,
meta_cols = NULL,
spatial_network_to_use = spatial_network_to_use,
wm_method = "distance",
wm_name = "spat_weights",
node_values = NULL,
weight_matrix = NULL,
verbose = verbose)
resultSpdepCor <- evaluate_autocor_input(
gobject = gobject,
use_ext_vals = FALSE,
use_sn = TRUE,
use_expr = TRUE,
use_meta = FALSE,
spat_unit = spat_unit,
feat_type = feat_type,
feats = NULL,
data_to_use = "expression",
expression_values = expression_values,
meta_cols = NULL,
spatial_network_to_use = spatial_network_to_use,
wm_method = "distance",
wm_name = "spat_weights",
node_values = NULL,
weight_matrix = NULL,
verbose = verbose
)


# Extract feats and weight_matrix from the result
Expand All @@ -69,21 +70,26 @@ spdepAutoCorr <- function (gobject,
result_list <- list()
progressr::with_progress({
if(step_size > 1) pb = progressr::progressor(steps = nfeats/step_size)
result_list <- lapply_flex(seq_along(feat),
function(feat_value){
callSpdepVar <- callSpdep(method = method,
x = use_values[,feat_value],
listw = mat2listw (weight_matrix, style = "W"))
# Extract the estimated value from the result
result_value <- callSpdepVar$estimate[1]
temp_dt <- data.table(feat_ID = feat[feat_value], value = result_value)
# increment progress
if(exists('pb')) if(feat_value %% step_size == 0) pb()
return(temp_dt)
}
)
result_list <- lapply_flex(
seq_along(feat),
future.packages = c('data.table', 'spdep'),
function(feat_value){
callSpdepVar <- callSpdep(
method = method,
x = use_values[,feat_value],
listw = spdep::mat2listw(weight_matrix, style = "W")
)
# Extract the estimated value from the result
result_value <- callSpdepVar$estimate[1]
temp_dt <- data.table(feat_ID = feat[feat_value], value = result_value)
# increment progress
if(exists('pb')) if(feat_value %% step_size == 0) pb()
return(temp_dt)
}
)
})
result_dt <- rbindlist(result_list)
# combine results
result_dt <- data.table::rbindlist(result_list)

# Return the resulting datatable

Expand Down Expand Up @@ -126,14 +132,17 @@ callSpdep <-function (method, ...){
}

# Check if 'method' exists in the 'spdep' package, if not, stop with an error
if(!(method %in% ls("package:spdep"))){
method <- try(eval(get(method, envir = loadNamespace('spdep'))),
silent = TRUE)
if (inherits(method, 'try-error')) {
stop(paste("Invalid method name. Method", method,
"is not available in the spdep package."))
}

# Fetch the arguments of the 'method' from 'spdep'
fun <- get(method, envir = loadNamespace('spdep'))
allArgs <- args(fun) |> as.list() |> names()
allArgs <- args(method) %>%
as.list() %>%
names()

# Capture arguments provided by the user
methodparam <- list (...)
Expand Down Expand Up @@ -181,6 +190,6 @@ callSpdep <-function (method, ...){
combinedParams <- combinedParams[commonParams]

# Call the function with its parameters
do.call(eval(parse(text=paste0("spdep::", method))), combinedParams)
do.call(method, combinedParams)
}

26 changes: 18 additions & 8 deletions man/filterGiotto.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 48e7a71

Please sign in to comment.