Skip to content

Rebuild the core: pooled region values, density regions and a size rule, with the review's defect fixes - #13

Merged
elkronos merged 15 commits into
mainfrom
dev/core
Oct 19, 2026
Merged

elkronos merged 15 commits into
mainfrom
dev/core

Conversation

@elkronos

Copy link
Copy Markdown
Owner

This branch fixes the defects found in a review of the package, rebuilds how regions get their values and how many regions are drawn, and switches the defaults to the rebuilt path. Every earlier result can still be had by naming the old settings. NEWS.md lists each change.

New defaults (breaking)

Function New default Old behaviour
resolution_profile() pooled values scored on one ladder rung of 4.5 observations per region; density-weighted regions from three weighted k-means++ starts; no variogram on that ladder estimate = NULL, obs_per_cell = NULL, sac = NULL, partition = "kmeans"
select_resolution() criterion = "auto": the size for pooled values, the leave-one-out minimum for plain means, cp for a profile with no estimate criterion = "cp"
get_voronoi_seeds(), voronoi_seeds_kmeans() density-weighted k-means partition = "kmeans"
summarize_by_cell() pooled values reported beside the plain mean estimate = "mean"

FNN moves from Suggests to Imports. A number of k-means starts that is not whole now stops get_voronoi_seeds() when no kind is named.

What the rebuild adds

  • Pooled region values (summarize_by_cell(estimate = "pooled")): each region's mean is pulled toward the mean of its 8 nearest regions, with a weight on its own mean that grows with its count. Works on any polygons, including ones the user brings.
  • An interval for one observation (obs_level), from leave-one-out residuals, kept apart from the existing interval for a region's mean. The help says where it holds and where it does not.
  • The count by size or by leave-one-out error (obs_per_cell, criterion = "size" | "loo" | "auto"), with a record of how the count was set that travels to the summary, which warns when the regions summarised are not the regions scored.
  • Density-weighted partitions (partition = "density", init, density_power, density_k).
  • cell_values_at(): region values and intervals at other locations.

Defect fixes from the review

Among them: the range estimate (no iteration, no dependence on units or row order, a test for spatial structure), the cell count's ceiling and criteria, cells that reach the edge of the data, kNNDM folds and a neutral fold_separation(), a GWR solver of the package's own (GWmodel is no longer called), the Bayesian model's prior and convergence verdict, the area of applicability's weighting, and classed warnings for events that were silent. fold_separation()'s within_range column is renamed mean_cor.

Testing

  • A frozen fixture of 361 calls holds the earlier results; every way back to an old default returns the earlier object.
  • Whole test suite on macOS (R 4.6.1): 45,389 expectations pass, none fail, 23 skip on their guards.
  • R CMD check --no-manual: no errors, no warnings.

The version stays 2.0.0.9000.

…ell count, cells, GWR, Bayesian model, area of applicability

Range estimate. estimate_sac_range() fits its variogram by a profile
weighted least squares that needs no iteration, on standardised values, so
the range and nugget no longer depend on the units or the order of the
rows. It tests for spatial structure before it returns a range, bins lags
adaptively by default (lags = "equal" gives the old bins), treats repeat
visits as one place, and no longer lets the largest directional range stand
in for the all-pairs fit. New attributes say how far the nugget can be
trusted (nugget_at_bound, first_lag, short_lag_semivariance).

Cell count. The support ceiling counts rows that carry a response. The
ladder starts at 2 cells and resolution_profile() defaults to
range_floor = FALSE; select_resolution() holds the reliability criterion to
the range floor. moran_z is a diagnostic and no longer a count rule. A count
chosen at a bound, or one a single cell matches, raises a classed warning,
and a profile is read by cp or is an error where no criterion is named.

Cells. Voronoi cells built on k-means or random seeds reach the hull of the
data or the boundary the seeds came from (new argument cover). Features in
no cell, duplicated polygon IDs and infinite values are reported. The Kish
correction uses one intraclass correlation per column, a failed variogram
correction falls back to Kish, and a layer with no spatial structure gets a
design effect of 1. kriging_adequacy() drops kr_exceeds_design and reports
plain_var and kr_gain.

Folds. make_folds() gains method = "knndm" and max_test. Fewer folds than
asked for is a classed warning. fold_separation() takes prediction_points
and gives a direction only against them.

GWR. The package solves the local regressions itself by pivoted QR and no
longer calls GWmodel; sp is still needed. A window of deficient rank gives
NA coefficients with a warning in place of an error. The bandwidth comes
from the package's own search, by leave-one-location-out where locations
repeat. coef() and predict() return standard errors on request, and a model
with no predictors is a local mean.

Bayesian model. The automatic slope prior scales with the response. The
convergence verdict follows Stan's thresholds and raises a classed warning.
The fit stores and prints the shortest range its basis can resolve, warns
before fitting when the estimated range is below it, and predicts the rows
it can when newdata holds a factor level it was not fitted with.

Area of applicability, forest, selection. The index weights predictors by
the model's importance by default (weights = NULL gives equal weights) and
measures location separately for GWR and Bayesian fits. Forests order the
levels of unordered factors by the response. select_features_forward() has
a baseline for every learner and adds a variable only when its gain exceeds
one standard error across folds.

Warnings that were silent or log lines now carry classes of the form
spatialkit_<what>, each documented where it is raised, and one helper
raises them all.

Not changed here: the Cp formula and its noise variance, the default count
criterion, min_cell_n, the default fold design and include_coords.

Help pages are regenerated with the installed roxygen2, NEWS.md has an
entry for each user-visible change, and the README, vignettes and tour
scripts are corrected where the code changes made a statement untrue.

Tests: 17,867 pass, none fail, 23 skip on their guards. R CMD check: no
errors, no warnings.
The column held the share of held-out points closer than the range. It now
holds the mean correlation the range leaves between a held-out point and
its nearest training point, so the old name described something the column
no longer is. The table, the pooled attribute and print() use mean_cor;
code that reads within_range has to be changed. The help and NEWS.md say
what the earlier column was.

Tests: 17,871 pass, none fail, 23 skip on their guards.
… seeding functions and the resolution profile

resolution_profile(), get_voronoi_seeds(method = "kmeans") and
voronoi_seeds_kmeans() gain partition = c("kmeans", "density"), init,
density_power, density_k and iter_max. Under "density" each point is
weighted by its local density to the power density_power, and the centres
come from weighted k-means with weighted k-means++ starts. At power 1 the
cells hold about the same number of points once there are more cells than
dense places. The result does not depend on the order of the rows, the unit
of the coordinates or whether FNN is installed.

Every call that names none of the new arguments returns what it returned
before. New classed warnings: spatialkit_partition_unused,
spatialkit_empty_cells and spatialkit_not_converged.

Tests: 21,457 pass, none fail, 23 skip on their guards. R CMD check: no
errors, no warnings.
…summary functions

A fixture of 361 calls of resolution_profile(), select_resolution(), the
seeding functions, build_tessellation(), assign_features_to_polygons() and
summarize_by_cell() records what each returns, raises, prints and logs on
the tree of the previous commit. test-core-frozen.R replays every call and
compares the results exactly on the fixture's platform and versions, and
loosely elsewhere; with SPATIALKIT_FROZEN_STRICT=true a version mismatch
fails instead of skipping. dev/baseline-core-frozen.R writes the fixture.
It names the baseline by its tree, c64fcac, which is the tree of the
previous commit.

The reference functions of the two design experiments are copied, unchanged
and with their sources named, into a test helper for the reproduction tests
that follow.

Tests: 27,806 pass, none fail, 23 skip. R CMD check: no errors, no
warnings.
R/pool.R holds .pool_fit(): each region's value is its mean pulled toward
the n-weighted mean of its 8 nearest regions, with a weight on its own mean
that grows with its count. The engine also gives the leave-one-out errors
of the pooled values and of plain means, the error of one mean for all
rows, a test of the region means against one mean, and the leave-one-out
residuals an interval is read from. It reproduces the design experiments'
functions exactly on the test layouts, with FNN and without.

Nothing exported changes.

Tests: 32,697 pass, none fail, 23 skip. R CMD check: no errors, no
warnings.
…mmarize_by_cell()

summarize_by_cell() gains estimate = c("mean", "pooled") and
obs_level = NULL. With estimate = "pooled" each summarised column gains its
pooled value, the weight the value gives the region's own mean, and the
mean of the neighbouring regions it is pulled toward. obs_level adds an
interval for one further observation in a region, read from the
leave-one-out residuals of the pooled values. attr(, "intervals") says what
each interval covers; the existing interval is one for a region's mean.

The plain columns, agg_funs, deff and conf_level keep their meaning and
their numbers. New classed warnings for regions too few or too small to
pool, a column without spread, and a response the regions do not help with.

Tests: 34,913 pass, none fail, 23 skip. R CMD check: no errors, no
warnings.
resolution_profile() gains estimate and obs_per_cell. With an estimate the
profile adds loo, loo_se, scored_per_cell, share_alone and own_weight: the
leave-one-out error of that estimate on every scored row, in the cells the
seeds will build, with no variogram. obs_per_cell sets the ladder by
observations per region. nstart = NULL gives 3 starts for the density kind
and the present number for k-means; sac = "auto" fits no variogram on a
ladder of sizes. Two work guards stop a fit or an exact search that would
take too long and name the ways on (options spatialkit.fit_work_max and
spatialkit.exact_pairs_max). On a ladder of sizes Moran's z reads cell
means from grouped sums.

A profile built without the new arguments is unchanged.

Tests: 39,128 pass, none fail, 23 skip. R CMD check: no errors, no
warnings.
…on()

select_resolution() gains the criteria "size", "loo" and "auto": a size
for pooled values, the leave-one-out minimum for plain means, and cp for a
profile with no estimate. Under a size, whether the response has structure
is tested by the leave-one-out error against one mean for all rows, and a
structureless response raises spatialkit_no_structure. The selection
carries a count_rule record of how the count was set. A profile with an
estimate, passed straight to a seeding function as the count, is read by
"auto".

The default criterion is still "cp".

Tests: 40,482 pass, none fail, 23 skip. R CMD check: no errors, no
warnings.
…mmarised are the regions scored

The count_rule record travels from the selection through the seeds, the
tessellation and the assigned layer to summarize_by_cell(). The summary
warns with spatialkit_estimate_mismatch when it reports an estimate the
count was not chosen for, and with spatialkit_cells_differ when the cells
or rows differ from those the count was scored on. The seeding functions
take nstart = NULL and read the partition arguments a call names in one
way.

Tests: 42,408 pass, none fail, 23 skip. R CMD check: no errors, no
warnings.
cell_values_at() gives each location the value and the observation
interval of the region it falls in, found from the seeds or the polygons.
A location whose region holds no data takes the value of the nearest region
that does and is marked as filled. Each location's distance from the data
is reported beside its value.

Tests: 43,167 pass, none fail, 23 skip. R CMD check: no errors, no
warnings.
Help pages, NEWS entries and the resolution and reporting vignettes cover
the new arguments, columns, records and warnings. The help says that the
observation interval is checked only where data are near and that no
interval is calibrated away from the data. dev/sim-pooled-values.R
produces the figures the help quotes, and a test ties those figures to the
script's saved output.

Tests: 43,681 pass, none fail, 23 skip. R CMD check: no errors, no
warnings.
…red in

On gridded locations a point can lie exactly as far from two centres. The
profile scored it in one cell by its nearest-centre rule, while the
assignment to polygons could place it in the other, and the summary then
warned that the cells differ from those the count was scored on.

The count's record now carries the centres the profile scored. For cells
that carry such a record, assign_features_to_polygons() gives a point on a
shared edge the cell of its nearest scored centre, a tie going to the
lower-numbered centre as in the profile; other points keep their cell.
cell_values_at(seeds =) matches seeds to the scored centres as a set, in any
order and CRS, and settles ties the same way. For seeds that carry scored
centres, build_tessellation() and create_voronoi_polygons() build the cells
in the record's CRS.

Polygons without a record, records whose cells were not scored, features
that are not points, and every call that names no new argument are placed
as before.

Tests: 44,946 pass, none fail, 23 skip. R CMD check: no errors, no
warnings.
… pooled values

resolution_profile() now scores pooled values on a ladder of one size, 4.5
observations per region, with density-weighted regions from three weighted
k-means++ starts, and fits no variogram on such a ladder.
select_resolution() picks by that size for pooled values, by the
leave-one-out minimum for plain means, and by cp for a profile with no
estimate. get_voronoi_seeds() and voronoi_seeds_kmeans() draw density-
weighted regions. summarize_by_cell() reports pooled values beside the plain
mean. Moran's z is NA, with a warning, above its cell limit on every ladder.
FNN moves from Suggests to Imports.

Every earlier result can be had by naming the old setting: estimate = NULL,
obs_per_cell = NULL, sac = NULL and partition = "kmeans" in the profile;
criterion = "cp" in the selection; partition = "kmeans" in the seeding
functions; estimate = "mean" in the summary. Each argument's help gives its
old default. A number of k-means starts that is not whole now stops
get_voronoi_seeds() when no kind is named.

No function body changes beyond those defaults and the value of
.moran_skip_any_ladder(). The frozen fixture's 361 calls now name the old
defaults they were recorded under, and give the same objects. Of the tests
that failed after the switch, 118 now name the old default they were written
for and 13 are rewritten for the new defaults; 12 tests are new, among them
the default path end to end and every way back.

The README, the vignettes, the examples and the scripts follow the new
defaults, and the README figures are drawn again. The help of the pooled
value says how much it loses beside a sharp boundary, and the help of the
observation interval gives its simulated coverage on fields of county levels
with a smooth part.

Tests: 45,389 pass, none fail, 23 skip. R CMD check: no errors, no warnings.
The frozen fixture was recorded on macOS. On Linux, stats::kmeans() stops
at slightly other centres, on a structureless layer at another solution,
and PROJ's measured distortion moves with its version, so the comparison of
numbers to 1e-12 failed in 159 expectations of test-core-frozen.R,
test-core-count-size.R and test-core-switch.R.

Off the fixture's platform these tests now compare what holds on any
platform: whether each call stops, and the class, names and attribute names
of what it returns. On the fixture's platform every part is still compared
in full and must be identical.
test-core-gridded-ties.R took for granted that seeds sent through degrees
and back lie farther from the scored centres than the margin of an edge.
That holds with macOS's PROJ build and not with Windows', where the round
trip is nearly exact, so the test's premise failed. The test now matches the
round-tripped seeds whatever their offset, and moves seeds by five times the
margin itself so that the case is tested on every platform.

R-devel's RNGkind() reports a fourth kind; test-core-pool-helper.R now
compares the three it sets.
@elkronos
elkronos merged commit bd9e04b into main Oct 19, 2026
9 checks passed
elkronos added a commit that referenced this pull request Oct 19, 2026
…le, with the review's defect fixes (#13)

* Fix the defects found in the package review: range estimate, folds, cell count, cells, GWR, Bayesian model, area of applicability

Range estimate. estimate_sac_range() fits its variogram by a profile
weighted least squares that needs no iteration, on standardised values, so
the range and nugget no longer depend on the units or the order of the
rows. It tests for spatial structure before it returns a range, bins lags
adaptively by default (lags = "equal" gives the old bins), treats repeat
visits as one place, and no longer lets the largest directional range stand
in for the all-pairs fit. New attributes say how far the nugget can be
trusted (nugget_at_bound, first_lag, short_lag_semivariance).

Cell count. The support ceiling counts rows that carry a response. The
ladder starts at 2 cells and resolution_profile() defaults to
range_floor = FALSE; select_resolution() holds the reliability criterion to
the range floor. moran_z is a diagnostic and no longer a count rule. A count
chosen at a bound, or one a single cell matches, raises a classed warning,
and a profile is read by cp or is an error where no criterion is named.

Cells. Voronoi cells built on k-means or random seeds reach the hull of the
data or the boundary the seeds came from (new argument cover). Features in
no cell, duplicated polygon IDs and infinite values are reported. The Kish
correction uses one intraclass correlation per column, a failed variogram
correction falls back to Kish, and a layer with no spatial structure gets a
design effect of 1. kriging_adequacy() drops kr_exceeds_design and reports
plain_var and kr_gain.

Folds. make_folds() gains method = "knndm" and max_test. Fewer folds than
asked for is a classed warning. fold_separation() takes prediction_points
and gives a direction only against them.

GWR. The package solves the local regressions itself by pivoted QR and no
longer calls GWmodel; sp is still needed. A window of deficient rank gives
NA coefficients with a warning in place of an error. The bandwidth comes
from the package's own search, by leave-one-location-out where locations
repeat. coef() and predict() return standard errors on request, and a model
with no predictors is a local mean.

Bayesian model. The automatic slope prior scales with the response. The
convergence verdict follows Stan's thresholds and raises a classed warning.
The fit stores and prints the shortest range its basis can resolve, warns
before fitting when the estimated range is below it, and predicts the rows
it can when newdata holds a factor level it was not fitted with.

Area of applicability, forest, selection. The index weights predictors by
the model's importance by default (weights = NULL gives equal weights) and
measures location separately for GWR and Bayesian fits. Forests order the
levels of unordered factors by the response. select_features_forward() has
a baseline for every learner and adds a variable only when its gain exceeds
one standard error across folds.

Warnings that were silent or log lines now carry classes of the form
spatialkit_<what>, each documented where it is raised, and one helper
raises them all.

Not changed here: the Cp formula and its noise variance, the default count
criterion, min_cell_n, the default fold design and include_coords.

Help pages are regenerated with the installed roxygen2, NEWS.md has an
entry for each user-visible change, and the README, vignettes and tour
scripts are corrected where the code changes made a statement untrue.

Tests: 17,867 pass, none fail, 23 skip on their guards. R CMD check: no
errors, no warnings.

* Rename fold_separation()'s within_range column to mean_cor

The column held the share of held-out points closer than the range. It now
holds the mean correlation the range leaves between a held-out point and
its nearest training point, so the old name described something the column
no longer is. The table, the pooled attribute and print() use mean_cor;
code that reads within_range has to be changed. The help and NEWS.md say
what the earlier column was.

Tests: 17,871 pass, none fail, 23 skip on their guards.

* Add a density-weighted partition and a choice of starting rule to the seeding functions and the resolution profile

resolution_profile(), get_voronoi_seeds(method = "kmeans") and
voronoi_seeds_kmeans() gain partition = c("kmeans", "density"), init,
density_power, density_k and iter_max. Under "density" each point is
weighted by its local density to the power density_power, and the centres
come from weighted k-means with weighted k-means++ starts. At power 1 the
cells hold about the same number of points once there are more cells than
dense places. The result does not depend on the order of the rows, the unit
of the coordinates or whether FNN is installed.

Every call that names none of the new arguments returns what it returned
before. New classed warnings: spatialkit_partition_unused,
spatialkit_empty_cells and spatialkit_not_converged.

Tests: 21,457 pass, none fail, 23 skip on their guards. R CMD check: no
errors, no warnings.

* Pin the present results of the resolution, seeding, tessellation and summary functions

A fixture of 361 calls of resolution_profile(), select_resolution(), the
seeding functions, build_tessellation(), assign_features_to_polygons() and
summarize_by_cell() records what each returns, raises, prints and logs on
the tree of the previous commit. test-core-frozen.R replays every call and
compares the results exactly on the fixture's platform and versions, and
loosely elsewhere; with SPATIALKIT_FROZEN_STRICT=true a version mismatch
fails instead of skipping. dev/baseline-core-frozen.R writes the fixture.
It names the baseline by its tree, c64fcac, which is the tree of the
previous commit.

The reference functions of the two design experiments are copied, unchanged
and with their sources named, into a test helper for the reproduction tests
that follow.

Tests: 27,806 pass, none fail, 23 skip. R CMD check: no errors, no
warnings.

* Add the engine for pooled region values

R/pool.R holds .pool_fit(): each region's value is its mean pulled toward
the n-weighted mean of its 8 nearest regions, with a weight on its own mean
that grows with its count. The engine also gives the leave-one-out errors
of the pooled values and of plain means, the error of one mean for all
rows, a test of the region means against one mean, and the leave-one-out
residuals an interval is read from. It reproduces the design experiments'
functions exactly on the test layouts, with FNN and without.

Nothing exported changes.

Tests: 32,697 pass, none fail, 23 skip. R CMD check: no errors, no
warnings.

* Report pooled region values and an interval for one observation in summarize_by_cell()

summarize_by_cell() gains estimate = c("mean", "pooled") and
obs_level = NULL. With estimate = "pooled" each summarised column gains its
pooled value, the weight the value gives the region's own mean, and the
mean of the neighbouring regions it is pulled toward. obs_level adds an
interval for one further observation in a region, read from the
leave-one-out residuals of the pooled values. attr(, "intervals") says what
each interval covers; the existing interval is one for a region's mean.

The plain columns, agg_funs, deff and conf_level keep their meaning and
their numbers. New classed warnings for regions too few or too small to
pool, a column without spread, and a response the regions do not help with.

Tests: 34,913 pass, none fail, 23 skip. R CMD check: no errors, no
warnings.

* Add a ladder of sizes and a leave-one-out error to resolution_profile()

resolution_profile() gains estimate and obs_per_cell. With an estimate the
profile adds loo, loo_se, scored_per_cell, share_alone and own_weight: the
leave-one-out error of that estimate on every scored row, in the cells the
seeds will build, with no variogram. obs_per_cell sets the ladder by
observations per region. nstart = NULL gives 3 starts for the density kind
and the present number for k-means; sac = "auto" fits no variogram on a
ladder of sizes. Two work guards stop a fit or an exact search that would
take too long and name the ways on (options spatialkit.fit_work_max and
spatialkit.exact_pairs_max). On a ladder of sizes Moran's z reads cell
means from grouped sums.

A profile built without the new arguments is unchanged.

Tests: 39,128 pass, none fail, 23 skip. R CMD check: no errors, no
warnings.

* Choose the count by size or by leave-one-out error in select_resolution()

select_resolution() gains the criteria "size", "loo" and "auto": a size
for pooled values, the leave-one-out minimum for plain means, and cp for a
profile with no estimate. Under a size, whether the response has structure
is tested by the leave-one-out error against one mean for all rows, and a
structureless response raises spatialkit_no_structure. The selection
carries a count_rule record of how the count was set. A profile with an
estimate, passed straight to a seeding function as the count, is read by
"auto".

The default criterion is still "cp".

Tests: 40,482 pass, none fail, 23 skip. R CMD check: no errors, no
warnings.

* Carry the count's record to the summary and check that the regions summarised are the regions scored

The count_rule record travels from the selection through the seeds, the
tessellation and the assigned layer to summarize_by_cell(). The summary
warns with spatialkit_estimate_mismatch when it reports an estimate the
count was not chosen for, and with spatialkit_cells_differ when the cells
or rows differ from those the count was scored on. The seeding functions
take nstart = NULL and read the partition arguments a call names in one
way.

Tests: 42,408 pass, none fail, 23 skip. R CMD check: no errors, no
warnings.

* Add cell_values_at(): region values and intervals at other locations

cell_values_at() gives each location the value and the observation
interval of the region it falls in, found from the seeds or the polygons.
A location whose region holds no data takes the value of the nearest region
that does and is marked as filled. Each location's distance from the data
is reported beside its value.

Tests: 43,167 pass, none fail, 23 skip. R CMD check: no errors, no
warnings.

* Document pooled values, the size rule and the observation interval

Help pages, NEWS entries and the resolution and reporting vignettes cover
the new arguments, columns, records and warnings. The help says that the
observation interval is checked only where data are near and that no
interval is calibrated away from the data. dev/sim-pooled-values.R
produces the figures the help quotes, and a test ties those figures to the
script's saved output.

Tests: 43,681 pass, none fail, 23 skip. R CMD check: no errors, no
warnings.

* Give a point on the edge between two scored cells the cell it was scored in

On gridded locations a point can lie exactly as far from two centres. The
profile scored it in one cell by its nearest-centre rule, while the
assignment to polygons could place it in the other, and the summary then
warned that the cells differ from those the count was scored on.

The count's record now carries the centres the profile scored. For cells
that carry such a record, assign_features_to_polygons() gives a point on a
shared edge the cell of its nearest scored centre, a tie going to the
lower-numbered centre as in the profile; other points keep their cell.
cell_values_at(seeds =) matches seeds to the scored centres as a set, in any
order and CRS, and settles ties the same way. For seeds that carry scored
centres, build_tessellation() and create_voronoi_polygons() build the cells
in the record's CRS.

Polygons without a record, records whose cells were not scored, features
that are not points, and every call that names no new argument are placed
as before.

Tests: 44,946 pass, none fail, 23 skip. R CMD check: no errors, no
warnings.

* Switch the defaults to density regions of about 4.5 observations with pooled values

resolution_profile() now scores pooled values on a ladder of one size, 4.5
observations per region, with density-weighted regions from three weighted
k-means++ starts, and fits no variogram on such a ladder.
select_resolution() picks by that size for pooled values, by the
leave-one-out minimum for plain means, and by cp for a profile with no
estimate. get_voronoi_seeds() and voronoi_seeds_kmeans() draw density-
weighted regions. summarize_by_cell() reports pooled values beside the plain
mean. Moran's z is NA, with a warning, above its cell limit on every ladder.
FNN moves from Suggests to Imports.

Every earlier result can be had by naming the old setting: estimate = NULL,
obs_per_cell = NULL, sac = NULL and partition = "kmeans" in the profile;
criterion = "cp" in the selection; partition = "kmeans" in the seeding
functions; estimate = "mean" in the summary. Each argument's help gives its
old default. A number of k-means starts that is not whole now stops
get_voronoi_seeds() when no kind is named.

No function body changes beyond those defaults and the value of
.moran_skip_any_ladder(). The frozen fixture's 361 calls now name the old
defaults they were recorded under, and give the same objects. Of the tests
that failed after the switch, 118 now name the old default they were written
for and 13 are rewritten for the new defaults; 12 tests are new, among them
the default path end to end and every way back.

The README, the vignettes, the examples and the scripts follow the new
defaults, and the README figures are drawn again. The help of the pooled
value says how much it loses beside a sharp boundary, and the help of the
observation interval gives its simulated coverage on fields of county levels
with a smooth part.

Tests: 45,389 pass, none fail, 23 skip. R CMD check: no errors, no warnings.

* Compare frozen results across platforms by what carries over

The frozen fixture was recorded on macOS. On Linux, stats::kmeans() stops
at slightly other centres, on a structureless layer at another solution,
and PROJ's measured distortion moves with its version, so the comparison of
numbers to 1e-12 failed in 159 expectations of test-core-frozen.R,
test-core-count-size.R and test-core-switch.R.

Off the fixture's platform these tests now compare what holds on any
platform: whether each call stops, and the class, names and attribute names
of what it returns. On the fixture's platform every part is still compared
in full and must be identical.

* Make two tests hold on Windows and on R-devel

test-core-gridded-ties.R took for granted that seeds sent through degrees
and back lie farther from the scored centres than the margin of an edge.
That holds with macOS's PROJ build and not with Windows', where the round
trip is nearly exact, so the test's premise failed. The test now matches the
round-tripped seeds whatever their offset, and moves seeds by five times the
margin itself so that the case is tested on every platform.

R-devel's RNGkind() reports a fourth kind; test-core-pool-helper.R now
compares the three it sets.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant