The S3 generic function keyval() finds various function values (default being the recommended) in a function-value-table, or an R object containing one or more function-value-tables. Package groupedHyperframe (v0.3.2) implements the following S3 methods (Table 15.3),
The S3 method keyval.fv() finds various function values (default being the recommended) in the function-value-table, with the corresponding function argument as the vectornames. Listing 15.5 finds the recommended function value in the function-value-table spruces_k (Listing 15.2).
15.2 Cumulative Average Vertical Height of Trapzoidal Integration
The S3 generic function cumvtrapz() has been introduced in Section 11.1 (Table 11.1). The S3 method cumvtrapz.fv() calculate the cumulative average vertical height of the trapezoidal integration (Section 11.1) under the recommended function values (Figure 15.2).
Listing 15.7: Figure: Visualize cumvtrapz of markcorr()
The S3 generic function .rmax() has been introduced in Section 27.10 (Table 27.9). The S3 method .rmax.fv() (Listing 15.8), often used as an internal utility function, simply grabs the maximum value of the \(r\)-vector in a function-value-table.
Function spatstat.explore::markcorr() is the workhorse inside functions Emark(), Vmark() and markvario() (v3.6.0.1). Function markcorr() relies on the un-exported workhorse function spatstat.explore:::sewsmod(), whose default method = "density" contains a ratio of two kernel density estimates. Due to the floating-point precision of R (Listing 15.9), such density ratios may have exceptional/illegal returns of
0 from \(0/\delta\), or Inf from \(\delta/0\), with a real number\(\delta\geq\) (approximately) 2.6e-324
NaN from \(0/\varepsilon\) or \(\varepsilon/0\), with a real number \(\varepsilon\leq\) (approximately) 2.5e-324
Listing 15.9: Review: exceptional/illegal ratio due to floating-point precision (R Core Team 2025)
Function spatstat.explore::markcorr() provides a default argument of parameter \(r\)-vector (Section 27.10), at which the mark correlation function \(k_f(r)\) are evaluated. The S3 method spatstat.explore::print.fv() (Listing 15.10) prints the recommended range (and available range) of \(r\)-vector.
spruces_k |> spatstat.explore::print.fv()# Function value object (class 'fv')# for the function r -> k[mm](r)# ................................................................................# Math.label Description # r r distance argument r # theo {k[mm]^{iid}}(r) theoretical value (independent marks) for k[mm](r)# trans {hat(k)[mm]^{trans}}(r) translation-corrected estimate of k[mm](r) # iso {hat(k)[mm]^{iso}}(r) Ripley isotropic correction estimate of k[mm](r) # ................................................................................# Default plot formula: .~r# where "." stands for 'iso', 'trans', 'theo'# Recommended range of argument r: [0, 9.5]# Available range of argument r: [0, 9.5]# Unit of length: 1 metre
Exceptional/illegal values of 0, Inf and/or NaN may appear in the mark correlation function \(k_f(r)\), if the \(r\)-vector goes well beyond the recommended range. The author constructs a malformed function-value-table fv_mal (Listing 15.11, Listing 15.12) to demonstrate various recovery procedures applicable in such cases.
Listing 15.11: Data: a malformed function-value-table fv_mal with \(r\)-vector out-of-range
The helper function lastLegal() (Listing 15.16, Listing 15.17) returns the index of the last consecutive legal values in a double (Listing 15.13) vector, i.e., the first exceptional/illegal value of 0, Inf, or NaN appears at the next index. The term “legal”, as in the function lastLegal(), is defined as
a double scalar being not-NA_real_, not-NaN, not-Inf, and with absolute value greater than .Machine$double.eps (Listing 15.14, Listing 15.15).
Listing 15.13: Advanced: NaN and Inf are double, not integer(R Core Team 2025)
The term Legal\(r_\text{max}\) indicates (the index) of the \(r\)-vector, where the last of the consecutive legal recommended function values appears. In Listing 15.17, the last consecutive legal recommended-function-value of the malformed function-value-table fv_mal (Listing 15.11) of \(k_f(r)=1.550\) appears at the 75-th index of the \(r\)-vector, i.e., \(r=74\).
Legality of the function spatstat.explore::markcorr() returns depends not only on the input point-pattern, but also on the values of the \(r\)-vector. In other words, the creation of a function-value-table by function markcorr() is a numerical procedure. Therefore, the discussion of Legal \(r_\text{max}\) pertains to the function-value-table (fv.object, Chapter 15), instead of to the point-pattern (ppp.object, Chapter 27).
Example: Legality of spatstat.explore::markcorr() return depends on \(r\)-vector
spatstat.data::spruces |> spatstat.explore::markcorr(r =seq.int(from =0, to =100, by = .1)) |>keyval.fv() |>lastLegal()# [1] 742# attr(,"value")# 74.1 # 0.3191326
The S3 generic functions .illegal2theo() and .disrecommend2theo() are exploratory approaches to remove the illegal recommended function values (Section 15.4) from a function-value-table. These approaches replace the recommended function values with the theoretical values starting at different locations in the function argument (Table 15.2, Listing 15.4), and return an updated function-value-table. Package groupedHyperframe (v0.3.2) implements the following S3 methods (Table 15.4, Table 15.5),
Function .illegal2theo.fv() (Figure 15.3) replaces the recommended function values after the first illegal \(r\) (Section 15.4) of the malformed function-value-table fv_mal (Listing 15.11) with its theoretical values.
Listing 15.18: Advanced: function .illegal2theo.fv()
par(mar =c(4, 4, 1, 1))fv_mal |>.illegal2theo() |> spatstat.explore::plot.fv(xlim =c(0, 100), main =NULL)# r≥75.0 replaced with theo
Figure 15.3: Replaces with theoretical values after the first illegal \(r\)
An experienced reader may wonder: is it truly advantageous to compute a coarse function-value-table and then perform interpolation and/or smoothing, rather than computing a fine function-value-table to start with? This is an excellent question! In fact, we observe no substantial difference in computation time via package microbenchmark(Mersmann 2024, v1.5.0) even when the grid of the \(r\)-vector is 100 times finer (Listing 15.25), as of package spatstat.explore (v3.6.0.1)! This observation justifies the use of the plain-and-naïve trapezoidal integration (Chapter 11, Section 11.1) on a finefv.object (Figure 15.8 B), rather than employing more sophisticated numerical integration methods, e.g., the Simpson’s rulepracma::simpson(), the adaptive Simpson quadraturepracma::quad(), etc. on an interpolation and/or smoothing of a coarsefv.object (Figure 15.5, Figure 15.6, Figure 15.7).
Listing 15.25: Advanced: coarse vs fine fv.object, benchmarks
Code
suppressPackageStartupMessages(library(spatstat))microbenchmark::microbenchmark(coarse =Emark(spruces, r = r_coarse),fine =Emark(spruces, r = r_fine)) |>suppressWarnings()# Unit: milliseconds# expr min lq mean median uq max neval cld# coarse 1.937086 1.954655 2.235100 1.966729 1.983723 20.019726 100 a# fine 2.270457 2.313979 2.503519 2.331116 2.362338 5.206918 100 a
Listing 15.26: Figure: Trapezoidal Integration, coarse vs. fine
R Core Team. 2025. R: A Language and Environment for Statistical Computing. Vienna, Austria: R Foundation for Statistical Computing. https://www.R-project.org/.