16 hyperframe
These packages (Note 1) are a one-person project undergoing rapid evolution. Backward compatibility (per Hadley Wickham) is provided as a courtesy rather than a guarantee.
Until further notice, these packages should
- not be used as the basis for research grant applications or referenced in final research progress reports,
- not be cited as an actively maintained tool in a peer-reviewed manuscript,
- not be used to support or fulfill requirements for pursuing an academic degree.
In addition, work primarily based on these packages (Note 1) should not be presented at academic conferences or similar scholarly venues.
Furthermore, a person’s ability to use these packages (Note 1) does not necessarily imply an understanding of their underlying mechanisms. Accordingly, demonstration of their use alone should not be considered sufficient evidence of expertise, nor should it be credited as a basis for academic promotion or advancement.
These statements do not apply to the contributors (Tip 1) to these packages (Note 1) with respect to their specific contributions.
These statements do not apply when the maintainer of these packages (Note 1), Tingting Zhan, is credited as the first author, the lead author, and/or the corresponding author in a peer-reviewed manuscript, or as the Principal Investigator or Co-Principal Investigator in a research grant application and/or a final research progress report.
These statements are advisory in nature and do not modify or restrict the rights granted under the GNU General Public License https://www.r-project.org/Licenses/.
The function hyperframe() creates a hyper data frame, i.e., an R object of S3 class 'hyperframe'. The S3 generic function as.hyperframe() converts R objects of various classes into a hyper data frame. Note 16.1 and Note 1.2 summarize the S3 methods for the generic function as.hyperframe() and the S3 methods for the class 'hyperframe', respectively, in the spatstat.* family of packages,
| visible | isS4 | |
|---|---|---|
as.hyperframe.anylist |
TRUE | FALSE |
as.hyperframe.data.frame |
TRUE | FALSE |
as.hyperframe.default |
TRUE | FALSE |
as.hyperframe.hyperframe |
TRUE | FALSE |
as.hyperframe.listof |
TRUE | FALSE |
as.hyperframe.ppx |
TRUE | FALSE |
Table 16.1 summarizes the S3 methods for the class 'hyperframe' in package groupedHyperframe (v0.4.0, GPL-2),
S3 methods groupedHyperframe::*.hyperframe (v0.4.0)
| visible | generic | isS4 | |
|---|---|---|---|
aggregate.hyperframe |
FALSE | stats::aggregate |
FALSE |
as.groupedHyperframe.hyperframe |
FALSE | groupedHyperframe::as.groupedHyperframe |
FALSE |
get_nested_factor.hyperframe |
FALSE | groupedHyperframe::get_nested_factor |
FALSE |
getGroupsFormula.hyperframe |
FALSE | nlme::getGroupsFormula |
FALSE |
length.hyperframe |
FALSE | base::length |
FALSE |
superimpose.hyperframe |
FALSE | spatstat.geom::superimpose |
FALSE |
within.hyperframe |
FALSE | base::within |
FALSE |
16.1 Examples
Listing 16.1 creates a subset of the hyper data frame flu (Section 9.12).
fluM, a subset of flu (Section 9.12)
fluM = spatstat.data::flu |>
spatstat.geom::subset.hyperframe(
subset = (stain == 'M2-M1') & (virustype == 'wt'),
select = c('pattern', 'frameid')
)
fluMHyperframe:
pattern frameid
wt M2-M1 13 (ppp) 13
wt M2-M1 22 (ppp) 22
wt M2-M1 27 (ppp) 27
wt M2-M1 43 (ppp) 43
wt M2-M1 49 (ppp) 49
wt M2-M1 65 (ppp) 65
wt M2-M1 71 (ppp) 71
wt M2-M1 84 (ppp) 84
Listing 16.2 shows that each member of the ppp-hypercolumn fluM$pattern (Listing 16.1) has one multi-type mark with two levels 'M2' and 'M1'.
M1 and/or M2 points per point-pattern in fluM$pattern (Listing 16.1)
fluM$pattern |>
sapply(FUN = \(i) {
i |>
spatstat.geom::marks.ppp() |>
table()
}) |>
addmargins() wt M2-M1 13 wt M2-M1 22 wt M2-M1 27 wt M2-M1 43 wt M2-M1 49 wt M2-M1 65
M2 117 65 71 241 150 116
M1 354 152 143 165 267 202
Sum 471 217 214 406 417 318
wt M2-M1 71 wt M2-M1 84 Sum
M2 57 104 921
M1 208 405 1896
Sum 265 509 2817
16.2 Length
The S3 method length.hyperframe() finds the number of columns and/or hypercolumns of a hyper data frame. Table 16.2 explains its rational and similarity to other length methods in package base (R version 4.5.3 (2026-03-11)).
S3 Method length.hyperframe()
length() of 'data.frame' |
length.POSIXlt() |
length.hyperframe() |
|
|---|---|---|---|
| User-Perceived Length | Yes (Listing 16.3), the number of columns | Yes (Listing 16.6), the number of elements | Yes (Listing 16.4), the number of (hyper)columns |
| Internal Structure Length | Yes, the number of list elements | No (Listing 16.7) | No (Listing 16.5) |
Listing 16.3 reveals that the data frame Formaldehyde from package datasets (R version 4.5.3 (2026-03-11)) has 2 columns, using the .Primitive S3 generic function length().
length() on data.frame
datasets::Formaldehyde |>
length()[1] 2
Listing 16.4 reveals that the hyper data frame demohyper (Section 9.9) has 3 (hyper)columns. The internal structure length of a hyper data frame (Listing 16.5) is not relevant to end users and may change without notice in package spatstat.geom (v3.7.3, GPL (>= 2)).
length.hyperframe()
spatstat.data::demohyper |>
length()[1] 3
length of hyper data frame, internal-structure
spatstat.data::demohyper |>
unclass() |>
length()[1] 8
The S3 method length.POSIXlt() (R version 4.5.3 (2026-03-11)) (Listing 16.6) returns the user-perceived length of a POSIXlt object, rather than its internal structure length (Listing 16.7).
length of a POSIXlt object, user-perceived
tm = Sys.time() |>
as.POSIXlt.POSIXct(tz = 'GMT')
tm |>
length.POSIXlt()[1] 1
length of a POSIXlt object, internal-structure (Listing 16.6)
tm |>
unclass() |>
length()[1] 11
16.3 Aggregation
The S3 method aggregate.hyperframe()
- splits, according to the grouping level specified in the parameter
by,- the hypercolumn(s) that are
ppplist(Chapter 25) into list(s) ofppplist; - the hypercolumn(s) that are
imlist(Chapter 19) into list(s) ofimlist; - the hypercolumn(s) that are
solist(Chapter 27) into list(s) ofsolist.
- the hypercolumn(s) that are
- aggregates, according to the grouping level specified in the parameter
by,- the regular column(s) by simply taking their
unique-value, as the elements in each column must beall.equalwithin each grouping ofby;
- the regular column(s) by simply taking their
- returns a hyper data frame.
When the primary input is a grouped hyper data frame (Chapter 15), the aggregation may be specified at either one of the nested grouping levels (Chapter 34) \(g_1,\cdots,g_{m-1}\). Aggregation at the lowest grouping level \(g_m\) is ignored, i.e., no aggregation to be performed.
16.4 Adding group
The S3 generic function as.groupedHyperframe() creates a (grouped) hyper data frame. Package groupedHyperframe (v0.4.0, GPL-2) implements the following S3 methods (Table 16.3),
S3 methods of groupedHyperframe::as.groupedHyperframe (v0.4.0)
| visible | generic | isS4 | |
|---|---|---|---|
as.groupedHyperframe.hyperframe |
FALSE | groupedHyperframe::as.groupedHyperframe |
FALSE |
The S3 method as.groupedHyperframe.hyperframe() converts a hyper data frame into a grouped hyper data frame by inspecting and adding a (nested) grouping structure to the input.
Listing 16.8 adds a nested grouping structure ~id to the hyper data frame osteo (Section 9.20).
as.groupedHyperframe.hyperframe()
spatstat.data::osteo |>
as.groupedHyperframe(group = ~ id)Grouped Hyper Data Frame: ~id
4 id
id shortid brick pts depth
1 c77za4 4 1 (pp3) 45
2 c77za4 4 2 (pp3) 60
3 c77za4 4 3 (pp3) 55
4 c77za4 4 4 (pp3) 60
5 c77za4 4 5 (pp3) 85
6 c77za4 4 6 (pp3) 90
7 c77za4 4 7 (pp3) 95
8 c77za4 4 8 (pp3) 65
9 c77za4 4 9 (pp3) 100
10 c77za4 4 10 (pp3) 100
11 c77za5 5 1 (pp3) 45
21 c77za5 5 2 (pp3) 30
31 c77za5 5 3 (pp3) 40
41 c77za5 5 4 (pp3) 45
51 c77za5 5 5 (pp3) 40
61 c77za5 5 6 (pp3) 50
71 c77za5 5 7 (pp3) 40
81 c77za5 5 8 (pp3) 60
91 c77za5 5 9 (pp3) 65
101 c77za5 5 10 (pp3) 60
12 c77za8 8 1 (pp3) 40
22 c77za8 8 2 (pp3) 55
32 c77za8 8 3 (pp3) 60
42 c77za8 8 4 (pp3) 50
52 c77za8 8 5 (pp3) 45
62 c77za8 8 6 (pp3) 30
72 c77za8 8 7 (pp3) 50
82 c77za8 8 8 (pp3) 45
92 c77za8 8 9 (pp3) 70
102 c77za8 8 10 (pp3) 110
13 c77za9 9 1 (pp3) 60
23 c77za9 9 2 (pp3) 65
33 c77za9 9 3 (pp3) 55
43 c77za9 9 4 (pp3) 70
53 c77za9 9 5 (pp3) 55
63 c77za9 9 6 (pp3) 100
73 c77za9 9 7 (pp3) 80
83 c77za9 9 8 (pp3) 75
93 c77za9 9 9 (pp3) 85
103 c77za9 9 10 (pp3) 60
16.5 Superimpose
Listing 16.9 summarizes the S3 methods of the generic function superimpose() (v3.7.3, GPL (>= 2)) in the spatstat.* family of packages,
S3 methods spatstat.*::superimpose.*
library(spatstat)
.S3methods(generic = 'superimpose', all.names = TRUE) |>
attr(which = 'info', exact = TRUE) |>
subset.data.frame(subset = grepl(pattern = '^spatstat\\.', x = from)) visible from generic isS4
superimpose.default TRUE spatstat.geom superimpose FALSE
superimpose.lpp TRUE spatstat.linnet superimpose FALSE
superimpose.ppp TRUE spatstat.geom superimpose FALSE
superimpose.ppplist TRUE spatstat.geom superimpose FALSE
superimpose.psp TRUE spatstat.geom superimpose FALSE
superimpose.splitppp TRUE spatstat.geom superimpose FALSE
The S3 method superimpose.hyperframe() performs a by-element superimpose of the
- point-pattern (
ppp) hypercolumns - line-segment-pattern (
psp) hypercolumns 🚧
of multiple hyper data frames, if-and-only-if all input hyper data frames have identical
dimensions, i.e.,dim.hyperframe()(v3.7.3, GPL (>= 2))- columns, i.e.,
unclass(.)$df namesandclassof the hyper columns, i.e.,unclass(.)$hypercolumns
The hypercolumn fluM$pattern (Listing 16.1) contains 8 point-patterns, each of them has 200-500 points (Listing 16.2). Listing 16.10 creates a hyper data frame fluM1 which consists of the same columns as fluM, but a ppp-hypercolumn $pattern with M1 marks only; and another hyper data frame fluM2 which consists of the M2 marks only.
fluM1 and fluM2 (Listing 16.1)
fluM1 = fluM2 = fluM
fluM1$pattern = fluM$pattern |>
spatstat.geom::solapply(
FUN = spatstat.geom::subset.ppp,
subset = (marks == 'M1')
)
fluM2$pattern = fluM$pattern |>
spatstat.geom::solapply(
FUN = spatstat.geom::subset.ppp,
subset = (marks == 'M2')
)Listing 16.11 recreates the hyper data frame fluM (Listing 16.1) by superimposing the hyper data frames fluM2 and fluM1 (Listing 16.10). Note that the order of fluM2-then-fluM1 matters, because the points are arranged in M2-then-M1 in the original hypercolumn fluM$pattern (Listing 16.1, Listing 16.2).
superimpose.hyperframe() (Listing 16.1, Listing 16.10)
superimpose(fluM2, fluM1) |>
identical(y = fluM) |>
stopifnot()Note that the S3 method superimpose.ppplist() (v3.7.3, GPL (>= 2)) superimposes all point-patterns from all input point-pattern-lists (Listing 16.12).
superimpose.ppplist() not what we need (Listing 16.10)
list(
'all superimposed' = spatstat.geom::superimpose.ppplist(
unclass(fluM2)$hypercolumns$pattern,
unclass(fluM1)$hypercolumns$pattern
) |>
spatstat.geom::npoints.ppp(),
'all M2' = fluM2$pattern |>
vapply(FUN = spatstat.geom::npoints.ppp, FUN.VALUE = NA_integer_) |>
sum(),
'all M1' = fluM1$pattern |>
vapply(FUN = spatstat.geom::npoints.ppp, FUN.VALUE = NA_integer_) |>
sum()
)$`all superimposed`
[1] 2817
$`all M2`
[1] 921
$`all M1`
[1] 1896