27  vectorlist from anylist

The examples in Chapter 27 require that the search path contains the following namespaces,

library(groupedHyperframe)

Package groupedHyperframe (v0.3.0.20251020) defines a derived S3 class 'vectorlist' (Section 27.1), which inherits from the class 'anylist' (Chapter 11).

Package groupedHyperframe implements the following S3 method dispatches to the class 'vectorlist' (Listing 27.1, Table 27.1),

Listing 27.1: Table: S3 method dispatches groupedHyperframe::*.vectorlist
Code
methods2kable(class = 'vectorlist', package = 'groupedHyperframe', all.names = TRUE)
Table 27.1: S3 method dispatches groupedHyperframe::*.vectorlist (v0.3.0.20251020)
visible from generic isS4
aggregate.vectorlist TRUE groupedHyperframe stats::aggregate FALSE
t.vectorlist TRUE groupedHyperframe base::t FALSE

Data set Kovesi (Section 8.13) is a hyperframe. The character-hypercolumn Kovesi$values has the class 'anylist'. This is a length-41 listof character vectors of all-equal length of 256.

Data: an anylist object Kovesi$values
spatstat.data::Kovesi$values |>
  class()
# [1] "anylist" "listof"  "list"
spatstat.data::Kovesi$values |>
  length()
# [1] 41
spatstat.data::Kovesi$values |>
  lengths() |>
  unique.default()
# [1] 256

27.1 Validity

Function is.vectorlist() inspects whether all elements of an 'anylist'

  • are all atomic vectors;
  • have all-equal vector-mode, as determined by function base::is.vector();
  • have all-equal lengths, i.e., length-per-element. All criteria listed here, especially the last one, are tailored specifically for the summary statistics from Section 3.3.
Example: function is.vectorlist()
spatstat.data::Kovesi$values |>
  is.vectorlist(mode = 'character')
# [1] TRUE
spatstat.data::Kovesi$values |>
  is.vectorlist(mode = 'numeric')
# [1] FALSE

27.2 Creation

Function as.vectorlist() inspects whether the input qualifies as a 'vectorlist' (Section 27.1), and if true, appends the derived class 'vectorlist' to the returned value.

Data: a vectorlist object Kovesi_values
Kovesi_values = spatstat.data::Kovesi$values |>
  as.vectorlist(mode = 'character')
Kovesi_values |> 
  class()
# [1] "vectorlist" "anylist"    "listof"     "list"

27.3 Transpose

The S3 method dispatch t.vectorlist() transposes a vectorlist into another vectorlist, but with the length and lengths of the input switched. The use of the term “transpose”, and the extension of the S3 generic function base::t(), mirrors the use of the default dispatch base:::t.default() to transpose a matrix, i.e., to switch the ncol and nrow of the input. The returned object Kovesi_values_t is a length-256 listof vectors, all elements of which have length-41.

Example: function t.vectorlist()
Kovesi_values_t = Kovesi_values |> 
  t()
Kovesi_values_t |>
  class()
# [1] "vectorlist" "anylist"    "listof"     "list"
Kovesi_values_t |>
  length()
# [1] 256
Kovesi_values_t |>
  lengths() |>
  unique.default()
# [1] 41

The motivation of the derived class 'vectorlist' and the S3 method dispatch t.vectorlist() is that the function spatstat.geom::with.hyperframe() could be slow in a batch process.

Transposed element 1
z1 = spatstat.data::Kovesi |> 
  spatstat.geom::with.hyperframe(expr = values[1L])
stopifnot(identical(Kovesi_values_t[[1L]], z1))
Transposed element 2
z2 = spatstat.data::Kovesi |> 
  spatstat.geom::with.hyperframe(expr = values[2L])
stopifnot(identical(Kovesi_values_t[[2L]], z2))
Transposed element 256
z256 = spatstat.data::Kovesi |> 
  spatstat.geom::with.hyperframe(expr = values[256L])
stopifnot(identical(Kovesi_values_t[[256L]], z256))

The derived class 'vectorlist' is not part of package spatstat.geom (v3.6.0.3). Readers may call the S3 method dispatch t.vectorlist() explicitly as a workaround before package spatstat.geom (ever) implements the class vectorlist.

Workaround: without derived class 'vectorlist'
Kovesi_values_t2 = spatstat.data::Kovesi$values |>
  t.vectorlist()
stopifnot(identical(Kovesi_values_t, Kovesi_values_t2))

27.4 Aggregation

The S3 method dispatch aggregate.vectorlist() aggregates a numeric vectorlist by a factor specified in the parameter by, using the aggregation method provided in the parameter fun. The S3 method dispatch aggregate.vectorlist() returns a vectorlist.

Data: a toy example of vectorlist
set.seed(12); toy_vectorlist = replicate(n = 5L, expr = rnorm(n = 6L), simplify = FALSE)
class(toy_vectorlist) = c('vectorlist', 'anylist', 'listof', 'list')
toy_vectorlist
# Component 1:
# [1] -1.4805676  1.5771695 -0.9567445 -0.9200052 -1.9976421 -0.2722960
# 
# Component 2:
# [1] -0.3153487 -0.6282552 -0.1064639  0.4280148 -0.7777196 -1.2938823
# 
# Component 3:
# [1] -0.77956651  0.01195176 -0.15241624 -0.70346425  1.18887916  0.34051227
# 
# Component 4:
# [1]  0.5069682 -0.2933051  0.2236414  2.0072015  1.0119791 -0.3024592
# 
# Component 5:
# [1] -1.0252448 -0.2673848 -0.1991057  0.1311226  0.1457999  0.3620647
Example: function aggregate.vectorlist()
toy_vectorlist |>
  aggregate(by = factor(c('a', 'a', 'b', 'b', 'b')), fun = pmean)
# a:
# [1] -0.8979582  0.4744571 -0.5316042 -0.2459952 -1.3876808 -0.7830892
# 
# b:
# [1] -0.43261439 -0.18291274 -0.04262683  0.47828660  0.78221939  0.13337258
toy_vectorlist |>
  aggregate(by = factor(c('a', 'a', 'b', 'b', 'b')), fun = pmedian)
# a:
# [1] -0.8979582  0.4744571 -0.5316042 -0.2459952 -1.3876808 -0.7830892
# 
# b:
# [1] -0.7795665 -0.2673848 -0.1524162  0.1311226  1.0119791  0.3405123

Available aggregation methods in parameter fun are the point-wise minima base::pmin(), maxima base::pmax(), means pmean() (default) and medians pmedian().

Example: function pmean()
pmean_1 = toy_vectorlist[3:5] |> 
  do.call(what = pmean)
pmean_2 = toy_vectorlist[3:5] |> 
  .mapply(FUN = c, dots = _, MoreArgs = NULL) |>
  sapply(FUN = mean.default)
all.equal.numeric(pmean_1, pmean_2, tolerance = 1e-18)
# [1] "Mean relative difference: 1.367649e-16"
Example: function pmedian()
pmed_1 = toy_vectorlist[3:5] |> 
  do.call(what = pmedian)
pmed_2 = toy_vectorlist[3:5] |> 
  .mapply(FUN = c, dots = _, MoreArgs = NULL) |>
  sapply(FUN = median.default)
stopifnot(identical(pmed_1, pmed_2))