Internal-consistency release. The documented workflow shrinks
from eight steps to seven: issue counting becomes an internal detail of
customized_filter(), and the coordinate stage is renamed
par_clean_coordinates(). The two native-status detectors
stop demanding a CoordinateRefined object and become plain
table functions with explicit column-name arguments, and their
classification columns are simplified.
clean_coordinates() is renamed
par_clean_coordinates(). The old name collided
with CoordinateCleaner::clean_coordinates(), which the
function calls, and said nothing about how it works. The new name
records that the CoordinateCleaner tests are distributed across
threads workers through foreach /
doParallel. The signature changes from
clean_coordinates(customized_filtered, threads = 4, tests = ...)
to
par_clean_coordinates(input = NA, species = "Accepted_name_id", longitude = "decimalLongitude", latitude = "decimalLatitude", threads = 4, tests = ...).
The first argument is renamed and the three column-name arguments are
new; see Improvements.extract_gbif_issues() is renamed
extract_issues() and is no longer exported. Issue
counting was never a decision the user had to make: it only feeds the
gbif_issues_max rule of customized_filter(),
which now calls it internally. The "issue" class and its
print.issue() method are gone with the export.detect_native_coord()
and detect_native_country() now take a tableCoordinateRefined object.
detect_native_coord(cleaned_coordinates = NA, buffer_km = 10, buffer_chunk_size = 2000)
becomes
detect_native_coord(input = NA, species = "Accepted_name", longitude = "decimalLongitude", latitude = "decimalLatitude", buffer_km = 10, buffer_chunk_size = 2000),
and detect_native_country(cleaned_coordinates = NA) becomes
detect_native_country(input = NA, species = "Accepted_name", country = "countryCode").
Anything data.table::as.data.table() can convert is
accepted, so the inherits() check on the input class is
gone. Pass the concrete table, for example
par_clean_coordinates(...)$CoordinateCleaned, rather than
the wrapper object.species,
longitude, latitude and country
arguments, which default to the GBIF names. A column that happens to
share a name with one of the arguments (a species column,
say) does not interfere: the column vectors are extracted before the
internal data.table expression is evaluated.detect_native_country() no longer requires
coordinates and no longer inspects
CoordinateProblematic. It classifies every record
handed to it through countryCode, so it also works on
records that do have coordinates but are better classified without
geometry.gbifID is filled in. Both
functions previously relied on it as a join key; an input without one
now gets a character sequence number instead of failing.native_status_source values renamed.
In the spatial result, spatial and
spatial_buffered become exact and
buffered. In the country-code result,
country_code and country_code_no_entry become
country and no_entry. The
unmatched value is unchanged in both.buffered logical column has been
removed. It was fully implied by
native_status_source == "buffered", and was always
FALSE in the country-code result, so it carried no
information of its own. Both results now append exactly three
classification columns: LEVEL3_COD,
native_status, native_status_source.customized_filter() no longer takes
gbif_issue. The argument had to be filled with the
output of extract_gbif_issues(), which is now called
internally, so the signature drops to
customized_filter(occ_import, taxa_checked, filter_countryCode = TRUE, filter_coordinateUncertainty = 10000, filter_date = FALSE, filter_identifiedBy = FALSE, filter_recordedBy = FALSE, filter_gbif_issues_max = 5).export_records() gains a
native_detected_country argument and renames its output
files. The signature becomes
export_records(native_detected_coord = NA, native_detected_country = NA, export_path = NA).
Each classification supplied is written as its own pair -
all_records_coord.csv.gz /
native_records_coord.csv.gz and
all_records_country.csv.gz /
native_records_country.csv.gz - replacing
all_records.csv.gz / native_records.csv.gz.
The two sets are never bound into a combined table.map_records() gains a species
argument. The signature becomes
map_records(native_detected_coord = NA, species = "all", precision = 3, cex = 3),
so a single species can be mapped without subsetting the table by hand.
A name that selects nothing stops with an error rather than rendering an
empty map.import_records() accepts an already-extracted
occurrence table, and remove_tempfile defaults to
TRUE. The default was NULL, which
resolved to TRUE for an auto-created directory but
FALSE for a user-supplied one; it is now a plain
TRUE. The extension check on path is gone: a
non-ZIP file is no longer rejected on its suffix but probed for a
gbifID first column, which rejects non-GBIF files including
comma-separated ones whose header would otherwise arrive as a single
column.rnaturalearthdata dependency has been
removed. The seas test is evaluated against the
bundled WorldLandMap object, which is passed explicitly as
seas_ref, so the package was never imported at run
time.import_records() -> check_taxon() ->
customized_filter() ->
par_clean_coordinates() ->
detect_native_coord() /
detect_native_country() -> map_records()
-> export_records(). Every step number was decremented
after the removal of the issue-extraction step.par_clean_coordinates() returned different
results for a data.table and a
data.frame.
CoordinateCleaner::clean_coordinates() behaves differently
on the two: inside cc_outl() it subsets with
k[, c(species, lon, lat)], which on a
data.table returns a three-element character vector rather
than the columns, silently changing which records are flagged as
outliers. The table is now converted with as.data.frame()
before it is handed over, so the same input always yields the same
output. This was a reproducibility defect: the result depended on the
class of the caller’s object rather than on its contents.import_records() could delete a directory the
caller supplied. Cleanup ran
unlink(ex_path, recursive = TRUE) unconditionally when
tempdir was given, so a user-supplied directory was removed
in full even though it may have held unrelated files. An auto-created
directory is still removed whole, but a caller-supplied one now has only
the extracted members unlinked.set_threads() stopped with
"illegal !!!". A non-positive x now
stops with `x` must be a single positive number. instead of
an unexplained exclamation.par_clean_coordinates() rejects a whole
customFiltered object with a usable message.
Passing the object rather than the table it contains previously failed
deep inside the coordinate tests; it now stops with
`input` is a `customFiltered` object, not a table. Pass the table it contains, for example `par_clean_coordinates(filtered$occ_filtered)`.
The guard tests for the class, so an ordinary list or
data.frame input is unaffected.par_clean_coordinates() names its columns and
chunks by species. The species,
longitude and latitude arguments free the
input from GBIF field names, and the parallel split runs per species so
a chunk never straddles a taxon boundary. The seas test is
evaluated against the bundled WorldLandMap land polygons
buffered by 5 km.customized_filter() reports per-rule
verdicts. Each rule now evaluates the whole table and stores a
logical filter_* column, so one record can be audited
against several rules at once. occ_filtered carries no
verdict columns; the verdicts are returned separately in
occ_marked, one column per applied rule.
summary gains failed (records the rule rejects
on its own terms) and only_failed_here (records it rejects
and no other rule does) alongside the existing sequential
dropped / remaining, whose sums differ on
overlapping rules.extract_issues() returns one tidy
table. The previous "issue" object bundled a wide
logical matrix with a per-code summary; the internal function returns a
single data.table of gbifID and a numeric
issue_count, which is all the gbif_issues_max
rule needs.export_records() validates and documents both
channels. The coordinate channel requires gbifID,
native_status, decimalLongitude and
decimalLatitude, and rejects a record with a missing
coordinate; the country-code channel requires only gbifID
and native_status. Supplying one argument leaves the files
of the other untouched.countryCode that is blank, NA, or maps to no
WGSRPD Level 3 area is retained as unknown /
unmatched rather than dropped, and a country that maps but
has no distribution entry for the taxon is unknown /
no_entry. The two are distinct in
native_status_source, so a genuinely absent country is
never confused with a taxon that has no record there.Example.Rmd, and
Application.Rmd rewritten for the seven-step workflow, the
renamed functions, and the new column contracts.clean_coordinates(),
refine_coordinates(), custom_filter() and
extract_gbif_issues() reference has been updated across
R/, README, and the vignettes. References to the internal
extract_gbif_issues() are cross-links to the unexported
extract_issues()._pkgdown.yml step headings renumbered to match, and the
removed print.issue method dropped from the reference
index.test-custom_filter.R rewritten for the verdict-column
contract: the gbif_issue argument is gone, raw
pipe-separated issue strings are built in the fixtures, and
the failed / only_failed_here semantics are
pinned against overlapping and disjoint rules.test-detect_native_coord.R and
test-detect_native_country.R rewritten for the table input,
the auto-generated gbifID, and the renamed classification
values; both add a regression test that a column named
species does not shadow the species
argument.test-par_clean_coordinates.R added, replacing
test-refine_coordinates.R. It covers the renamed argument,
table-like inputs, the customFiltered guard, and a
thread-independence check that threads = 1 and
threads = 2 return identical() results.test-extract_issues.R added, replacing
test-extract_gbif_issues.R. It asserts the new return
contract and that the function stays internal with no
print.issue method.test-export_records.R extended to the country-code
channel and the renamed files; the fixtures now create their own
temporary directories.test-import_records.R, test-map_records.R,
and test-set_threads.R updated for the new
tempdir semantics, the header probe error, the
species argument, and the reworded thread error. The
set_threads snapshot was re-recorded.detect_native_country() now requires a
CoordinateRefined object. The function signature
has changed from detect_native_country(customized_filtered)
to detect_native_country(cleaned_coordinates). It now takes
the output of clean_coordinates() instead of
customized_filter(), processing all records from
CoordinateProblematic (both coordinateless records and
those that failed coordinate validation tests).clean_coordinates() now includes coordinateless
records in CoordinateProblematic. Records missing
longitude or latitude are no longer silently excluded but are added to
CoordinateProblematic alongside records that failed
coordinate validation tests. This ensures all problematic records are
captured in one place for downstream processing.detect_native_country() processes all
CoordinateProblematic records. The function now
classifies both coordinateless records and records with coordinates that
failed validation tests, providing comprehensive country-code-based
classification for all records that cannot be spatially matched.VasGBIF-package.R now accurately
reflects that detect_native_coord() processes
CoordinateCleaned while
detect_native_country() processes all
CoordinateProblematic records. The “Precise native-status
detection system” section has been revised to clarify the division of
labor between the two functions.cleaned_coordinates to detect_native_country()
instead of the previous customized_filtered argument.custom_filter() and refine_coordinates()
have been updated to customized_filter() and
clean_coordinates() respectively across package
documentation, ensuring consistency with actual function names.test-detect_native_country.R updated for new
input type. All 40 tests rewritten to create
CoordinateRefined objects instead of
customFiltered objects. New tests verify that records with
complete coordinates (those that failed validation) are correctly
processed alongside coordinateless records.test-refine_coordinates.R updated for
CoordinateProblematic behavior. All 32 tests
updated to reflect that CoordinateProblematic now includes
both validation-failed records and coordinateless records, with tests
confirming the correct categorization of each record type.