
Area-frame and dual-frame survey design under real field cost. Survey samples
are usually designed for precision alone; the cost that actually decides
whether a survey happens is the field work: travelling between sampling units
and interviewing. fieldopt puts that cost next to the variance of the
estimator so that both are visible when the design is chosen, and provides
the pieces an agricultural survey with an area frame (grid cells, points
inside them) and a list frame needs.
travel_matrix() builds the travel matrix between units from coordinates
(great-circle or planar distances, optionally times a detour factor), from
a road network through OSRM (durations or distances, in blocks), or wraps a
matrix computed elsewhere.field_cost_model() turns travel, team-days, visits and interviews into
money or time.route_fieldwork() routes the field work from a depot through the selected
units, for one team or several, under daily limits of duration (travel plus
the service time at each unit), stops and capacity, on symmetric or
road-network matrices: exact up to 13 units, otherwise a hybrid genetic
search with the optimal split of the tour and a granular local search
(optimal on the classical TSPLIB instances and on 24 of the 27 Augerat CVRP
set A instances, largest gap 0.15%), with the Held-Karp bound and a proof of
optimality when it closes;
engine = "vrpr" hands the same problem to the PyVRP solver.schedule_fieldwork() solves the multi-depot problem of several bases
with their teams and days (assignment, routes and the number of team-days
at once) and distributes the routes over the teams and the days available:
a calendar that says whether the field work fits; schedule_calendar()
redoes that distribution as an integer programme (through highs) with
team availability, fixed assignments, precedences and shared team-days.select_units() draws a probability sample of segments or cells, within
strata, by the local pivotal method (spatially balanced), by spatially
ordered systematic sampling along a Hilbert curve with interpenetrating
replicates, by the cube method balanced on auxiliaries, or by simple random
sampling; spatial_balance() measures how evenly a sample covers the
territory.select_points(), expected_hits() and point_estimator() implement
point sampling inside the selected cells and the multiplicity estimator
(each hit of an establishment counts, divided by its expected hits).segment_estimator() gives the closed, open and weighted segment
estimators; design_variance() the Horvitz-Thompson total with the
variance estimator that matches the design (local-mean, replicates, SRS);
ratio_estimator() uses a known auxiliary total; dual_frame_estimator()
combines the area and the list samples (Hartley with a fixed, screening or
estimated weight; Fuller-Burmeister).frame_allocation() allocates across strata for a target variance or a
budget; multivariate_allocation() does it for several study variables at
once (Bethel); dual_frame_allocation() is Hartley's allocation for an
area frame plus a list frame with overlap, with the optimal mixing weight
or the screening design; two_stage_allocation() is Cochran's two-stage
allocation with the cost function c1 n + c2 n m. tidy() and glance()
read them all.routed_unit_cost(), two_stage_design() and dual_frame_design() close
the loop: the cost of an area unit is measured by routing a sample of the
allocated size, and the allocation is repeated until it stabilises.point_design_effect() simulates the whole area design (cells, points,
hits, estimator) and returns the bias, the variance and the design effect
of point sampling, the deff_a the dual-frame allocation asks for.cost_variance_frontier() simulates designs over a grid of sample sizes and
returns the trade-off between field cost and variance.as_frame(), as_sf() and read_areaframe() move between spatial layers
(or the cells exported by an area-frame service) and the plain frames the
package works on; frame_overlap() matches a list frame to the cells and
marks the overlap domain; as_svydesign() hands a sample to the survey
package for calibration, domains and nonresponse adjustment.The numerical engine is the Rust crate
fieldopt-core, usable on
its own from Rust or from other languages.
The development version needs a Rust toolchain (cargo and rustc 1.70 or
later, from https://rustup.rs):
# install.packages("pak")
pak::pak("castlaboratory/fieldopt")
library(fieldopt)
library(dplyr)
set.seed(1)
frame <- tibble(
unit = c("depot", paste0("s", 1:40)),
x = c(5, runif(40, 0, 10)), y = c(5, runif(40, 0, 10))
) |>
mutate(crop = if_else(unit == "depot", NA_real_, 20 + 3 * x + rnorm(n())))
model <- field_cost_model(
per_travel = 2, per_unit = 30, per_interview = 10,
interviews_per_unit = 4, currency = "BRL"
)
# one design: select, route, price, estimate
s <- frame |>
filter(unit != "depot") |>
select_units(n = 12)
r <- s |>
travel_matrix(bases = frame |> filter(unit == "depot"), method = "euclidean") |>
route_fieldwork(units = s, depot = "depot", max_stops = 5, cost_model = model)
r
design_variance(s, y = "crop")
# the frontier across sample sizes
f <- cost_variance_frontier(
frame,
depot = "depot", cost_model = model,
n_grid = c(8, 12, 16, 24), y = "crop",
method = "euclidean", max_stops = 5, n_rep = 10
)
autoplot(f)
Spatially balanced sampling and its variance estimator follow Grafström,
Lundström and Schelin (2012) and Grafström and Schelin (2014), as implemented
in BalancedSampling; the allocations are Cochran's (1977) cost-optimal
allocations and Hartley's (1962, 1974) dual-frame design; the dual-frame
estimators (Hartley, Fuller-Burmeister, Kalton-Anderson, pseudo-maximum
likelihood, calibration) are in Frames2. What fieldopt adds is the
design side with the routing and the cost model, so that the field cost of a
design is computed instead of approximated by the sample size.
André Leite (UFPE), Raydonal Ospina (UFBA) and Cristiano Ferraz (UFPE), CAST Lab. Licence GPL (>= 3).
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.