| Title: | Detection of Edge Effects in Field Trials via Besag-Kempton Competition |
|---|---|
| Description: | Estimates and evaluates the intraspecific competition coefficient associated with the edge (border) effect in agricultural field trials, using the Besag-Kempton autoregressive model and a least-squares estimator following Darghan, Rivera, Gonzalez and Castellanos (2022) <doi:10.47280/RevFacAgron(LUZ).v39.n1.18>. Provides field-layout generation, spatial weight matrices, a formula interface for arbitrary two-way designs, a simulation-based decision procedure for presence or absence of the edge effect, Moran's I diagnostics, and a 'shiny' application. |
| Authors: | Sergio Gamboa [aut, cre, cph] (Author of the R package), Aquiles Enrique Darghan Contreras [aut, cph] (Author of the method and original code), Carlos Armando Rivera Moreno [aut, cph] (Author of the method and original code), Nair Jose Gonzalez Sotomayor [aut, cph] (Author of the method), Jose Luis Castellanos Coronel [aut, cph] (Author of the method) |
| Maintainer: | Sergio Gamboa <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.1.0 |
| Built: | 2026-10-05 10:28:39 UTC |
| Source: | https://github.com/segamboam/bordereffect |
Fits the least-squares Besag-Kempton competition coefficient for
a two-way (treatment + block) field trial. The projection onto the design's
column space is obtained from model.matrix(formula, data) via qr.resid(),
so any design expressible as an R formula is supported.
border_effect(formula, data, coords, weights = NULL)border_effect(formula, data, coords, weights = NULL)
formula |
A model formula, e.g. |
data |
A data.frame containing the response and the design factors. |
coords |
A |
weights |
Optional precomputed weight matrix (see |
An object of class border_effect: a list with kappa, call,
formula, terms, weights, residuals, fitted, coords, data.
field_layout() reserves the column names x and y for plot
coordinates. When your data is a field_layout (or shares its
coordinates via coords), give the response a different name (e.g.
resp, yield, response) so it does not overwrite the y coordinate.
Darghan, Rivera, Gonzalez & Castellanos (2022). doi:10.47280/RevFacAgron(LUZ).v39.n1.18
fl <- field_layout(nx = 12, ny = 8, ntrt = 3, nblk = 2, seed = 3000) set.seed(1); fl$resp <- rnorm(96, 2.21, 0.06) be <- border_effect(resp ~ trt + blk, data = fl, coords = fl) befl <- field_layout(nx = 12, ny = 8, ntrt = 3, nblk = 2, seed = 3000) set.seed(1); fl$resp <- rnorm(96, 2.21, 0.06) be <- border_effect(resp ~ trt + blk, data = fl, coords = fl) be
Given the coordinates of the units in a rectangular field trial, returns a
0/1 indicator of the units belonging to a chosen border pattern. The outer
ring ("outer1") and the second ring ("outer2") correspond to the sets
and of the paper; the side and multi-side patterns
reproduce the partial-border scenarios.
border_indicators( coords, pattern = c("outer1", "outer2", "lower", "left", "upper", "right", "lower_left", "lower_upper", "lower_right", "left_upper", "left_right", "upper_right", "lower_left_upper", "lower_left_right", "lower_upper_right", "left_upper_right", "central_h") )border_indicators( coords, pattern = c("outer1", "outer2", "lower", "left", "upper", "right", "lower_left", "lower_upper", "lower_right", "left_upper", "left_right", "upper_right", "lower_left_upper", "lower_left_right", "lower_upper_right", "left_upper_right", "central_h") )
coords |
A |
pattern |
One of |
An integer vector of 0s and 1s, length nrow(coords).
The side and ring patterns are defined from the global minimum/maximum
x and y coordinates (matching the original method), so they assume an
aligned rectangular grid. With arrangement = "triangular" in
field_layout(), the half-shifted even rows are not fully captured by the
side patterns (e.g. "left"/"right" only flag the exact-min/max-x
column, which excludes the shifted units in even rows). Users of
triangular layouts should interpret side/ring patterns accordingly.
Darghan, Rivera, Gonzalez & Castellanos (2022). doi:10.47280/RevFacAgron(LUZ).v39.n1.18
fl <- field_layout(nx = 5, ny = 4, ntrt = 2, nblk = 2) table(border_indicators(fl, "outer1"))fl <- field_layout(nx = 5, ny = 4, ntrt = 2, nblk = 2) table(border_indicators(fl, "outer1"))
Implements the paper's decision procedure: an indicator model
response ~ S1 (or response ~ S1 + S2 for the double outer edge) is fitted,
new responses are generated with simulate(), and is recomputed
for each simulated response using the two-way design. The resulting
distribution yields a confidence interval; if it contains zero the edge effect
is judged absent, otherwise present.
border_test(object, pattern = "outer1", nsim = 500, level = 0.95, seed = NULL)border_test(object, pattern = "outer1", nsim = 500, level = 0.95, seed = NULL)
object |
A |
pattern |
Border pattern to test (see |
nsim |
Number of simulated responses (default 500). |
level |
Confidence level for the interval (default 0.95). |
seed |
Optional seed; RNG state is restored on exit. |
An object of class border_test: a list with kappa_obs,
kappa_sim, ci, level, contains_zero, decision, pattern, nsim.
Darghan, Rivera, Gonzalez & Castellanos (2022). doi:10.47280/RevFacAgron(LUZ).v39.n1.18
fl <- field_layout(nx = 12, ny = 8, ntrt = 3, nblk = 2, seed = 3000) set.seed(1); fl$resp <- rnorm(96, 2.21, 0.06) be <- border_effect(resp ~ trt + blk, data = fl, coords = fl) border_test(be, pattern = "outer1", nsim = 200, seed = 42)fl <- field_layout(nx = 12, ny = 8, ntrt = 3, nblk = 2, seed = 3000) set.seed(1); fl$resp <- rnorm(96, 2.21, 0.06) be <- border_effect(resp ~ trt + blk, data = fl, coords = fl) border_test(be, pattern = "outer1", nsim = 200, seed = 42)
Builds an inverse-distance weight matrix W for the units of a field trial,
as used by the Besag-Kempton competition model. The diagonal is zero (a unit
does not compete with itself) and, by default, the matrix is standardized to
sum to one.
border_weights(coords, method = c("idw"), power = 1, standardize = TRUE)border_weights(coords, method = c("idw"), power = 1, standardize = TRUE)
coords |
A |
method |
Weighting method. Currently only |
power |
Positive exponent applied to the distance before inverting. |
standardize |
If |
A symmetric numeric matrix of class border_weights with zero diagonal.
Darghan, Rivera, Gonzalez & Castellanos (2022). doi:10.47280/RevFacAgron(LUZ).v39.n1.18
fl <- field_layout(nx = 4, ny = 4, ntrt = 2, nblk = 2) W <- border_weights(fl) sum(W)fl <- field_layout(nx = 4, ny = 4, ntrt = 2, nblk = 2) W <- border_weights(fl) sum(W)
Places nx * ny experimental units on a rectangular grid (square or
triangular / "tres bolillos" arrangement), randomly assigns treatments,
blocks and replicates, and appends 0/1 indicator columns for every border
pattern (see border_indicators()).
field_layout( nx, ny, ntrt = 3, nblk = 2, arrangement = c("square", "triangular"), width = NULL, height = NULL, randomize = TRUE, seed = NULL ) ## S3 method for class 'field_layout' plot(x, color_by = "trt", ...)field_layout( nx, ny, ntrt = 3, nblk = 2, arrangement = c("square", "triangular"), width = NULL, height = NULL, randomize = TRUE, seed = NULL ) ## S3 method for class 'field_layout' plot(x, color_by = "trt", ...)
nx, ny
|
Number of columns and rows of the grid. |
ntrt, nblk
|
Number of treatments and blocks. |
arrangement |
|
width, height
|
Physical extent of the grid. Defaults to |
randomize |
If |
seed |
Optional integer seed; RNG state is restored on exit. |
x |
A |
color_by |
Column used to color the points (default |
... |
Passed to |
A data.frame of class field_layout with columns x, y, trt,
blk, rep, and one integer column per border pattern.
With arrangement = "triangular", the appended border-pattern
columns (see border_indicators()) are still computed from the global
min/max x/y, which assumes an aligned rectangular grid; the
half-shifted even rows mean side patterns like "left"/"right" only
capture the exact-min/max-x column. Interpret side/ring indicators with
this in mind for triangular layouts.
Darghan, Rivera, Gonzalez & Castellanos (2022). doi:10.47280/RevFacAgron(LUZ).v39.n1.18
fl <- field_layout(nx = 12, ny = 8, ntrt = 3, nblk = 2, seed = 3000) head(fl)fl <- field_layout(nx = 12, ny = 8, ntrt = 3, nblk = 2, seed = 3000) head(fl)
A simulated staggered-planting trial (12 x 8 units, 3 treatments, 2 blocks) where the outer ring has a higher mean response than the interior, used to demonstrate edge-effect detection.
field_trialfield_trial
A data.frame with 96 rows and 6 columns:
plot coordinates
treatment factor (T1-T3)
block factor (B1-B2)
replicate factor
simulated yield
Darghan, Rivera, Gonzalez & Castellanos (2022). doi:10.47280/RevFacAgron(LUZ).v39.n1.18
Computes the closed-form least-squares estimator of the competition
coefficient associated with the edge effect, given a response
vector, a spatial weight matrix, and a design. The perpendicular projection
onto the column space of the design is applied implicitly via qr.resid(),
so no explicit projection matrix is formed and the estimator
works for any (possibly rank-deficient) design.
kappa_hat(y, W, design)kappa_hat(y, W, design)
y |
Numeric response vector of length |
W |
Symmetric |
design |
An |
A single numeric value, .
Darghan, Rivera, Gonzalez & Castellanos (2022). doi:10.47280/RevFacAgron(LUZ).v39.n1.18
n <- 12 xy <- expand.grid(x = 1:4, y = 1:3) W <- border_weights(xy) X <- model.matrix(~ rep(0:1, length.out = n)) kappa_hat(rnorm(n), W, X)n <- 12 xy <- expand.grid(x = 1:4, y = 1:3) W <- border_weights(xy) X <- model.matrix(~ rep(0:1, length.out = n)) kappa_hat(rnorm(n), W, X)
Computes Moran's I for the residuals of the fitted two-way model held in a
border_effect object, using the same weight matrix used to estimate
. A small p-value indicates spatial dependence of the residuals,
a signature of the edge effect. The statistic and its normal-approximation
variance follow the standard definition (as in ape::Moran.I).
moran_border(object)moran_border(object)
object |
A |
A list with observed, expected, sd, and (two-sided) p.value.
Darghan, Rivera, Gonzalez & Castellanos (2022). doi:10.47280/RevFacAgron(LUZ).v39.n1.18
fl <- field_layout(nx = 6, ny = 4, ntrt = 4, nblk = 3, seed = 5) set.seed(2); fl$resp <- rnorm(24) be <- border_effect(resp ~ trt + blk, data = fl, coords = fl) moran_border(be)fl <- field_layout(nx = 6, ny = 4, ntrt = 4, nblk = 3, seed = 5) set.seed(2); fl$resp <- rnorm(24) be <- border_effect(resp ~ trt + blk, data = fl, coords = fl) moran_border(be)
Opens an interactive application with two modes: Analyze a real trial
(upload a CSV with x, y, trt, block, response, or pick one of the
bundled example scenarios – no border, single/double outer border, and
unilateral/bilateral/trilateral partial borders – then read the
density, confidence interval and verdict) and Explore the
method (adjust layout and effect size and watch the distribution
respond). All statistics are computed by the package's exported functions.
run_border_app()run_border_app()
A Shiny app object (invisibly, when run interactively).
if (interactive() && requireNamespace("shiny", quietly = TRUE)) { run_border_app() }if (interactive() && requireNamespace("shiny", quietly = TRUE)) { run_border_app() }