| Title: | An Integration Framework for Agricultural Analytics |
| Version: | 0.1.0 |
| Description: | Assembles agricultural analyses around a single unit of observation, the management unit within a season, and keeps climate, soil and remote-sensing covariates aligned to it. Covariates are aggregated over phenological windows derived from accumulated growing degree days rather than calendar months, following McMaster and Wilhelm (1997) <doi:10.1016/S0168-1923(97)00027-0>. Models are validated with spatial resampling by default, since random cross-validation inflates apparent skill when observations are spatially autocorrelated, as shown by Roberts and others (2017) <doi:10.1111/ecog.02881>. Prediction intervals use split conformal inference after Lei and others (2018) <doi:10.1080/01621459.2017.1307116>. Data sources and learning algorithms are supplied through registries so that new providers and methods can be added without modifying the package. |
| License: | MIT + file LICENSE |
| Encoding: | UTF-8 |
| Language: | en-GB |
| Depends: | R (≥ 4.1.0) |
| Imports: | graphics, grDevices, stats, utils |
| Suggests: | testthat (≥ 3.0.0), ranger, xgboost, Cubist, glmnet, kernlab, mgcv, treeshap, nasapower, chirps, daymetr, geodata, terra, agridat, knitr, rmarkdown |
| VignetteBuilder: | knitr |
| Config/testthat/edition: | 3 |
| URL: | https://github.com/mqfarooqi1/AgriFusionR |
| BugReports: | https://github.com/mqfarooqi1/AgriFusionR/issues |
| Config/roxygen2/version: | 8.0.0 |
| NeedsCompilation: | no |
| Packaged: | 2026-08-20 23:18:42 UTC; faroo |
| Author: | Muhammad Farooqi |
| Maintainer: | Muhammad Farooqi <mqfarooqi@gmail.com> |
| Repository: | CRAN |
| Date/Publication: | 2026-08-26 20:20:08 UTC |
AgriFusionR: an integration framework for agricultural analytics
Description
R is already well supplied with machine learning, geospatial and agronomic packages. What it lacks is the layer that joins them: a single object that holds a management unit and its season, keeps climate, soil and remote-sensing covariates aligned to it, aggregates them over the crop's phenology rather than the calendar, and validates the result in a way that survives spatial autocorrelation. That layer is what this package provides.
Getting started
agri_project() builds the object; add_climate() and its siblings attach
covariates; phenology_windows() derives thermal-time stages;
build_features() reduces everything to one row per unit and season;
check_project() looks for leakage and other faults; train_model() fits
and validates; explain(), uncertainty() and report() interpret.
Extending it
register_source() and register_learner() add data providers and
algorithms without modifying the package.
Author(s)
Maintainer: Muhammad Farooqi mqfarooqi@gmail.com (ORCID)
Authors:
Muhammad Farooqi mqfarooqi@gmail.com (ORCID)
See Also
Useful links:
Report bugs at https://github.com/mqfarooqi1/AgriFusionR/issues
Attach a covariate layer to a project
Description
Fetches covariates from a registered source and attaches them to the
project, keyed to the management unit and season. add_climate(),
add_soil() and add_satellite() differ only in the layer they write to
and the sources they expect; all three are thin calls to the source
registry, so a source added with register_source() is usable immediately.
Usage
add_layer(p, source, layer, overwrite = FALSE, ...)
add_climate(p, source = "demo", layer = "climate", overwrite = FALSE, ...)
add_soil(p, source = "demo_soil", layer = "soil", overwrite = FALSE, ...)
add_satellite(p, source, layer = "satellite", overwrite = FALSE, ...)
Arguments
p |
An |
source |
Name of a registered source. See |
layer |
Name to store the layer under. |
overwrite |
Replace an existing layer of the same name. |
... |
Passed to the source's |
Details
Nothing is fetched twice: a layer already present is returned unchanged
unless overwrite = TRUE.
Value
The project, with the layer attached and the operation recorded in its provenance.
See Also
register_source(), list_sources(), build_features()
Examples
p <- agri_project(demo_agri_data(n_units = 4, n_seasons = 2))
p <- add_climate(p, source = "demo")
names(p$layers)
head(p$layers$climate$data)
Create an agricultural analysis project
Description
Builds the object every other function in the package operates on. The unit
of observation is a management unit within a season: a field, plot or
administrative area, together with the window over which the crop grew. Each
observation is keyed by (unit_id, season_id), and every covariate layer
added later must reduce to that key.
Usage
agri_project(
data,
unit_id = NULL,
x = NULL,
y = NULL,
season = NULL,
start = NULL,
end = NULL,
crop = NULL,
crs = 4326,
cache_dir = NULL
)
Arguments
data |
A data frame with one row per management unit and season. |
unit_id, x, y |
Column names giving the unit identifier and its
coordinates. Detected from names such as |
season |
Column naming the season, typically a year. Detected from
|
start, end |
Columns giving the start and end of the growing window as
dates. Detected from names such as |
crop |
Column giving the crop, if more than one is present. |
crs |
Coordinate reference system as an EPSG code. Only 4326 is currently treated as geographic; anything else is taken as projected, which changes how distances are computed. |
cache_dir |
Directory for cached downloads. Defaults to a session temporary directory, so nothing is written outside it unless asked. |
Details
Column roles are detected from common names when not given explicitly, so
agri_project(data) usually works unchanged. Detection is reported by the
print method, and can always be overridden.
Value
An object of class agri_project.
See Also
add_climate(), build_features(), check_project()
Examples
d <- demo_agri_data(n_units = 6, n_seasons = 2)
p <- agri_project(d)
p
Build the model design matrix
Description
Reduces every attached layer to one row per management unit and season, which is the key the whole package is organised around.
Usage
build_features(
p,
aggregation = c("phenology", "monthly", "season"),
stats = c("mean", "sum", "min", "max"),
stress = TRUE,
heat_threshold = 30,
dry_threshold = 1
)
Arguments
p |
An |
aggregation |
How to group days within a season. |
stats |
Statistics to compute for each variable and group. |
stress |
Whether to derive stress-day counters. |
heat_threshold |
Daily maximum temperature, in degrees Celsius, above which a day counts as heat stress. |
dry_threshold |
Daily rainfall, in millimetres, below which a day counts as dry. |
Details
Daily layers are aggregated within phenological stage by default, so that a
feature such as prcp_sum_grain_fill carries the same meaning across sites
that sowed weeks apart. Aggregating by calendar month instead is available
for comparison, and is the usual practice in the literature; it is offered
so the difference can be measured rather than assumed.
Stress counters are derived before aggregation: days above the heat threshold, days below freezing, dry days, and the longest dry spell in the season.
Value
The project, with features populated.
See Also
phenology_windows(), check_project(), train_model()
Examples
p <- agri_project(demo_agri_data(n_units = 6, n_seasons = 2))
p <- add_climate(p, source = "demo")
p <- phenology_windows(p)
p <- build_features(p)
dim(p$features)
Check a project for the faults that invalidate an analysis
Description
Runs the checks that are cheap to automate and expensive to discover late.
Usage
check_project(p, mad_k = 3, max_missing = 0.2)
Arguments
p |
An |
mad_k |
Number of median absolute deviations beyond which a value is flagged. Three is conventional. |
max_missing |
Proportion of missing values in a feature above which it is reported. |
Details
The most important is the leakage guard: a covariate window that extends past the harvest it is supposed to predict produces a model that cannot be deployed and a skill estimate that means nothing. It is easy to introduce by fetching a fixed date range for every site, and hard to see afterwards.
Also checked: duplicated unit-season keys, coordinates outside plausible bounds, missingness by column, and univariate outliers by the median absolute deviation, which is resistant to the outliers it is looking for.
Value
A data frame of issues with columns severity, check and
detail, invisibly returned and printed. Zero rows means every check
passed.
See Also
build_features(), train_model()
Examples
p <- agri_project(demo_agri_data(n_units = 6, n_seasons = 2))
p <- add_climate(p, source = "demo")
check_project(p)
Indicative crop thermal parameters
Description
Base and upper temperatures, and cumulative growing degree days at the end of each phenological stage, for a small set of crops.
Usage
crop_parameters(crop = NULL)
Arguments
crop |
Optional crop name. When |
Value
A data frame with columns crop, t_base, t_upper, stage and
gdd_end, ordered by crop and cumulative thermal time.
Calibrate before trusting
These values are indicative defaults for getting started, not calibrated
constants. Thermal requirements vary substantially with cultivar,
photoperiod and region, and a stage boundary that is wrong by a fortnight
will misattribute the weather a model sees. Supply your own thresholds
through the stages argument of phenology_windows() for any analysis you
intend to publish.
See Also
growing_degree_days(), phenology_windows()
Examples
crop_parameters("wheat")
unique(crop_parameters()$crop)
A demonstration agricultural data set
Description
Generates a multi-field, multi-season data set whose yields are produced by a known process, for examples, tests and teaching.
Usage
demo_agri_data(n_units = 40, n_seasons = 4, crop = "maize", start_year = 2018)
Arguments
n_units |
Number of management units. |
n_seasons |
Number of seasons per unit. |
crop |
Crop name, used for thermal parameters. |
start_year |
First season. |
Details
The data are simulated, not observed. Yield is built from rainfall accumulated during grain fill, the count of days above 30 degrees during silking, soil clay content, a smooth spatial trend and a season effect. Because those drivers are known exactly, an analysis of this data set can be checked against the truth rather than against a previous run.
Generation is deterministic: no random number generator is used and the global RNG state is not touched, so repeated calls return identical data.
Value
A data frame with one row per unit and season, containing coordinates, the growing window, soil clay, yield, and the true driver values used to build it.
See Also
Examples
d <- demo_agri_data(n_units = 6, n_seasons = 2)
str(d)
Explain a fitted model
Description
Permutation importance and partial dependence, both computed so that the answer means what it appears to mean.
Usage
explain(
object,
method = c("importance", "pdp", "ale", "ice", "shap"),
features = NULL,
n_perm = 5,
grid = 20,
...
)
## S3 method for class 'agri_model'
explain(
object,
method = c("importance", "pdp", "ale", "ice", "shap"),
features = NULL,
n_perm = 5,
grid = 20,
...
)
Arguments
object |
A model fitted by |
method |
Which explanation to compute; see the section above. |
features |
Features to examine. Defaults to all for |
n_perm |
Number of shuffles per feature and fold. The function uses the
ambient random state; call |
grid |
Number of grid points for partial dependence. |
... |
Ignored. |
Details
Importance is measured out of fold: within each resampling fold, one feature of the held-out rows is shuffled and the increase in that fold's error is recorded. In-sample permutation importance on a flexible learner mostly measures how much the model was able to memorise, which is why it is not offered here.
Note that permutation importance is unreliable when features are strongly correlated, which climate features usually are: shuffling one of a pair of near-duplicates leaves the other to carry the signal, so both look unimportant. Treat the ranking as indicative and read it alongside partial dependence.
Value
A data frame. For "importance", one row per feature with the mean
and standard deviation of the error increase. For "pdp" and "ale", one
row per feature and grid value. For "ice", one row per observation,
feature and grid value. For "shap", one row per observation and feature.
Which method answers which question
"importance"How much does the model rely on this feature? Measured out of fold, so it reflects generalisation rather than memorisation.
"pdp"What shape is the relationship, averaged over everything else? Misleading when features are strongly correlated, because it averages over combinations that never occur.
"ale"The same question, but accumulated over local differences within narrow windows of the feature, so it never evaluates the model on impossible combinations. Prefer it to partial dependence whenever the predictors are correlated, which for weather features they always are (Apley and Zhu, 2020).
"ice"Partial dependence for each observation separately. Curves that fan out reveal interactions that the averaged curve hides.
"shap"Exact tree SHAP values, attributing each prediction among the features. Requires the treeshap package and a tree-based learner.
References
Apley, D. W. & Zhu, J. (2020) "Visualizing the effects of predictor variables in black box supervised learning models." Journal of the Royal Statistical Society Series B 82, 1059-1086. doi:10.1111/rssb.12377
See Also
Examples
p <- agri_project(demo_agri_data(n_units = 12, n_seasons = 3))
p <- build_features(phenology_windows(add_climate(p)))
m <- train_model(p, "yield", algorithm = "lm", k = 3)
set.seed(1)
head(explain(m), 5)
head(explain(m, "ale", features = "prcp_sum_grain_fill", grid = 6))
Growing degree days
Description
Daily thermal time by the capped-average method: the mean of the daily maximum and minimum, each first constrained to the interval between the base and upper temperatures, less the base temperature, with negative values set to zero.
Usage
growing_degree_days(tmin, tmax, t_base = 5, t_upper = Inf)
Arguments
tmin, tmax |
Numeric vectors of daily minimum and maximum temperature in degrees Celsius. |
t_base |
Base temperature below which development is taken to stop. |
t_upper |
Temperature above which further warmth adds no development. |
Details
This is the interpretation McMaster and Wilhelm (1997) label Method 1 with a horizontal cut-off. The choice matters: the two common interpretations of the same equation can differ by hundreds of degree days over a season, so the method is stated rather than left implicit.
Value
A numeric vector of daily growing degree days, never negative.
References
McMaster, G. S. & Wilhelm, W. W. (1997) "Growing degree-days: one equation, two interpretations." Agricultural and Forest Meteorology 87, 291-300. doi:10.1016/S0168-1923(97)00027-0
See Also
crop_parameters(), phenology_windows()
Examples
growing_degree_days(tmin = c(4, 8, 12), tmax = c(18, 24, 33), t_base = 5)
List registered sources and learners
Description
List registered sources and learners
Usage
list_sources()
list_learners()
Value
A data frame describing what is currently registered.
See Also
register_source(), register_learner()
Examples
list_sources()
list_learners()
Derive phenological windows from accumulated thermal time
Description
Labels every day of every growing season with the phenological stage the crop had reached by that date, based on accumulated growing degree days, and summarises the resulting windows.
Usage
phenology_windows(
p,
crop = NULL,
stages = NULL,
t_base = NULL,
t_upper = NULL,
layer = "climate"
)
Arguments
p |
An |
crop |
Crop name used to look up thermal parameters. When |
stages |
Optional data frame of custom thresholds with columns |
t_base, t_upper |
Optional overrides for the base and upper temperatures. |
layer |
Name of the climate layer to read. |
Details
Aligning covariates to phenology rather than to the calendar is the point of
the exercise. "Rainfall in September" means different things to two crops
sown six weeks apart; "rainfall during grain fill" means the same thing to
both. Aggregation in build_features() uses these labels.
Value
The project, with daily stage labels attached to the climate layer
and a window summary available as p$windows.
See Also
growing_degree_days(), crop_parameters(), build_features()
Examples
p <- agri_project(demo_agri_data(n_units = 4, n_seasons = 2))
p <- add_climate(p, source = "demo")
p <- phenology_windows(p)
head(p$windows)
Plot a fitted model
Description
Plot a fitted model
Usage
## S3 method for class 'agri_model'
plot(
x,
type = c("observed", "residuals", "importance"),
top = 12,
n_perm = 3,
...
)
Arguments
x |
A model fitted by |
type |
|
top |
Number of features for |
n_perm |
Shuffles per feature for |
... |
Passed to |
Value
x, invisibly. Called for the plot.
See Also
plot_map(), plot_effect(), plot_uncertainty()
Examples
p <- agri_project(demo_agri_data(n_units = 20, n_seasons = 3))
p <- build_features(phenology_windows(add_climate(p)), stats = "sum")
m <- train_model(p, "yield", algorithm = "lm", k = 3)
plot(m)
plot(m, type = "residuals")
Plot a project's management units
Description
Draws the units in space, sized by how many seasons each was observed in. Worth looking at before modelling: clustered units are the situation that makes random cross-validation misleading, and it is easier to see than to infer.
Usage
## S3 method for class 'agri_project'
plot(x, ...)
Arguments
x |
An |
... |
Passed to |
Value
x, invisibly. Called for the plot.
See Also
plot.agri_resample(), plot_map()
Examples
p <- agri_project(demo_agri_data(n_units = 20, n_seasons = 3))
plot(p)
Plot a resampling scheme
Description
Draws each unit coloured by the fold it is held out in, so that what the blocking actually did can be seen rather than assumed. Blocks that look interleaved are not blocking anything.
Usage
## S3 method for class 'agri_resample'
plot(x, ...)
Arguments
x |
An |
... |
Passed to |
Value
x, invisibly. Called for the plot.
See Also
resample_scheme(), plot.agri_project()
Examples
p <- agri_project(demo_agri_data(n_units = 24, n_seasons = 2))
p <- build_features(phenology_windows(add_climate(p)), stats = "sum")
plot(resample_scheme(p, method = "spatial_block", k = 4))
Plot a marginal effect
Description
Draws accumulated local effects, partial dependence, or individual conditional expectation curves for one feature.
Usage
plot_effect(model, feature, method = c("ale", "pdp", "ice"), grid = 20, ...)
Arguments
model |
A model fitted by |
feature |
Name of the feature to show. |
method |
|
grid |
Number of grid points. |
... |
Passed to |
Details
Accumulated local effects is the default deliberately. Partial dependence averages the model over feature combinations that may never occur, which for correlated weather features it routinely does; ALE accumulates local differences instead and does not.
Value
The computed effect, invisibly.
See Also
Examples
p <- agri_project(demo_agri_data(n_units = 20, n_seasons = 3))
p <- build_features(phenology_windows(add_climate(p)), stats = "sum")
m <- train_model(p, "yield", algorithm = "lm", k = 3)
plot_effect(m, "prcp_sum_grain_fill")
Map predictions, residuals or uncertainty
Description
Draws each management unit at its coordinates, coloured by what the model produced there. The uncertainty map is the one worth reading: a model can have acceptable average skill and still be useless over part of its area, and only the map shows where.
Usage
plot_map(
model,
what = c("prediction", "residual", "uncertainty"),
season = NULL,
level = 0.9,
...
)
Arguments
model |
A model fitted by |
what |
|
season |
Optional season to show. Defaults to the first, since overplotting several seasons at one location hides all but the last. |
level |
Coverage level for |
... |
Passed to |
Value
A data frame of the plotted values, invisibly.
See Also
plot.agri_model(), uncertainty()
Examples
p <- agri_project(demo_agri_data(n_units = 24, n_seasons = 2))
p <- build_features(phenology_windows(add_climate(p)), stats = "sum")
m <- train_model(p, "yield", algorithm = "lm", k = 4)
plot_map(m, "residual")
Plot prediction intervals and their coverage
Description
Observations are sorted by prediction and drawn with their conformal
interval, with the ones the interval missed picked out. A calibrated
interval should miss about 1 - level of them, scattered rather than
concentrated at one end.
Usage
plot_uncertainty(model, level = 0.9, ...)
Arguments
model |
A model fitted by |
level |
Coverage level. |
... |
Passed to |
Value
A data frame of predictions, bounds and whether each was covered, invisibly.
See Also
uncertainty(), predict.agri_model()
Examples
p <- agri_project(demo_agri_data(n_units = 20, n_seasons = 3))
p <- build_features(phenology_windows(add_climate(p)), stats = "sum")
m <- train_model(p, "yield", algorithm = "lm", k = 3)
plot_uncertainty(m)
Predict from a fitted model
Description
Predict from a fitted model
Usage
## S3 method for class 'agri_model'
predict(object, newdata = NULL, interval = FALSE, level = 0.9, ...)
Arguments
object |
A model fitted by |
newdata |
Optional data frame of features. When omitted, predictions for the training rows are returned, alongside the out-of-fold predictions, which are the honest ones. |
interval |
Attach conformal prediction intervals. |
level |
Coverage level for the interval. |
... |
Ignored. |
Value
A data frame with the keys, .pred, and when newdata is omitted
.pred_oof; plus .lower and .upper when interval = TRUE.
See Also
Examples
p <- agri_project(demo_agri_data(n_units = 12, n_seasons = 3))
p <- build_features(phenology_windows(add_climate(p)))
m <- train_model(p, "yield", algorithm = "lm", k = 3)
head(predict(m, interval = TRUE))
Register a learning algorithm
Description
Adds an algorithm to the learner registry so that train_model() can select
it by name. Keeping learners behind a registry is what allows the package to
delegate to established implementations rather than reimplement them.
Usage
register_learner(name, fit, predict, requires = character(), description = "")
Arguments
name |
Name used to select the learner. |
fit |
A function |
predict |
A function |
requires |
Character vector of packages the learner needs. |
description |
A one-line human description. |
Value
Invisibly, the registered name.
See Also
list_learners(), register_source()
Examples
register_learner("mean_only",
fit = function(x, y, ...) mean(y),
predict = function(object, newx, ...) {
rep(object, nrow(newx))
})
"mean_only" %in% list_learners()$name
Register a covariate source
Description
Adds a data provider to the source registry, making it available to
add_climate(), add_soil() and add_satellite(). This is the extension
point for new providers: no change to the package is needed.
Usage
register_source(
name,
fetch,
provides,
kind = c("series", "static"),
requires_network = TRUE,
description = ""
)
Arguments
name |
Name used to select the source, for example |
fetch |
A function with signature |
provides |
Character vector of the variables the source returns. |
kind |
Either |
requires_network |
Whether the source needs internet access. Sources that do are skipped in tests and examples. |
description |
A one-line human description. |
Value
Invisibly, the registered name.
See Also
list_sources(), register_learner()
Examples
register_source("flat",
fetch = function(units, seasons, ...) {
data.frame(unit_id = units$unit_id, elevation = 100)
},
provides = "elevation", kind = "static",
requires_network = FALSE)
"flat" %in% list_sources()$name
Write a model card
Description
Turns the provenance ledger and the validation results into a model card in Markdown: what was fitted, on what data, validated how, with which caveats.
Usage
report(object, file = NULL, top = 10, ...)
## S3 method for class 'agri_model'
report(object, file = NULL, top = 10, ...)
Arguments
object |
A model fitted by |
file |
Optional path to write to. The text is always returned. |
top |
Number of features to list. |
... |
Ignored. |
Details
The limitations section is generated from the model's own diagnostics rather than written by hand, so it cannot fall out of step with the results. If random cross-validation would have overstated the model, the card says so.
Value
A character vector of Markdown lines, invisibly when written to file.
See Also
Examples
p <- agri_project(demo_agri_data(n_units = 12, n_seasons = 3))
p <- build_features(phenology_windows(add_climate(p)))
m <- train_model(p, "yield", algorithm = "lm", k = 3)
cat(head(report(m), 20), sep = "\n")
Build a resampling scheme
Description
Constructs the train and test splits used to estimate predictive skill.
Usage
resample_scheme(
p,
method = c("spatial_block", "leave_location_out", "forward_season", "random"),
k = 5,
buffer = 0
)
Arguments
p |
An |
method |
|
k |
Number of folds. |
buffer |
Exclude training rows whose unit lies within this distance of any test unit. Kilometres when the project is geographic, otherwise coordinate units. Buffering removes the residual optimism that blocking alone leaves at block edges. |
Value
An object of class agri_resample.
Why the default is spatial
Agricultural observations near one another share weather, soil and management. Under random k-fold cross-validation a test point almost always has a near-duplicate in the training set, so the estimate answers "how well does this interpolate between my own plots" when the question asked is usually "how well does this predict somewhere new". The gap between the two is often large. Roberts et al. (2017) set out the problem and the blocking remedies; Meyer and Pebesma (2021) show how far a model can be trusted outside the space it was trained in.
"random" remains available, and train_model() reports both so the
difference can be quantified rather than argued about.
References
Roberts, D. R. et al. (2017) "Cross-validation strategies for data with temporal, spatial, hierarchical, or phylogenetic structure." Ecography 40, 913-929. doi:10.1111/ecog.02881
Meyer, H. & Pebesma, E. (2021) "Predicting into unknown space? Estimating the area of applicability of spatial prediction models." Methods in Ecology and Evolution 12, 1620-1633. doi:10.1111/2041-210X.13650
See Also
Examples
p <- agri_project(demo_agri_data(n_units = 12, n_seasons = 2))
p <- add_climate(p, source = "demo")
p <- phenology_windows(p)
p <- build_features(p)
resample_scheme(p, method = "spatial_block", k = 3)
Stack weights from a fitted ensemble
Description
Reports how much each base learner contributed to a "stack" model, which
is usually more informative than the ensemble's accuracy alone: a stack that
puts all its weight on one learner is telling you the others added nothing.
Usage
stack_weights(model)
Arguments
model |
A model fitted by |
Value
A named numeric vector of weights summing to one.
See Also
train_model(), list_learners()
Examples
p <- agri_project(demo_agri_data(n_units = 14, n_seasons = 3))
p <- build_features(phenology_windows(add_climate(p)), stats = "sum")
set.seed(1)
m <- train_model(p, "yield", algorithm = "stack", k = 3,
compare_random = FALSE)
stack_weights(m)
Train and honestly validate a model
Description
Fits a model to predict target from the features built for the project,
estimating skill by spatial resampling rather than random folds.
Usage
train_model(
p,
target,
algorithm = "auto",
resampling = NULL,
method = "spatial_block",
k = 5,
buffer = 0,
compare_random = TRUE,
...
)
Arguments
p |
An |
target |
Name of the response column in the project's observations. |
algorithm |
A registered learner, or |
resampling |
A |
method, k, buffer |
Passed to |
compare_random |
Also evaluate with random folds, to quantify the optimism that random cross-validation would have introduced. |
... |
Passed to the learner's |
Details
By default the same model is also evaluated with random folds and both results are reported. The difference between them is the amount by which random cross-validation would have overstated the model, and it is worth knowing before any figure is published.
Missing predictor values are filled with the median of the training rows of each fold, computed inside the fold so that no information crosses the split.
Value
An object of class agri_model.
See Also
resample_scheme(), explain(), uncertainty(), report()
Examples
p <- agri_project(demo_agri_data(n_units = 12, n_seasons = 3))
p <- add_climate(p, source = "demo")
p <- phenology_windows(p)
p <- build_features(p)
m <- train_model(p, target = "yield", algorithm = "lm", k = 3)
m
Prediction intervals by split conformal inference
Description
Turns the out-of-fold residuals into prediction intervals with a distribution-free finite-sample coverage guarantee.
Usage
uncertainty(object, level = 0.9, ...)
## S3 method for class 'agri_model'
uncertainty(object, level = 0.9, ...)
Arguments
object |
A model fitted by |
level |
Target coverage, between 0 and 1. |
... |
Ignored. |
Details
Conformal inference is used because it is the only interval method that works uniformly across a registry of arbitrary learners: it assumes nothing about the model or the error distribution, only that the calibration and prediction data are exchangeable. Because the residuals come from spatial resampling, the resulting intervals inherit that honesty; intervals calibrated on random folds would be too narrow for the same reason random cross-validation is too optimistic.
Value
An object of class agri_uncertainty giving the interval
half-width, the target level and the estimated empirical coverage.
Reported coverage
The half-width and the coverage check cannot come from the same residuals without being circular. Coverage is therefore estimated by two-fold splitting of the residual vector: calibrate on one half, measure on the other, and average the two directions.
References
Lei, J., G'Sell, M., Rinaldo, A., Tibshirani, R. J. & Wasserman, L. (2018) "Distribution-free predictive inference for regression." Journal of the American Statistical Association 113, 1094-1111. doi:10.1080/01621459.2017.1307116
See Also
train_model(), predict.agri_model()
Examples
p <- agri_project(demo_agri_data(n_units = 12, n_seasons = 3))
p <- build_features(phenology_windows(add_climate(p)))
m <- train_model(p, "yield", algorithm = "lm", k = 3)
uncertainty(m)
Accessors for project components
Description
Accessors for project components
Usage
units_of(p)
seasons_of(p)
provenance(p)
Arguments
p |
An |
Value
units_of() returns one row per management unit with its
coordinates; seasons_of() one row per unit and season with the growing
window; provenance() the ledger of operations applied so far.
Examples
p <- agri_project(demo_agri_data(n_units = 4, n_seasons = 2))
units_of(p)
head(seasons_of(p))