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

Fix SpatiallyVariableFeatures.Assay & Introduce SVFInfo/SpatiallyVariableFeatures.StdAssay #242

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

zskylarli
Copy link
Collaborator

@zskylarli zskylarli commented Feb 14, 2025

This PR fixes a small bug with SpatiallyVariableFeatures.Assay and then introduces implementations for SpatiallyVariableFeatures.StdAssay/SpatiallyVariableFeatures.Assay5 & SVFInfo.StdAssay/SVFInfo.Assay5.

The error was being thrown by this call to order—apparently it has always been wrong to call order on a data.frame but it became an error in R 4.3.0.

Copy link
Collaborator

@dcollins15 dcollins15 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice! 🙌

Ideally, we'd like to implement SVFInfo.StdAssay & SpatiallyVariableFeatures.StdAssay to emulate the interfaces for HVFInfo.StdAssay and SpatiallyVariableFeatures.StdAssay so that they expose a layers argument. Since this would require updating Seurat::FindSpatiallyVariableFeatures.StdAssay to be layer-aware I'm ok with just duplicating the Assay implementations for now.

In that case, I think it'll be a lot cleaner to make the methods explicitly equivalent—I've added some suggested changes to that effect.


Please also keep in mind that any links to to lab's private repositories (e.g. satijalab/seurat-private#138) cannot be viewed by external contributors and should be avoided in public-facing PRs. I've updated the description for this PR to use as an example going forward.

Thanks!

Comment on lines +1694 to +1744
SVFInfo.StdAssay <- function(
object,
method = c("markvariogram", "moransi"),
status = FALSE,
selection.method = deprecated(),
...
) {
CheckDots(...)
if (is_present(arg = selection.method)) {
.Deprecate(
when = '5.0.0',
what = 'SVFInfo(selection.method = )',
with = 'SVFInfo(method = )'
)
method <- selection.method
}
method <- match.arg(arg = method)
vars <- switch(
EXPR = method,
markvariogram = grep(
pattern = "r.metric",
x = colnames(x = object[[]]),
value = TRUE
),
moransi = grep(
pattern = 'MoransI',
x = colnames(x = object[[]]),
value = TRUE
),
abort(message = paste("Unknown method:", sQuote(x = method)))
)

tryCatch(
expr = svf.info <- object[[vars]],
error = function(e) {
stop(
"Unable to find spatially variable feature information for method '",
method,
"'",
call. = FALSE
)
}
)

colnames(x = svf.info) <- vars
if (status) {
svf.info$variable <- object[[paste0(method, '.spatially.variable')]]
svf.info$rank <- object[[paste0(method, '.spatially.variable.rank')]]
}
return(svf.info)
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
SVFInfo.StdAssay <- function(
object,
method = c("markvariogram", "moransi"),
status = FALSE,
selection.method = deprecated(),
...
) {
CheckDots(...)
if (is_present(arg = selection.method)) {
.Deprecate(
when = '5.0.0',
what = 'SVFInfo(selection.method = )',
with = 'SVFInfo(method = )'
)
method <- selection.method
}
method <- match.arg(arg = method)
vars <- switch(
EXPR = method,
markvariogram = grep(
pattern = "r.metric",
x = colnames(x = object[[]]),
value = TRUE
),
moransi = grep(
pattern = 'MoransI',
x = colnames(x = object[[]]),
value = TRUE
),
abort(message = paste("Unknown method:", sQuote(x = method)))
)
tryCatch(
expr = svf.info <- object[[vars]],
error = function(e) {
stop(
"Unable to find spatially variable feature information for method '",
method,
"'",
call. = FALSE
)
}
)
colnames(x = svf.info) <- vars
if (status) {
svf.info$variable <- object[[paste0(method, '.spatially.variable')]]
svf.info$rank <- object[[paste0(method, '.spatially.variable.rank')]]
}
return(svf.info)
}
SVFInfo.Assay5 <- SVFInfo.StdAssay

Comment on lines +1750 to +1772
SpatiallyVariableFeatures.StdAssay <- function(
object,
method = "moransi",
decreasing = TRUE,
selection.method = deprecated(),
...
) {
CheckDots(...)
if (is_present(arg = selection.method)) {
.Deprecate(
when = '5.0.0',
what = 'SpatiallyVariableFeatures(selection.method = )',
with = 'SpatiallyVariableFeatures(method = )'
)
method <- selection.method
}
vf <- SVFInfo(object = object, method = method, status = TRUE)
vf <- vf[rownames(x = vf)[which(!is.na(x = vf[, "variable"]))], ]
if (!is.null(x = decreasing)) {
vf <- vf[order(x = vf[, "rank"][, 1], decreasing = !decreasing), ]
}
return(rownames(x = vf))
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
SpatiallyVariableFeatures.StdAssay <- function(
object,
method = "moransi",
decreasing = TRUE,
selection.method = deprecated(),
...
) {
CheckDots(...)
if (is_present(arg = selection.method)) {
.Deprecate(
when = '5.0.0',
what = 'SpatiallyVariableFeatures(selection.method = )',
with = 'SpatiallyVariableFeatures(method = )'
)
method <- selection.method
}
vf <- SVFInfo(object = object, method = method, status = TRUE)
vf <- vf[rownames(x = vf)[which(!is.na(x = vf[, "variable"]))], ]
if (!is.null(x = decreasing)) {
vf <- vf[order(x = vf[, "rank"][, 1], decreasing = !decreasing), ]
}
return(rownames(x = vf))
}
SpatiallyVariableFeatures.StdAssay <- SpatiallyVariableFeatures.Assay

Comment on lines +1774 to +1785
#' @rdname SpatiallyVariableFeatures
#' @method SpatiallyVariableFeatures Assay5
#' @export
#'
SpatiallyVariableFeatures.Assay5 <- SpatiallyVariableFeatures.StdAssay

#' @rdname VariableFeatures
#' @method SVFInfo Assay5
#' @export
#'
SVFInfo.Assay5 <- SVFInfo.StdAssay

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit—consistent ordering:

Suggested change
#' @rdname SpatiallyVariableFeatures
#' @method SpatiallyVariableFeatures Assay5
#' @export
#'
SpatiallyVariableFeatures.Assay5 <- SpatiallyVariableFeatures.StdAssay
#' @rdname VariableFeatures
#' @method SVFInfo Assay5
#' @export
#'
SVFInfo.Assay5 <- SVFInfo.StdAssay
#' @rdname VariableFeatures
#' @method SVFInfo Assay5
#' @export
#'
SVFInfo.Assay5 <- SVFInfo.StdAssay
#' @rdname SpatiallyVariableFeatures
#' @method SpatiallyVariableFeatures Assay5
#' @export
#'
SpatiallyVariableFeatures.Assay5 <- SpatiallyVariableFeatures.StdAssay

)
method <- selection.method
}
method <- match.arg(arg = method)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! You should drop the redundant method <- method[1] call from SVFInfo.Assay too 👌

@@ -878,9 +878,9 @@ SpatiallyVariableFeatures.Assay <- function(
method <- selection.method
}
vf <- SVFInfo(object = object, method = method, status = TRUE)
vf <- vf[rownames(x = vf)[which(x = vf[, "variable"][, 1])], ]
vf <- vf[rownames(x = vf)[which(!is.na(x = vf[, "variable"]))], ]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you revert this change, then I think you can just return rownames(vf) without sorting again. I think this was your intent in SVFInfo.StdAssay except that updating this line means that features where variable == FALSE will still be returned.

Suggested change
vf <- vf[rownames(x = vf)[which(!is.na(x = vf[, "variable"]))], ]
vf <- vf[rownames(vf)[which(vf[, "variable"][, 1])], ]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants