Skip to content

Commit dd43acd

Browse files
committed
homotypic subsetting
1 parent 77ced53 commit dd43acd

File tree

5 files changed

+82
-10
lines changed

5 files changed

+82
-10
lines changed

NAMESPACE

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ export(LabelArray)
55
export(PointFrame)
66
export(ShapeFrame)
77
export(SpatialData)
8+
export(ct_args)
9+
export(ct_axes)
10+
export(ct_data)
11+
export(ct_name)
12+
export(ct_type)
813
export(feature_key)
914
export(instance_key)
1015
export(readImage)
@@ -53,6 +58,7 @@ importFrom(S7,new_S3_class)
5358
importFrom(S7,new_class)
5459
importFrom(S7,new_generic)
5560
importFrom(S7,new_union)
61+
importFrom(S7,prop_names)
5662
importFrom(SingleCellExperiment,"int_metadata<-")
5763
importFrom(SingleCellExperiment,int_metadata)
5864
importFrom(SummarizedExperiment,assay)
@@ -65,6 +71,7 @@ importFrom(grDevices,rainbow)
6571
importFrom(grDevices,rgb)
6672
importFrom(methods,as)
6773
importFrom(methods,is)
74+
importFrom(methods,slot)
6875
importFrom(rlang,.data)
6976
importFrom(sfarrow,read_sf_dataset)
7077
importFrom(utils,.DollarNames)

R/Zattrs.R

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#' @description Handling of coordinate transformations.
77
#'
88
#' @param x \code{Zattrs}
9+
#' @param i scalar integer or string
10+
#' specifying a coordinate transformation.
911
#'
1012
#' @return
1113
#' \item{ct_axes}{character vector of axes names and types.}
@@ -26,6 +28,7 @@
2628
NULL
2729

2830
#' @rdname Zattrs
31+
#' @export
2932
ct_data <- new_generic("ct_data", "x")
3033
method(ct_data, Zattrs) <- \(x) {
3134
ms <- x@data$multiscales[[1]]
@@ -34,18 +37,21 @@ method(ct_data, Zattrs) <- \(x) {
3437
}
3538

3639
#' @rdname Zattrs
40+
#' @export
3741
ct_type <- new_generic("ct_type", "x")
3842
method(ct_type, Zattrs) <- \(x) {
3943
vapply(ct_data(za), \(.) .$type, character(1))
4044
}
4145

4246
#' @rdname Zattrs
47+
#' @export
4348
ct_name <- new_generic("ct_name", "x")
4449
method(ct_name, Zattrs) <- \(x) {
4550
vapply(ct_data(x), \(.) .$output$name, character(1))
4651
}
4752

4853
#' @rdname Zattrs
54+
#' @export
4955
ct_axes <- new_generic("ct_axes", "x")
5056
method(ct_axes, Zattrs) <- \(x) {
5157
ax <- ct_data(x)[[1]]$input$axes
@@ -56,6 +62,7 @@ method(ct_axes, Zattrs) <- \(x) {
5662
}
5763

5864
#' @rdname Zattrs
65+
#' @export
5966
ct_args <- new_generic("ct_args", "x")
6067
method(ct_args, Zattrs) <- \(x, i) {
6168
if (missing(i)) {

R/class.R

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
#' @param points list of \code{\link{PointFrame}}s
1010
#' @param shapes list of \code{\link{ShapeFrame}}s
1111
#' @param tables list of \code{SingleCellExperiment}s
12+
#' @param data
13+
#' For \code{Image/LabelArray}s, a list of \code{ZarrArray}s;
14+
#' For \code{Shape/PointFrame}s, an \code{arrow} Table or derivative.
15+
#' @param zattrs \code{Zattrs} objects; used to represent .zattrs.
16+
#' @param metadata (option) list of free-form extra data.
1217
#'
1318
#' @return \code{SpatialData}
1419
#'
@@ -19,7 +24,9 @@
1924
#'
2025
#' names(sd)
2126
#' sd@images[[1]]
22-
#' sd["shapes", 2]
27+
#' sd[-4, ][, 1]
28+
#' sd[1:2, c(1,1)]
29+
#' sd["shapes", c(1,3)]
2330
#' region(sd, "table")
2431
#'
2532
#' @importFrom S7 new_class new_generic method class_list check_is_S7
@@ -50,10 +57,13 @@ SpatialData <- new_class("SpatialData",
5057
ok <- c(ok, mapply(x=slot, y=type, \(x, y) {
5158
if (length(z <- attr(self, x)) && !.all(z, y))
5259
sprintf("'@%s' should be a list of '%s's", x, y)
53-
nms <- names(slot(self, x))
54-
len <- vapply(nms, nchar, integer(1))
55-
if (is.null(nms) || any(len == 0))
56-
sprintf("'@%s' should be a fully named list", x)
60+
l <- slot(self, x)
61+
if (length(l)) {
62+
nms <- names(l)
63+
len <- vapply(nms, nchar, integer(1))
64+
if (is.null(nms) || any(len == 0))
65+
sprintf("'@%s' should be a fully named list", x)
66+
}
5767
}, SIMPLIFY=FALSE) |> unlist())
5868
ts <- self@tables
5969
for (t in ts) {
@@ -72,11 +82,47 @@ names(.LAYERS) <- .LAYERS <- names(SpatialData@properties)
7282

7383
method(`[[`, SpatialData) <- \(x, i) attr(x, .LAYERS[i])
7484

85+
#' @importFrom S7 prop_names
86+
#' @importFrom methods slot
7587
method(`[`, SpatialData) <- \(x, i, j) {
76-
n <- length(y <- x[[i]])
77-
if (missing(j)) if (n) j <- TRUE else return(y)
78-
if (is.numeric(j) && any(j > n)) stop("'j' out of bounds")
79-
if (!isTRUE(j) && length(j) == 1) y[[j]] else y[j]
88+
ps <- prop_names(x)
89+
if (missing(i)) {
90+
n <- vapply(ps, \(.) length(slot(x, .)), integer(1))
91+
i <- ps[n > 0]
92+
} else {
93+
if (is.numeric(i)) {
94+
stopifnot(abs(i) <= length(ps), i == round(i))
95+
i <- ps[i]
96+
} else if (is.character(i)) {
97+
i <- match.arg(i, ps, TRUE)
98+
}
99+
}
100+
if (missing(j)) {
101+
j <- !logical(length(i))
102+
} else {
103+
if (length(i) == 1) {
104+
j <- list(j)
105+
} else {
106+
if (length(j) == 1)
107+
j <- replicate(length(i), j, FALSE)
108+
j <- as.list(j)
109+
}
110+
stopifnot(length(j) == length(i))
111+
for (. in seq_along(i)) {
112+
.j <- j[[.]]
113+
l <- slot(x, i[.])
114+
if (is.character(.j)) {
115+
match.arg(.j, names(l), TRUE)
116+
} else {
117+
n <- length(l)
118+
stopifnot(abs(.j) <= n, .j == round(.j))
119+
}
120+
}
121+
}
122+
l <- mapply(i=i, j=j, \(i, j) {
123+
slot(x, i)[j]
124+
}, SIMPLIFY=FALSE)
125+
do.call(SpatialData, l)
80126
}
81127

82128
method(names, SpatialData) <- \(x) lapply(.LAYERS, \(.) names(slot(x, .)))

man/SpatialData.Rd

Lines changed: 10 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/Zattrs.Rd

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)