gpfield is the spatial member of an agricultural-analytics R-package
orchestra. It does change-of-support Gaussian-process regression for
field and multi-environment-trial (MET) data: it smooths a noisy field
surface, predicts at a support different from the one observed (a point
process predicted as paddock-scale block averages, with the predictive
variance propagated through the support map), and -- the part that
matters in practice -- abstains when the data support or the estimated
spatial range cannot bear the requested prediction resolution, rather
than returning a confident wrong surface.
The Gaussian process is a self-contained exact solver in base R, so the package takes no heavy external GP dependency and installs and checks anywhere.
gpfield fits an exact Gaussian process, whose cost grows with the cube
of the number of observations, so it suits field trials rather than very
large datasets. It adds a typed refusal when the estimated range or the
data cannot support the requested prediction, a one-call smoother for
row-column trial layouts (gp_field_smooth()), and output in the
orchestra manifest that the other orchestra packages read.
# install.packages("remotes")
# remotes::install_github("max578/gpfield")
install.packages("gpfield", repos = c('https://max578.r-universe.dev', 'https://cloud.r-project.org'))
Matern covariance, hyperparameters estimated
by marginal likelihood.library(gpfield)
# A noisy field on a 10 x 10 plot grid.
set.seed(1L)
field <- expand.grid(row = seq_len(10L), col = seq_len(10L))
field$yield <- 3 + 0.3 * field$row + sin(field$col / 2) +
rnorm(nrow(field), 0, 0.2)
# Fit the GP.
fit <- gp_fit(gpfield_spec(c("row", "col"), "yield"), field, seed = 1L)
fit
#> <gpfield_fit>
#> kernel: matern
#> n training: 100
#> length-scale (standardised): 4.34
#> range (raw units): 34.31
#> marginal var / noise var: 3.317 / 0.02171
#> log marginal likelihood: 10.6
# Predict two paddock-scale block averages (change of support).
blocks <- block_support(
lower = rbind(c(1, 1), c(6, 6)),
upper = rbind(c(5, 5), c(10, 10))
)
gp_predict(fit, support = "block", blocks = blocks, seed = 1L)
#> <gpfield_prediction>
#> support: block
#> locations: 2
#> mean range: [4.725, 4.778]
#> sd range: [0.03812, 0.03812]
# Ask for a resolution the field cannot support: gpfield abstains.
gp_predict(fit, data.frame(row = c(1, 60), col = c(1, 60)))
#> <gpfield_abstention>
#> scope: gp_predict
#> reason: range_too_short
#> detail: query spacing 83.44 exceeds 1 x the estimated range 34.31; the field cannot be resolved this finely
#> spacing = 83.44
#> range = 34.31
#> spacing_tol = 1
Bug reports and suggestions are welcome through the GitHub issues.
citation("gpfield")
MIT (c) 2026 Max Moldovan. The orchestra is open-source across the board.