25  hyperframe

Function spatstat.geom::hyperframe() creates a hyper data frame, i.e., an R object of S3 class 'hyperframe'.

The S3 generic function spatstat.geom::as.hyperframe() converts R objects of various classes into a hyper data frame. Listing 25.1 summarizes the S3 methods for the generic function as.hyperframe() in the spatstat.* family of packages,

Listing 25.1: S3 methods spatstat.*::as.hyperframe.*
Code
suppressPackageStartupMessages(library(spatstat))
.S3methods(generic.function = 'as.hyperframe', all.names = TRUE) |> 
  attr(which = 'info', exact = TRUE) |>
  subset.data.frame(subset = grepl(pattern = '^spatstat\\.', x = from))
#                          visible          from       generic  isS4
# as.hyperframe.anylist       TRUE spatstat.geom as.hyperframe FALSE
# as.hyperframe.data.frame    TRUE spatstat.geom as.hyperframe FALSE
# as.hyperframe.default       TRUE spatstat.geom as.hyperframe FALSE
# as.hyperframe.hyperframe    TRUE spatstat.geom as.hyperframe FALSE
# as.hyperframe.listof        TRUE spatstat.geom as.hyperframe FALSE
# as.hyperframe.ppx           TRUE spatstat.geom as.hyperframe FALSE

Listing 25.2 summarizes the S3 methods for the class 'hyperframe' in the spatstat.* family of packages,

Listing 25.2: S3 methods spatstat.*::*.hyperframe
Code
suppressPackageStartupMessages(library(spatstat))
.S3methods(class = 'hyperframe', all.names = TRUE) |> 
  attr(which = 'info', exact = TRUE) |>
  subset.data.frame(subset = grepl(pattern = '^spatstat\\.', x = from))
#                          visible          from       generic  isS4
# [.hyperframe                TRUE spatstat.geom             [ FALSE
# [[.hyperframe               TRUE spatstat.geom            [[ FALSE
# [[<-.hyperframe             TRUE spatstat.geom          [[<- FALSE
# [<-.hyperframe              TRUE spatstat.geom           [<- FALSE
# $.hyperframe                TRUE spatstat.geom             $ FALSE
# $<-.hyperframe              TRUE spatstat.geom           $<- FALSE
# as.data.frame.hyperframe    TRUE spatstat.geom as.data.frame FALSE
# as.hyperframe.hyperframe    TRUE spatstat.geom as.hyperframe FALSE
# as.list.hyperframe          TRUE spatstat.geom       as.list FALSE
# cbind.hyperframe            TRUE spatstat.geom         cbind FALSE
# dim.hyperframe              TRUE spatstat.geom           dim FALSE
# dimnames.hyperframe         TRUE spatstat.geom      dimnames FALSE
# dimnames<-.hyperframe       TRUE spatstat.geom    dimnames<- FALSE
# edit.hyperframe             TRUE spatstat.geom          edit FALSE
# head.hyperframe             TRUE spatstat.geom          head FALSE
# is.na.hyperframe            TRUE spatstat.geom         is.na FALSE
# names.hyperframe            TRUE spatstat.geom         names FALSE
# names<-.hyperframe          TRUE spatstat.geom       names<- FALSE
# plot.hyperframe             TRUE spatstat.geom          plot FALSE
# print.hyperframe            TRUE spatstat.geom         print FALSE
# rbind.hyperframe            TRUE spatstat.geom         rbind FALSE
# row.names.hyperframe        TRUE spatstat.geom     row.names FALSE
# row.names<-.hyperframe      TRUE spatstat.geom   row.names<- FALSE
# split.hyperframe            TRUE spatstat.geom         split FALSE
# split<-.hyperframe          TRUE spatstat.geom       split<- FALSE
# str.hyperframe              TRUE spatstat.geom           str FALSE
# subset.hyperframe           TRUE spatstat.geom        subset FALSE
# summary.hyperframe          TRUE spatstat.geom       summary FALSE
# tail.hyperframe             TRUE spatstat.geom          tail FALSE
# with.hyperframe             TRUE spatstat.geom          with FALSE

The examples in Chapter 25 require

library(groupedHyperframe)
search path & loadedNamespaces on author’s computer
search()
#  [1] ".GlobalEnv"                "package:groupedHyperframe" "package:stats"             "package:graphics"          "package:grDevices"         "package:utils"             "package:datasets"         
#  [8] "package:methods"           "Autoloads"                 "package:base"
loadedNamespaces() |> sort.int()
#  [1] "abind"             "base"              "cli"               "cluster"           "codetools"         "compiler"          "datasets"          "deldir"            "digest"           
# [10] "doParallel"        "dplyr"             "evaluate"          "farver"            "fastmap"           "fastmatrix"        "foreach"           "generics"          "geomtextpath"     
# [19] "GET"               "ggplot2"           "glue"              "goftest"           "graphics"          "grDevices"         "grid"              "gridExtra"         "groupedHyperframe"
# [28] "gtable"            "htmltools"         "htmlwidgets"       "iterators"         "jsonlite"          "knitr"             "lattice"           "lifecycle"         "magrittr"         
# [37] "Matrix"            "matrixStats"       "methods"           "nlme"              "otel"              "parallel"          "patchwork"         "pillar"            "pkgconfig"        
# [46] "polyclip"          "pracma"            "R6"                "RColorBrewer"      "rlang"             "rmarkdown"         "rstudioapi"        "S7"                "scales"           
# [55] "SpatialPack"       "spatstat.data"     "spatstat.explore"  "spatstat.geom"     "spatstat.random"   "spatstat.sparse"   "spatstat.univar"   "spatstat.utils"    "splines"          
# [64] "stats"             "survival"          "systemfonts"       "tensor"            "textshaping"       "tibble"            "tidyselect"        "tools"             "utils"            
# [73] "vctrs"             "viridisLite"       "xfun"              "yaml"

Table 25.1 summarizes the S3 methods for the class 'hyperframe' in package groupedHyperframe (v0.3.4),

Table 25.1: S3 methods groupedHyperframe::*.hyperframe (v0.3.4)
visible generic isS4
.disrecommend2theo.hyperframe TRUE groupedHyperframe::.disrecommend2theo FALSE
.illegal2theo.hyperframe TRUE groupedHyperframe::.illegal2theo FALSE
.rmax.hyperframe TRUE groupedHyperframe::.rmax FALSE
aggregate_marks.hyperframe TRUE groupedHyperframe::aggregate_marks FALSE
aggregate.hyperframe TRUE stats::aggregate FALSE
as.groupedHyperframe.hyperframe TRUE groupedHyperframe::as.groupedHyperframe FALSE
attr_.hyperframe TRUE groupedHyperframe::attr_ FALSE
cumvtrapz.hyperframe TRUE groupedHyperframe::cumvtrapz FALSE
Emark_.hyperframe TRUE groupedHyperframe::Emark_ FALSE
Gcross_.hyperframe TRUE groupedHyperframe::Gcross_ FALSE
global_envelope_test_.hyperframe TRUE groupedHyperframe::global_envelope_test_ FALSE
Jcross_.hyperframe TRUE groupedHyperframe::Jcross_ FALSE
Kcross_.hyperframe TRUE groupedHyperframe::Kcross_ FALSE
kerndens.hyperframe TRUE groupedHyperframe::kerndens FALSE
keyval.hyperframe TRUE groupedHyperframe::keyval FALSE
Kmark_.hyperframe TRUE groupedHyperframe::Kmark_ FALSE
Lcross_.hyperframe TRUE groupedHyperframe::Lcross_ FALSE
length.hyperframe TRUE base::length FALSE
markconnect_.hyperframe TRUE groupedHyperframe::markconnect_ FALSE
markcorr_.hyperframe TRUE groupedHyperframe::markcorr_ FALSE
markvario_.hyperframe TRUE groupedHyperframe::markvario_ FALSE
nncross_.hyperframe TRUE groupedHyperframe::nncross_ FALSE
quantile.hyperframe TRUE stats::quantile FALSE
rlabelRes.hyperframe TRUE groupedHyperframe::rlabelRes FALSE
superimpose.hyperframe TRUE spatstat.geom::superimpose FALSE
Vmark_.hyperframe TRUE groupedHyperframe::Vmark_ FALSE

25.1 Examples

Listing 25.3 creates a subset of the hyper data frame flu (Section 9.12).

Listing 25.3: Data: 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')
  )
fluM
# Hyperframe:
#             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 25.4 shows that each member of the ppp-hypercolumn fluM$pattern (Listing 25.3) has one multi-type mark with two levels 'M2' and 'M1'.

Listing 25.4: Review: number of M1 and/or M2 points per point-pattern in fluM$pattern (Listing 25.3)
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 wt M2-M1 71 wt M2-M1 84  Sum
# M2          117          65          71         241         150         116          57         104  921
# M1          354         152         143         165         267         202         208         405 1896
# Sum         471         217         214         406         417         318         265         509 2817

25.2 Plot

Section 25.2 is intended as an educational handbook for beginners to package spatstat.geom (v3.7.0.6). This section does not discuss the functionality of package groupedHyperframe (v0.3.4).

The S3 method spatstat.geom::plot.hyperframe() plots the plot-able hypercolumn(s) in a hyper data frame.

Listing 25.5 deems the multi-type ppp-hypercolumn flu$pattern (Section 9.12) to be plot-able, and plots them (Figure 25.1).

Listing 25.5: Review: spatstat.geom::plot.hyperframe(); plot ppp-hypercolumn flu$pattern
par(mar = c(0,0,1,0))
spatstat.data::flu[1:2, ] |>
  spatstat.geom::plot.hyperframe()
Figure 25.1: Plot ppp-hypercolumn flu$pattern

25.3 Length

The S3 method length.hyperframe() finds the number of columns and/or hypercolumns of a hyper data frame. Table 25.2 explains its rational and similarity to other length methods in package base shipped with R version 4.5.2 (2025-10-31).

Table 25.2: Rational of S3 Method length.hyperframe()
length() on 'data.frame' length.POSIXlt() length.hyperframe()
Number of (Hyper)Columns Yes (Listing 25.6) Not Applicable Yes (Listing 25.7)
User-Perceived Length Yes, “length” as number of columns Yes (Listing 25.9) Yes, “length” as number of (hyper)columns
Internal Structure Length Yes, “length” as number of list elements No (Listing 25.10) No (Listing 25.8)

Listing 25.6 reveals that the data frame Formaldehyde from package datasets shipped with R version 4.5.2 (2025-10-31) has 2 columns, using the .Primitive S3 generic function base::length().

Listing 25.6: Review: function base::length() on data.frame
datasets::Formaldehyde |>
  length()
# [1] 2

Listing 25.7 reveals that the hyper data frame demohyper (Section 9.9) has 3 (hyper)columns. The internal structure length of a hyper data frame (Listing 25.8) is not relevant to end users and may change without notice in package spatstat.geom (v3.7.0.6).

Listing 25.7: Example: function length.hyperframe()
spatstat.data::demohyper |>
  length()
# [1] 3
Listing 25.8: Review: length of hyper data frame, internal-structure
Code
spatstat.data::demohyper |>
  unclass() |>
  length()
# [1] 8

The S3 method base::length.POSIXlt() (Listing 25.9) returns the user-perceived length of a POSIXlt object , rather than its internal structure length (Listing 25.10).

Listing 25.9: Review: length of a POSIXlt object, user-perceived
Code
tm = Sys.time() |> 
  as.POSIXlt.POSIXct(tz = 'GMT')
tm |> 
  length.POSIXlt()
# [1] 1
Listing 25.10: Review: length of a POSIXlt object, internal-structure (Listing 25.9)
Code
tm |> 
  unclass() |>
  length()
# [1] 11

25.4 Kernel Density Estimates

The S3 method kerndens.hyperframe() (Section 32.1, Table 32.2) finds the kernel density (Becker, Chambers, and Wilks 1988) estimates,

  • of the numeric-hypercolumns using the S3 method kerndens.anylist() (Section 14.1), and
  • of the numeric marks in the one-and-only-one point-pattern (ppp) hypercolumn using the S3 method kerndens.ppplist() (Section 36.2).

and appends additional numeric-hypercolumns to the input. Example has been discussed extensively in Section 2.3.4.

25.5 Quantile

The S3 method quantile.hyperframe() finds the quantiles

  • of the numeric-hypercolumns (Section 14.2), and
  • of the numeric marks in the one-and-only-one point-pattern (ppp) hypercolumn (Section 36.3).

and appends the returned quantiles as numeric-hypercolumns to the input. Example has been discussed extensively in Section 2.3.3.

25.6 Aggregation

The S3 method aggregate.hyperframe()

  • splits (Section 14.5), according to the grouping level specified in the parameter by,
    • the hypercolumn(s) that are ppplist (Chapter 36) into list(s) of ppplist;
    • the hypercolumn(s) that are imlist (Chapter 28) into list(s) of imlist;
    • the hypercolumn(s) that are fvlist (Chapter 20) into list(s) of fvlist;
    • the hypercolumn(s) that are solist (Chapter 38) into list(s) of solist.
  • 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 be all.equal within each grouping of by;
    • the hypercolumn(s) that are vector-lists (vectorlist, Chapter 42) using the aggregation method provided in the parameter fun (Section 42.4).
  • returns a hyper data frame.

When the primary input is a grouped hyper data frame (Chapter 24, e.g., in Section 2.4), the aggregation may be specified at either one of the nested grouping levels (Chapter 48) \(g_1,\cdots,g_{m-1}\). Aggregation at the lowest grouping level \(g_m\) is ignored, i.e., no aggregation to be performed.

25.7 Aggregate Marks-Statistics from ppp-Hypercolumn

The S3 method aggregate_marks.hyperframe() (Section 35.7, Table 35.9)

  • aggregates the marks of one-and-only-one (Section 25.13) ppp-hypercolumn in the input hyper data frame, using the S3 method aggregate_marks.ppplist() (Section 36.4);
  • appends the returned numeric vector-list (vectorlist, Chapter 42) to the input as a new hypercolumn named $markstats.

Listing 25.11 aggregates the relative frequencies of the 'M2' and 'M1' marks in each member of the ppp-hypercolumn fluM$pattern (Listing 25.3, Listing 25.4).

Listing 25.11: Example: function aggregate_marks.hyperframe(), for relative frequencies (Listing 25.3)
fluM_relfreq = fluM |> 
  aggregate_marks(FUN = \(z) table(z)/length(z))
fluM_relfreq
# Hyperframe:
#             pattern frameid markstats
# wt M2-M1 13   (ppp)      13 (numeric)
# wt M2-M1 22   (ppp)      22 (numeric)
# wt M2-M1 27   (ppp)      27 (numeric)
# ✂️ --- output truncated --- ✂️

Listing 25.12 shows the aggregated relative frequencies of the 'M2' and 'M1' marks in the returned hypercolumn fluM_relfreq$markstats (Listing 25.11).

Listing 25.12: Example: inside numeric-hypercolumn fluM_relfreq$markstats (Listing 25.11)
fluM_relfreq$markstats
# wt M2-M1 13:
#        M2        M1 
# 0.2484076 0.7515924 
# 
# wt M2-M1 22:
#        M2        M1 
# 0.2995392 0.7004608 
# ✂️ --- output truncated --- ✂️

As explained in Section 36.4, the S3 method t.vectorlist() (Section 42.3) is the fastest way to extract a “slice” from the numeric-hypercolumn, e.g., fluM_relfreq$markstats.

Listing 25.13: Advanced: function t.vectorlist() (Listing 25.11)
fluM_relfreq$markstats |>
  t.vectorlist()
# A 'vectorlist' of 2 vectors 
# Name(s): M2, M1 
# Storage Mode: numeric 
# Individual Vector Length: 8

Unfortunately, package spatstat.data (v3.1.9) does not have a hyper data frame with (any) ppp-hypercolumn of

  • 'dataframe' mark-format, to showcase the use of parameter by (Section 35.7.3.1).
  • 'vector' mark-format and numeric marks, to showcase the aggregation by sample mean and standard deviation.

25.8 Create groupedHyperframe

The S3 method as.groupedHyperframe.hyperframe() (Section 17.1, Table 17.2) converts a hyper data frame into a grouped hyper data frame by inspecting and adding a (nested) grouping structure to the input.

Listing 25.14 adds a nested grouping structure ~id/brick to the hyper data frame osteo (Section 9.20).

Listing 25.14: Example: function as.groupedHyperframe.hyperframe()
spatstat.data::osteo |> 
  as.groupedHyperframe(group = ~ id/brick)
# Grouped Hyper Data Frame: ~id/brick
# 
# 40 brick nested in
# 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
# ✂️ --- output truncated --- ✂️

25.9 Superimpose

Listing 25.15 summarizes the S3 methods of the generic function spatstat.geom::superimpose() (v3.7.0.6) in the spatstat.* family of packages,

Listing 25.15: S3 methods spatstat.*::superimpose.*
Code
suppressPackageStartupMessages(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

The hypercolumn fluM$pattern (Listing 25.3) contains 8 point-patterns, each of them has 200-500 points (Listing 25.4). Listing 25.16 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.

Listing 25.16: Data: two hyper data frames fluM1 and fluM2 (Listing 25.3)
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 25.17 recreates the hyper data frame fluM (Listing 25.3) by superimposing the hyper data frames fluM2 and fluM1 (Listing 25.16). 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 25.3, Listing 25.4).

Listing 25.17: Example: function superimpose.hyperframe() (Listing 25.3, Listing 25.16)
superimpose.hyperframe(fluM2, fluM1) |>
  identical(y = fluM) |>
  stopifnot()

Note that the S3 method spatstat.geom::superimpose.ppplist() (v3.7.0.6) superimposes all point-patterns from all input point-pattern-lists (Listing 25.18).

Listing 25.18: Review: superimpose.ppplist() not what we need (Listing 25.16)
Code
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

25.10 Attributes per Element

The S3 generic function attr_.hyperframe() (Section 14.4, Table 14.3)

  • extracts the specified attribute per element, per hypercolumn of a hyper data frame;
  • appends these attributes, if exist, to the input hyper data frame as columns or hypercolumns, named in the fashion of $<hypercolumn>.<which>.

Examples of the S3 method attr_.hyperframe() are Listing 25.19.

25.11 Default \(r_\text{max}\)

The S3 method .rmax.hyperframe() (Section 35.10, Table 35.13) obtains the default \(r_\text{max}\) of the one-or-more ppp-hypercolumn(s) (Section 36.6) before the (potentially) very slow batch processes.

Example: function .rmax.hyperframe() for Emark_(), Vmark_(), markcorr_(), markvario_() on numeric- and multi-type mark
s |> .rmax(fun = 'K')
Example: function .rmax.hyperframe() for Kcross_() on multi-type mark
s |> .rmax(fun = 'K', i = 'CK+.CD8-', j = 'CK-.CD8+')
s |> .rmax(fun = 'K', i = 'CK-.CD8+', j = 'CK+.CD8-')
Example: function .rmax.hyperframe() for Gcross_() on multi-type mark
s |> .rmax(fun = 'G', i = 'CK+.CD8-', j = 'CK-.CD8+')
s |> .rmax(fun = 'G', i = 'CK-.CD8+', j = 'CK+.CD8-')
Example: function .rmax.hyperframe() for Jcross_() on multi-type mark
s |> .rmax(fun = 'J', i = 'CK+.CD8-', j = 'CK-.CD8+')
s |> .rmax(fun = 'J', i = 'CK-.CD8+', j = 'CK+.CD8-')

25.12 Random Re-Labelling Envelope Residual & Test

The S3 method rlabelRes.hyperframe() (Section 35.13, Table 35.20)

  1. applies the S3 method rlabelRes.ppplist() (Section 36.8) on the one-and-only-one ppp-hypercolumn of the input hyper data frame;
  2. appends a 'curve_set' (Chapter 16) hypercolumn $.rlabelRes to the input hyper data frame.

The S3 method global_envelope_test_.hyperframe() (Section 14.3, Table 14.2)

  1. applies the S3 method global_envelope_test_.anylist() (Section 14.3) to one or more 'curve_set' (Chapter 16) hypercolumn(s) of the input hyper data frame;
  2. appends one or more 'global_envelope' (Chapter 22) hypercolumn(s) to the input hyper data frame, named in the fashion of $<curve_set>.GET.

Listing 25.19 performs the random re-labelling envelope residual and test on the ppp-hypercolumn fluM$pattern (Listing 25.3), and creates a hyper data frame with

  • a 'curve_set' hypercolumn $.rlabelRes;
  • a 'global_envelope' hypercolumn $.rlabelRes.GET;
  • a numeric column $.rlabelRes.GET.p, the \(p\)-values per element of the hypercolumn $.rlabelRes.GET.
Listing 25.19: Example: functions rlabelRes.hyperframe(), global_envelope_test_.hyperframe() and attr_.hyperframe() (Section 25.10) (Listing 25.3)
fluM |>
  rlabelRes(fun = spatstat.explore::Gcross) |>
  global_envelope_test_() |>
  attr_(which = 'p', exact = TRUE)
# Hyperframe:
#             pattern frameid  .rlabelRes    .rlabelRes.GET .rlabelRes.GET.p
# wt M2-M1 13   (ppp)      13 (curve_set) (global_envelope)             0.01
# wt M2-M1 22   (ppp)      22 (curve_set) (global_envelope)             0.02
# wt M2-M1 27   (ppp)      27 (curve_set) (global_envelope)             0.02
# wt M2-M1 43   (ppp)      43 (curve_set) (global_envelope)             0.01
# wt M2-M1 49   (ppp)      49 (curve_set) (global_envelope)             0.01
# wt M2-M1 65   (ppp)      65 (curve_set) (global_envelope)             0.01
# wt M2-M1 71   (ppp)      71 (curve_set) (global_envelope)             0.06
# wt M2-M1 84   (ppp)      84 (curve_set) (global_envelope)             0.01

25.13 Batch Process on Eligible Marks

The S3 methods Emark_.hyperframe(), Vmark_.hyperframe(), etc., in Table 25.1 are user-friendly wrappers of the low-level utility function op_hyperframe(), for batch operation on hyper data frame (Section 2.2). Function op_hyperframe()

  1. performs the batch operation on the one-and-only-one ppp-hypercolumn (Section 36.9) of the input hyper data frame. The batch operation is not designed to handle a hyper data frame containing multiple ppp-hypercolumns, e.g., cetaceans (Section 9.8). Supporting such functionality would require resolving potential name clashes in the marks across multiple ppp-hypercolumns.
  2. column-binds the two-level hierarchical list returned from the previous step to the input hyper data frame.

Listing 25.20 calls the S3 method Gcross_.hyperframe() to

  1. apply the S3 method Gcross_.ppplist() (Section 36.9) to the ppp-hypercolumn fluM$pattern (Listing 25.3);
  2. append an fv-hypercolumn $m.G to the input hyper data frame.
Listing 25.20: Data: a hyper data frame fluG (Listing 25.3)
fluG = fluM |>
  Gcross_(i = 'M1', j = 'M2', r = 0:300)
fluG
# Hyperframe:
#             pattern frameid  m.G
# wt M2-M1 13   (ppp)      13 (fv)
# wt M2-M1 22   (ppp)      22 (fv)
# wt M2-M1 27   (ppp)      27 (fv)
# ✂️ --- output truncated --- ✂️

25.14 Function Value from fv-Hypercolumns

The S3 method keyval.hyperframe() (Section 19.2, Table 19.3)

  1. applies the S3 method keyval.fvlist() (Section 20.4) across all fv-hypercolumns of the input hyper data frame;
  2. appends the numeric-hypercolumn(s) $<mark>.<fv>.<selected_value> to the input hyper data frame.

Listing 25.21 works on the hyper data frame fluG (Listing 25.20) to

  • create a numeric-hypercolumn $m.G.y of the recommended function values of the fv-hypercolumn fluG$m.G in the returned hyper data frame, using the S3 method keyval.hyperframe();
  • create a numeric-hypercolumn $m.G.theo of the theoretical function values of the fv-hypercolumn fluG$m.G in the returned hyper data frame, using the S3 method keyval.hyperframe(., key = 'theo').
Listing 25.21: Example: function keyval.hyperframe() (Listing 25.20)
fluG |>
  keyval() |>
  keyval(key = 'theo')
# Hyperframe:
#             pattern frameid  m.G     m.G.y  m.G.theo
# wt M2-M1 13   (ppp)      13 (fv) (numeric) (numeric)
# wt M2-M1 22   (ppp)      22 (fv) (numeric) (numeric)
# wt M2-M1 27   (ppp)      27 (fv) (numeric) (numeric)
# ✂️ --- output truncated --- ✂️

25.15 Cumulative Average Vertical Height of Trapzoidal Integration of fv-Hypercolumn

The S3 method cumvtrapz.hyperframe() (Section 10.2, Table 10.1)

  • runs the workhorse function cumvtrapz.fvlist() (Section 20.6) across all fv-hypercolumns of the input hyper data frame;
  • appends additional numeric-hypercolumns $<mark>.<fv>.cumvtrapz to the input hyper data frame;
  • returns a hyper data frame.

Listing 25.22 applies the S3 method cumvtrapz.hyperframe() to the hyper data frame fluG (Listing 25.20) and creates a numeric-hypercolumn $m.G.cumvtrapz from the fv-hypercolumn fluG$m.G in the returned hyper data frame fluG_vt.

Listing 25.22: Example: function cumvtrapz.hyperframe() (Listing 25.20)
fluG_vt = fluG |>
  cumvtrapz()
fluG_vt
# Hyperframe:
#             pattern frameid  m.G m.G.cumvtrapz
# wt M2-M1 13   (ppp)      13 (fv)     (numeric)
# wt M2-M1 22   (ppp)      22 (fv)     (numeric)
# wt M2-M1 27   (ppp)      27 (fv)     (numeric)
# ✂️ --- output truncated --- ✂️

The S3 method t.vectorlist() (Section 42.3) is the fastest way to extract a “slice” from a numeric-hypercolumn, e.g., fluG_vt$m.G.cumvtrapz (Listing 25.22), which is a 'vectorlist' (Chapter 42) although not supported as a hypercolumn in hyper data frame as of package spatstat.geom (v3.7.0.6). A “slice” of the hypercolumn fluG_vt$m.G.cumvtrapz at the 50th index of the \(r\)-vector, i.e., \(r=50\), may be extracted by calling the S3 method spatstat.geom::with.hyperframe() (Listing 25.24), but the S3 method t.vectorlist() (Listing 25.23) is much faster.

Listing 25.23: Advanced: function t.vectorlist() (Listing 25.22)
tG = fluG_vt$m.G.cumvtrapz |>
  t.vectorlist()
Listing 25.24: Review: function spatstat.geom::with.hyperframe() (Listing 25.22, Listing 25.23)
Code
fluG_vt |>
  spatstat.geom::with.hyperframe(expr = {
    m.G.cumvtrapz['50']
  }) |>
  identical(y = tG[[50L]]) |>
  stopifnot()
fluG_vt |>
  spatstat.geom::with.hyperframe(expr = {
    m.G.cumvtrapz[50L]
  }) |>
  identical(y = tG[[50L]]) |>
  stopifnot()

25.16 Handling Illegal Recommended-Function-Value

The S3 methods .illegal2theo.hyperframe() and .disrecommend2theo.hyperframe() (Section 19.5.1, Table 19.5, Table 19.6)

  • apply the S3 methods .illegal2theo.fvlist() and .disrecommend2theo.fvlist() (Section 20.5), respectively, to all fv-hypercolumns of the input hyper data frame;
  • overwrite the fv-hypercolumns in the input hyper data frame;
  • return a hyper data frame.

Listing 25.25 applies the S3 method .disrecommend2theo.hyperframe() on the hyper data frame fluG (Listing 25.20) and overwrites the fv-hypercolumn $m.G in the returned hyper data frame.

Listing 25.25: Example: function .disrecommend2theo.hyperframe() (Listing 25.20)
fluG |>
  .disrecommend2theo()
# Hyperframe:
#             pattern frameid  m.G
# wt M2-M1 13   (ppp)      13 (fv)
# wt M2-M1 22   (ppp)      22 (fv)
# wt M2-M1 27   (ppp)      27 (fv)
# ✂️ --- output truncated --- ✂️

25.17 \(k\)-Means Clustering

Function kmeans.hyperframe()

  • is a “pseudo” S3 method, as the workhorse function stats::kmeans() shipped with R version 4.5.2 (2025-10-31) is not an S3 generic function.
  • performs \(k\)-means clustering on the one-and-only-one (Section 25.13) ppp-hypercolumn via kmeans.ppplist() (Section 36.7).
  • returns an object of class 'hyperframekm', which inherits from 'hyperframe'.

Package groupedHyperframe (v0.3.4) implements the following S3 methods to the class 'hyperframekm' (Table 25.3),

Table 25.3: S3 methods groupedHyperframe::*.hyperframekm (v0.3.4)
visible from generic isS4
split.hyperframekm TRUE groupedHyperframe base::split FALSE

25.17.1 Examples

Listing 25.26 performs \(k\)-means clustering of the ppp-hypercolumn fluM$pattern in the hyper data frame fluM (Listing 25.3).

Listing 25.26: Example: function kmeans.hyperframe() (Listing 25.3)
set.seed(13); flu_k = fluM |> 
  kmeans.hyperframe(formula = ~ x + y, centers = 3L)
flu_k
# Hyperframe:
#             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 25.27: Example: A hyperframekm flu_k (Listing 25.26)
flu_k |>
  class()
# [1] "hyperframekm" "hyperframe"   "list"
Listing 25.28: Example: hypercolumn flu_k$pattern (Listing 25.26)
flu_k$pattern |>
  lapply(FUN = class)
# $`wt M2-M1 13`
# [1] "pppkm" "ppp"  
# 
# $`wt M2-M1 22`
# [1] "pppkm" "ppp"  
# 
# $`wt M2-M1 27`
# [1] "pppkm" "ppp"  
# 
# ✂️ --- output truncated --- ✂️

25.17.2 Split by \(k\)-Means Clustering

The S3 method split.hyperframekm() splits a hyperframekm by the \(k\)-means clustering indices of the one-and-only-one (Section 25.13) ppp-hypercolumn. The returned object is a grouped hyper data frame with grouping structure

  • ~.id/.cluster, if the input is a hyper data frame
  • ~ <existing/grouping/structure>/.cluster, if the input is a grouped hyper data frame. Note that the grouping level .id is believed to be equivalent to the lowest level of existing grouping structure.

Listing 25.29 splits the hyper data frame fluM (Listing 25.3) by the \(k\)-means clustering of the ppp-hypercolumn fluM$pattern.

Listing 25.29: Example: function split.hyperframekm() (Listing 25.3)
set.seed(13); fluM |> 
  kmeans.hyperframe(formula = ~ x + y, centers = 3L) |> 
  split()
# Grouped Hyper Data Frame: ~.id/.cluster
# 
# 24 .cluster nested in
# 8 .id
# 
#    pattern .id .cluster frameid
# 1    (ppp)   1        1      13
# 2    (ppp)   1        2      13
# 3    (ppp)   1        3      13
# 4    (ppp)   2        1      22
# 5    (ppp)   2        2      22
# 6    (ppp)   2        3      22
# ✂️ --- output truncated --- ✂️