| Title: | Automated Soil Profile Classification per WRB 2022, 'SiBCS' 5 and USDA Soil Taxonomy 13 |
|---|---|
| Description: | Implements deterministic classification keys for the World Reference Base for Soil Resources 2022 (4th edition) and the Brazilian System of Soil Classification ('SiBCS', 5th edition). Provides a unified profile representation with explicit per-attribute provenance, multimodal extraction from field reports and photos via vision-language models, spatial priors from 'SoilGrids' and national soil maps, and gap-filling of soil attributes from Vis-NIR or MIR spectra via the Open Soil Spectral Library ('OSSL'). The taxonomic key itself is never delegated to a language model; LLMs are restricted to schema-validated extraction. Each classification result reports a key trace, a provenance-aware evidence grade, and ambiguities that further measurement would resolve. |
| Authors: | Hugo Rodrigues [aut, cre, cph] (ORCID: <https://orcid.org/0000-0002-8070-8126>) |
| Maintainer: | Hugo Rodrigues <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.9.313 |
| Built: | 2026-10-30 02:10:24 UTC |
| Source: | https://github.com/hugomachadorodrigues/soilkey |
Sharp clay-content increase between two superimposed mineral layers meeting all of (WRB 2022 3.2.1, p. 72):
underlying clay \>= 15% AND thickness \>= 7.5 cm;
underlying starts \>= 10 cm below the mineral soil surface;
underlying has, vs overlying: 2x clay if overlying < 20%, OR \>= 20pp (absolute) more clay if overlying \>= 20%;
transitional layer, if any, \<= 2 cm.
Since v0.9.312 criterion 5 is read from the distinctness of the lower
boundary of the overlying layer (boundary_distinctness): abrupt
(2 cm or less) or very abrupt passes, clear, gradual or diffuse fails, and
a boundary not recorded leaves the pair undecided (NA). Criterion 2
is counted from the mineral soil surface (below organic layers).
abrupt_textural_difference(pedon)abrupt_textural_difference(pedon)
pedon |
A |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
The Acrisols of the WRB 2022 key (Ch 4, p. 119): an argic horizon starting
100 cm from the mineral soil surface; a CEC (1 M NH4OAc, pH 7) of
< 24 cmolc/kg clay in some subhorizon of the argic horizon within 150 cm of
the mineral soil surface; and exchangeable Al > exchangeable (Ca+Mg+K+Na) in
half or more of 50-100 cm from the mineral soil surface, or of the lower half
of the mineral soil above a limiting layer starting 100 cm,
whichever is shallower. Where the cations are not available, the pH is read
by WRB 2022 Annex 2, Table 9.3.
acrisol(pedon, max_cec = 24, max_bs = 50)acrisol(pedon, max_cec = 24, max_bs = 50)
pedon |
A |
max_cec |
CEC per kg clay below which the clay is of low activity (default 24). |
max_bs |
Unused since v0.9.310 (WRB 2022 does not use the base saturation here), kept so that existing calls still run. |
IUSS Working Group WRB (2022), Chapter 4, Acrisols (p. 119).
Wind-deposited material in the upper 20 cm: rounded matt-surfaced sand
grains OR aeroturbation features, AND < 1% SOC in the upper 10 cm.
v0.3.3 detects via rock_origin == "aeolian" OR
layer_origin == "aeolic".
aeolic_material(pedon)aeolic_material(pedon)
pedon |
A |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Tongues of bleached, coarser-textured material penetrating an argic
horizon. v0.3.3 detects via designation pattern glossic|albeluvic
on a layer that overlies an argic-horizon-passing layer.
albeluvic_glossae(pedon)albeluvic_glossae(pedon)
pedon |
A |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
A bleached eluvial horizon – claric material that has lost iron oxides and/or organic matter due to clay migration, podzolization, or redox under stagnant water. Diagnostic for parts of Podzols, Retisols and Planosols qualifiers.
albic(pedon, min_thickness = 1)albic(pedon, min_thickness = 1)
pedon |
A |
min_thickness |
Minimum thickness in cm (default 1, per WRB 2022). The albic horizon has no canonical thickness gate; we keep a token min so that fully-NA layers don't pass. |
Sub-tests:
test_claric_munsell – Munsell criteria of claric
material (Ch 3.3.4).
Designation pattern E or Eg also serves as positive
evidence when Munsell columns are missing (proxy path).
IUSS Working Group WRB (2022), Ch 3.1 – Albic horizon.
The Alisols of the WRB 2022 key (Ch 4, p. 121): an argic horizon starting
100 cm from the mineral soil surface and exchangeable Al >
exchangeable (Ca+Mg+K+Na) in half or more of 50-100 cm (or of the lower half
of the mineral soil above a limiting layer starting 100 cm). The
key reaches them after the Acrisols and Lixisols.
alisol(pedon, min_cec = 24, min_al_sat = 50)alisol(pedon, min_cec = 24, min_al_sat = 50)
pedon |
A |
min_cec, min_al_sat
|
Unused since v0.9.310, kept so that existing calls still run. |
IUSS Working Group WRB (2022), Chapter 4, Alisols (p. 121).
Tests for the andic property complex – volcanic-ash-derived allophanic / imogolitic / Al-humus material. Diagnostic of Andosols. Two alternative qualifying paths per WRB 2022 Ch 3.2:
Al-Fe oxalate + low BD:
(Al_ox + 0.5*Fe_ox) >= min_alfe (default 2.0%) AND
bulk_density <= max_bd (default 0.9 g/cm^3) on the
same layer.
Phosphate retention: phosphate_retention_pct
>= min_p_retention (default 70%).
Either path qualifies. The volcanic-glass criterion is the
separate vitric_properties diagnostic; Andosols key
on (andic OR vitric) at the RSG-gate level (andosol).
andic_properties( pedon, min_alfe = 2, max_bd = 0.9, min_p_retention = 70, min_oc_proxy = 4, max_bd_proxy = 0.9 )andic_properties( pedon, min_alfe = 2, max_bd = 0.9, min_p_retention = 70, min_oc_proxy = 4, max_bd_proxy = 0.9 )
pedon |
A |
min_alfe |
Minimum (Al_ox + 0.5*Fe_ox) percent for the Al-Fe path (default 2.0). |
max_bd |
Maximum bulk density g/cm^3 for the Al-Fe path (default 0.9). |
min_p_retention |
Minimum phosphate retention % for the P path (default 70). |
min_oc_proxy |
Minimum SOC % for the v0.9.80 OC+BD proxy
path (default 4.0). Only consulted when the proxy is
enabled via |
max_bd_proxy |
Maximum bulk density g/cm^3 for the v0.9.80 OC+BD proxy path (default 0.9). Only consulted when the proxy is enabled. |
The answer is read layer by layer and is NA when a value it
needs is not recorded (until v0.9.312 an undecided profile returned
FALSE); evidence$layer_status holds the answer per layer.
A layer fails when Al_ox + 0.5*Fe_ox < min_alfe or the bulk
density > max_bd is measured (phosphate retention, an optional
path, can still pass it). Where bulk density is not measured,
Al_ox + 0.5*Fe_ox >= min_alfe together with a pH in NaF
(ph_naf) >= 9.5 in a carbonate-free layer passes, read from the
field test of WRB 2022 Ch 3.2.3; this is a proxy, named in
notes, reference and evidence$naf_field_test.
Field-described volcanic-ash soils (e.g.\ AfSP, KSSL/NASIS, SOTER)
routinely lack oxalate Al/Fe and phosphate retention measurements,
so the canonical paths return NA and Andosols cascade to
other RSGs. The genetic signature is still detectable from coarser
data: very high SOC (>= 4-5%) plus low bulk density
(<= 0.9 g/cm^3) typical of allophanic / Al-humus complexation.
With options(soilKey.andic_oc_bd_proxy = TRUE) the function
adds a third path that fires when both canonical paths fail and the
surface horizon shows oc_pct >= min_oc_proxy AND
bulk_density_g_cm3 <= max_bd_proxy (or OC alone >= 5% when
BD is missing). Default is FALSE (canonical behaviour
preserved).
When options(soilKey.andic_oc_bd_proxy_extend = TRUE)
(only meaningful with soilKey.andic_oc_bd_proxy = TRUE),
iteratively extend the proxy layers to include contiguous deeper
layers whose oc_pct >= min_oc_proxy / 2 AND whose
bulk_density_g_cm3 is missing OR
<= max_bd_proxy + 0.15. The extension stops at the first
horizon failing either constraint, so a ferralic / argic subsoil
cannot accidentally inflate the andic thickness. Default is
FALSE – canonical proxy behaviour preserved.
IUSS Working Group WRB (2022), Chapter 3, Andic properties.
WRB-canonical: layer(s) with andic OR vitric properties, combined thickness \>= 30 cm within 100 cm starting \<= 25 cm; OR \>= 60% of the entire soil thickness when a limiting layer starts 25-50 cm. Plus: no argic, ferralic, petroplinthic, pisoplinthic, plinthic or spodic horizon \<= 100 cm (unless buried below 50 cm).
andosol( pedon, min_thickness = 30, max_top_cm = 25, buried_below_cm = 50, strict = NULL )andosol( pedon, min_thickness = 30, max_top_cm = 25, buried_below_cm = 50, strict = NULL )
pedon |
A |
min_thickness |
Numeric threshold or option (see Details). |
max_top_cm |
Numeric threshold or option (see Details). |
buried_below_cm |
Numeric: layers of the exclusion diagnostics whose top_cm \>= this depth are treated as buried and do NOT exclude the Andosol (default 50, per WRB 2022 Ch 4 p 104). |
strict |
Logical or |
v0.3.4 enforces (1) andic OR vitric AND (2) combined thickness \>= 30 cm starting in the upper 25 cm AND (3) the negative-list exclusions on argic / ferralic / plinthic / spodic.
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
The combined thickness is that of every andic or vitric layer within
100 cm of the soil surface (clipped at 100 cm), provided the uppermost
starts \<= 25 cm; until v0.9.312 only layers starting \<= 25 cm were
added up. Item 1b applies: where a limiting layer starts \> 25 and
\<= 50 cm, andic or vitric layers covering \>= 60% of the soil above
it qualify. Petroplinthic and pisoplinthic horizons join the
exclusions. An argic horizon read from a clay increase alone (no clay
films recorded) whose layers all have andic properties does not
exclude (Hugo, N4: the clay of andic material does not disperse fully).
Layers whose andic or vitric status is not recorded leave the gate
undecided (NA) where they could change it.
WRB 2022 Ch 4 p 104 specifies the Andosol exclusion list (argic /
ferralic / petroplinthic / pisoplinthic / plinthic / spodic) as
"<= 100 cm unless buried below 50 cm". The earlier
implementation excluded an Andosol whenever any of those
diagnostics passed anywhere in the profile, including on layers
starting deeper than 50 cm – which mis-fires on AfSP Andosol
references like CM W3_0047, where an argic layer at
56-72 cm wrongly excluded the andic surface stack. v0.9.85
restricts the exclusion check to layers starting <= 50 cm:
a buried argic / ferralic / plinthic / spodic at deeper levels no
longer disqualifies the surface andic stack from Andosol.
With strict = TRUE the v0.9.85 buried-exclusion tolerance is
switched off: any argic / ferralic / plinthic / spodic horizon
anywhere in the profile excludes the Andosol, regardless of depth.
Applies usda_to_wrb_rsg to each pedon's USDA
classification (preserved as site$reference_usda +
site$reference_usda_suborder by
load_kssl_pedons_gpkg) and writes the result to
site$reference_wrb_from_usda – a "best-guess" expected WRB
label for benchmark comparison.
annotate_wrb_from_usda(pedons)annotate_wrb_from_usda(pedons)
pedons |
List of |
Pedons that already have site$reference_wrb populated (e.g.\
from external sources) are left untouched.
The same list, with site$reference_wrb_from_usda
populated where USDA classification is present.
Apl|Ap|Hh.Anthraquic horizon (WRB 2022): puddled-rice / paddy plough layer.
v0.3.3 detects via designation pattern Apl|Ap|Hh.
anthraquic(pedon, min_thickness = 20, max_top_cm = 50)anthraquic(pedon, min_thickness = 20, max_top_cm = 50)
pedon |
A |
min_thickness |
Numeric threshold or option (see Details). |
max_top_cm |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Tests for any of five anthropogenic surface horizons recognised by WRB 2022 (hortic, irragric, plaggic, pretic, terric). Diagnostic of Anthrosols. Two alternative paths qualify:
Designation: any layer's designation contains one
of hortic|irragric|plaggic|pretic|terric.
Property-based: a surface layer (top_cm <= 5)
at least min_thickness_cm cm thick (default 20)
with elevated dark colour (Munsell value moist <=
max_munsell_value, default 4) AND elevated
plant-available P (p_mehlich3_mg_kg >=
min_p_mg_kg, default 50).
Either path qualifies.
anthric_horizons( pedon, min_thickness_cm = 20, min_p_mg_kg = 50, max_munsell_value = 4 )anthric_horizons( pedon, min_thickness_cm = 20, min_p_mg_kg = 50, max_munsell_value = 4 )
pedon |
A |
min_thickness_cm |
Minimum thickness for the property-based path (default 20). |
min_p_mg_kg |
Minimum plant-available P (Mehlich 3, mg/kg) for the property-based path (default 50). |
max_munsell_value |
Maximum Munsell value moist for the property-based path (default 4). |
IUSS Working Group WRB (2022), Chapter 5, Anthrosols.
For each horizon and each requested attribute, interpolates the value
at the horizon's mid-depth from the six standard SoilGrids 2.0 depth
slices (0-5, 5-15, 15-30, 30-60, 60-100, 100-200 cm) and writes it
into the pedon with source = "inferred_prior". Existing values
are preserved unless overwrite = TRUE; the
PedonRecord authority order means a SoilGrids prior can
never silently displace a measured, spectra-predicted or VLM-extracted
value.
apply_soilgrids_depth_prior( pedon, attrs = NULL, depth_profiles = NULL, overwrite = FALSE )apply_soilgrids_depth_prior( pedon, attrs = NULL, depth_profiles = NULL, overwrite = FALSE )
pedon |
A |
attrs |
Character vector of horizon columns to fill. Defaults to
all SoilGrids-backed attributes: |
depth_profiles |
Optional named list mapping an attribute to a numeric vector of six slice values (0-5 ... 100-200 cm). When supplied the SoilGrids network call is skipped entirely – this is the path the test suite and offline users take. |
overwrite |
If |
This is the depth-resolved companion to
spatial_prior_soilgrids (which returns a site-level RSG
probability vector, not horizon attributes), and the attribute-fill
stage of classify_from_photos.
Invisibly, the mutated pedon. An attribute
"soilgrids_depth_fill" on the return value records how
many cells were filled.
## Not run: p <- make_cambisol_canonical() p$horizons$clay_pct <- NA_real_ # Offline: supply the six-slice profiles directly. apply_soilgrids_depth_prior( p, attrs = "clay_pct", depth_profiles = list(clay_pct = c(18, 20, 24, 28, 30, 30))) ## End(Not run)## Not run: p <- make_cambisol_canonical() p$horizons$clay_pct <- NA_real_ # Offline: supply the six-slice profiles directly. apply_soilgrids_depth_prior( p, attrs = "clay_pct", depth_profiles = list(clay_pct = c(18, 20, 24, 28, 30, 30))) ## End(Not run)
Composes the canonical soil-spectroscopy sequence, each step optional
and applied in this fixed scientific order:
reflectance (absorbance) (Savitzky-Golay
smoothing) (Savitzky-Golay 1st or 2nd derivative). Each
Savitzky-Golay pass trims (window - 1) / 2 columns from each
edge; the wavelength axis is trimmed to match and returned so callers
can plot the treated spectrum on the correct axis.
apply_spectral_preprocessing( X, wavelengths = NULL, absorbance = FALSE, sg_smooth = FALSE, sg_derivative = 0L, window = 11L, poly = 2L )apply_spectral_preprocessing( X, wavelengths = NULL, absorbance = FALSE, sg_smooth = FALSE, sg_derivative = 0L, window = 11L, poly = 2L )
X |
Numeric matrix (rows = samples/horizons, columns = wavelengths) or a numeric vector (treated as one sample). |
wavelengths |
Optional numeric wavelength axis. Defaults to the
numeric part of |
absorbance |
Logical; apply |
sg_smooth |
Logical; apply Savitzky-Golay smoothing
( |
sg_derivative |
Integer |
window |
Odd Savitzky-Golay window (default |
poly |
Savitzky-Golay polynomial order (default |
The transform is robust: reflectance that looks like a percentage
(maximum > 1.5) is rescaled to a 0–1 fraction before the
absorbance log, values are clamped away from zero to avoid
log(0), and a Savitzky-Golay step that cannot fit the requested
window into the available wavelengths is skipped (recorded in
steps) rather than erroring.
A list with X (the treated numeric matrix, wavelength
column names trimmed to match), wavelengths (numeric)
and steps (an ordered character vector describing the
transforms actually applied, starting with
"Reflectance").
X <- matrix(seq(0.1, 0.5, length.out = 3 * 60), nrow = 3, byrow = TRUE) colnames(X) <- seq(400, 2400, length.out = 60) res <- apply_spectral_preprocessing(X, absorbance = TRUE, sg_smooth = TRUE, sg_derivative = 1L) res$steps # ordered treatment labels dim(res$X) # columns trimmed by the two SG passesX <- matrix(seq(0.1, 0.5, length.out = 3 * 60), nrow = 3, byrow = TRUE) colnames(X) <- seq(400, 2400, length.out = 60) res <- apply_spectral_preprocessing(X, absorbance = TRUE, sg_smooth = TRUE, sg_derivative = 1L) res$steps # ordered treatment labels dim(res$X) # columns trimmed by the two SG passes
Tests the texture of the Arenosols (WRB 2022 Ch 4, p. 124): within
100 cm of the mineral soil surface, a weighted average texture of loamy
sand or sand (silt + 2 * clay < 30), layers of finer texture and
layers with 40% coarse fragments each with a combined
thickness of < 15 cm (v0.9.314; until then every layer had to be coarser
than sandy loam). Diagnostic of Arenosols.
arenic_texture(pedon, max_top_cm = 100, engine = NULL)arenic_texture(pedon, max_top_cm = 100, engine = NULL)
pedon |
A |
max_top_cm |
Maximum top depth (cm) of layers to be tested (default 100, per WRB 2022). |
engine |
One of |
Sub-test: test_arenosol_texture. A part of the 100 cm whose
texture or coarse fragments are not recorded, or that is not described,
leaves the result undecided (NA) when it could change it.
v0.3 limitations: WRB 2022 Arenosol also requires that no other diagnostic horizon (argic, ferralic, etc.) is present, but those exclusions happen at the key level via canonical RSG order.
IUSS Working Group WRB (2022), Chapter 5, Arenosols.
Tests whether any horizon meets the argic horizon criteria per Chapter 3 of the WRB 2022 (4th edition). Argic is a subsurface horizon with distinctly higher clay content than the overlying horizon, qualified by three depth-conditional clay-increase rules; it must also have texture of sandy loam or finer, satisfy a minimum thickness, and not exhibit albeluvic glossic features (which would direct the profile to the Retisol path).
argic( pedon, min_thickness = 7.5, system = c("wrb2022", "usda"), engine = NULL, require_t = NULL, lithic_discontinuity = NULL )argic( pedon, min_thickness = 7.5, system = c("wrb2022", "usda"), engine = NULL, require_t = NULL, lithic_discontinuity = NULL )
pedon |
A |
min_thickness |
Minimum thickness in cm (default 7.5). |
system |
One of |
engine |
v0.9.63+. One of |
require_t |
v0.9.63+. Forwarded to |
lithic_discontinuity |
v0.9.220. Apply WRB 2022 criterion 2.a.i:
a clay increase over a coarser layer of another material (Ap over
2Bt, read from the designations' material numbers) counts only
with clay films of "common" or more (illuvial clay, criterion 2.b).
|
Sub-tests called (each a list with passed, layers,
missing, details, notes):
test_clay_increase_argic – the three-pronged
WRB 2022 clay-increase rule.
test_minimum_thickness – thickness >= 7.5 cm
(configurable via min_thickness).
test_texture_argic – texture of sandy loam or
finer (silt + 2 * clay >= 30).
Until v0.9.219 a glossic, albeluvic or retic designation anywhere voided the argic horizon (the WRB 2014 Albeluvisol logic); in WRB 2022 retic properties belong to an argic or natric horizon.
v0.9.310, for system = "wrb2022" (WRB 2022 Ch 3.1.3, p. 35-36):
criterion 1: the layers have 8% clay;
criterion 2.a.i (v0.9.317): the coarser-textured layer is not separated from the layer by a lithic discontinuity, read from the material numbers of the designations and from the data of each pair of layers in between (Ch 3.2.7, p. 76-77: the ratio sand to silt, criterion 2.a.iv; coarse fragments, criterion 6);
criterion 2.a.ii (v0.9.317): no clay increase counts below a plough layer (Ap) that directly overlies the argic horizon;
criterion 2.a.iii: a layer is compared with a coarser-textured layer
above it only across a transitional horizon of 15 cm;
layers already accepted and layers whose designation has the
suffix t are part of the argic horizon, not transitional;
criterion 2.b.ii: clay films of "common" or more (clay coatings on
15% of the aggregate surfaces) make a layer argic
without a clay increase;
a subsurface horizon: the layer at the mineral soil surface and the A horizons are not part of it.
The USDA argillic and order keys and the SiBCS B textural keep the earlier reading.
IUSS Working Group WRB (2022). World Reference Base for Soil Resources, 4th edition. International Union of Soil Sciences, Vienna. Chapter 3 – Argic horizon.
Wraps aqp::getArgillicBounds() (Beaudette et al.) in soilKey's
DiagnosticResult contract. The aqp implementation is
the canonical NRCS R port and uses the tiered USDA-NRCS clay-increase
thresholds:
Eluvial clay < 15\
Eluvial clay 15-40\
Eluvial clay \>= 40\
(vs. soilKey's hand-coded argic which uses the WRB
6/1.4/20 thresholds). For BDsolos / FEBR / KSSL profiles the aqp
rule is closer to KST 13ed and BDsolos field practice.
argic_aqp(pedon, require_t = FALSE, ...)argic_aqp(pedon, require_t = FALSE, ...)
pedon |
A |
require_t |
Whether to require an explicit "t" suffix in the
horizon designation (default |
... |
Reserved for future arguments. |
By default aqp requires a "t" suffix in the horizon designation
(require_t = TRUE); we expose this so callers can be
permissive on datasets where designation is missing or
non-conforming (BDsolos exports often drop the "t").
A DiagnosticResult with name =
"argic_aqp". $layers are the row indices of horizons
in the argillic / argic depth interval. $evidence carries
the raw aqp c(ubound, lbound) bounds for traceability.
argic (soilKey hand-coded; WRB 6/1.4/20),
aqp::getArgillicBounds.
Wraps argic() and inspects the
clay_films_amount field at the argic-passing layers. Returns
a structured result that B_latossolico() used, from
v0.9.61 to v0.9.240, to decide whether a B textural excluded it.
argic_with_strong_clay_films(pedon)argic_with_strong_clay_films(pedon)
pedon |
A |
Since v0.9.241 the SiBCS key does not use this rule: the B textural is
tested by the items of the book and excludes the B latossolico, whose
cerosidade is tested layer by layer (see B_textural and
B_latossolico). The function is kept to inspect a dataset.
A list with:
passed – logical, TRUE only when argic passes
AND at least one argic-passing layer has a strong
(comum / abundante) film qualifier.
layers – integer vector of argic-passing layer
indices (empty when passed is FALSE).
argic – the underlying DiagnosticResult
from argic().
films – character vector of the
clay_films_amount values at the argic-passing layers.
KST 13ed argillic horizon requires "evidence of illuvial accumulation of clay" alongside the clay-increase rule. Acceptable evidence:
oriented clays bridging sand grains in >= 1% of the horizon;
clay films lining pores or coating ped faces;
lamellae more than 5 mm thick.
argillic_clay_films_test(pedon)argillic_clay_films_test(pedon)
pedon |
A |
This test reads three complementary slots, in order of evidence strength:
pedon$site$nasis_diagnostic_features – the NASIS
pediagfeatures.featkind vector. The surveyor's
explicit "Argillic horizon" entry directly confirms
clay-illuviation evidence (~13 500 entries in the 2021
NASIS snapshot). Strongest evidence.
pedon$horizons$clay_films_amount – per-horizon
clay-film abundance derived from NASIS phpvsf.
Values: "few", "common", "many",
"continuous". Direct measurement.
pedon$horizons$designation containing a 't'
master suffix (e.g. Bt, Btk, Btx,
Bt1, 2Bt). v0.9.28: the pedologist who
wrote that designation explicitly identified the
horizon as clay-illuvial – per KST 13ed Ch 18, the 't'
suffix means "accumulation of silicate clay" – so it
counts as positive evidence even when NASIS records are
absent. This unlocks the KST 13ed argillic thresholds
for the ~47
pediagfeatures and phpvsf records.
Any of the three sources counts as positive evidence (logical OR).
passed = NA when none is populated AND no horizon designation
field is present at all (lab-only loaders without horizon
descriptions). passed = FALSE when designations exist but
none has a 't' suffix and NASIS slots are empty.
Soil Survey Staff (2022), Keys to Soil Taxonomy 13th
ed., Ch. 3, argillic horizon (clay-illuviation criteria, p. 4);
Ch. 18, master horizon symbols (t: silicate-clay
accumulation, p. 332).
Per the canonical definition: human-made / human-altered / human-
excavated material. v0.3.3 returns the layers where
artefacts_pct >= 1.
artefacts(pedon, min_pct = 1)artefacts(pedon, min_pct = 1)
pedon |
A |
min_pct |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Builds a aqp::SoilProfileCollection from one PedonRecord
or a list of them. Standard soilKey columns (top_cm,
bottom_cm, designation, clay_pct, sand_pct,
silt_pct) are renamed to aqp's canonical convention (top,
bottom, name, clay, sand, silt).
All other columns are passed through unchanged. Site-level slots
(lat, lon, country, parent_material,
reference_*, nasis_diagnostic_features, etc.) are
attached to the SPC's site table.
as_aqp(x)as_aqp(x)
x |
A |
Requires the aqp package, listed in Suggests; the function
raises a clear error if aqp is not installed.
A aqp::SoilProfileCollection.
from_aqp, the inverse conversion.
## Not run: library(soilKey) library(aqp) pedons <- list(make_ferralsol_canonical(), make_luvisol_canonical()) spc <- as_aqp(pedons) length(spc) # 2 profiles aqp::horizons(spc) # one row per horizon, aqp-named columns ## End(Not run)## Not run: library(soilKey) library(aqp) pedons <- list(make_ferralsol_canonical(), make_luvisol_canonical()) spc <- as_aqp(pedons) length(spc) # 2 profiles aqp::horizons(spc) # one row per horizon, aqp-named columns ## End(Not run)
Joins the LUCAS Soil 2018 Spectral Library (separate ESDAC release,
~83 GB) onto the pedons returned by
load_lucas_soil_2018, by matching the LUCAS
POINT_ID of the spectra against pedon$site$id. Each
matched pedon gets $spectra$vnir populated as a numeric
matrix (rows = horizons, cols = wavelengths).
attach_lucas_spectra( pedons, spectra, point_id_col = "POINT_ID", verbose = TRUE )attach_lucas_spectra( pedons, spectra, point_id_col = "POINT_ID", verbose = TRUE )
pedons |
List of |
spectra |
A wide or long |
point_id_col |
Name of the LUCAS point-id column in
|
verbose |
If |
Two input shapes are accepted:
A wide data.frame keyed by an integer
POINT_ID column with one column per wavelength
(column names parseable as numeric nm). One row per
LUCAS point.
A long data.frame with columns POINT_ID,
wavelength_nm, reflectance.
Spectra are attached only to the topsoil horizon (row 1); the
subsoil horizon (if any) is left without spectra. After this call,
benchmark_lucas_2018(..., fill_topsoil_from = "spectra",
ossl_models = ...) feeds the spectra through
predict_from_spectra (v0.9.46) to fill any
chemistry / texture gap not already populated by SoilGrids.
The list of pedons (mutated in place; returned invisibly).
predict_from_spectra,
predict_munsell_from_spectra,
load_lucas_soil_2018.
Applies argic_with_strong_clay_films() to every
pedon in pedons and returns a per-pedon table summarising
how the rule that B_latossolico() applied from v0.9.61 to
v0.9.240 resolves on the benchmark sample: a B textural (the WRB argic
horizon, then) excluded the B latossolico only when its clay films were
common or more.
audit_argic_strong_films(pedons, reference_filter = NULL)audit_argic_strong_films(pedons, reference_filter = NULL)
pedons |
List of |
reference_filter |
Optional regex applied to
|
Since v0.9.241 the SiBCS key does not use that rule (see
B_latossolico); the audit shows what it would have done
on field-described datasets such as BDsolos and Redape, where
clay-film qualifiers are recorded in mixed Portuguese / English
tokenisation. The audit is read-only and never invokes
classify_sibcs().
A data.frame with columns
id, reference_sibcs,
argic_passed,
has_films_at_argic,
strong_films_at_argic,
and would_exclude_from_latossolo.
## Not run: peds <- load_bdsolos_csv("RJ.csv") a <- audit_argic_strong_films(peds, reference_filter = "LATOSSOLO") table(a$would_exclude_from_latossolo) ## End(Not run)## Not run: peds <- load_bdsolos_csv("RJ.csv") a <- audit_argic_strong_films(peds, reference_filter = "LATOSSOLO") table(a$would_exclude_from_latossolo) ## End(Not run)
Probes the common system locations for PROJ proj.db and
GDAL data directories, on macOS Homebrew (Apple silicon and
Intel), Linuxbrew, conda / mamba environments, and Debian /
Ubuntu / Fedora apt or dnf installs. Sets the corresponding
environment variables only when they are not already set, so a
user-provided value always wins. Idempotent: safe to call
repeatedly.
auto_set_proj_env(verbose = FALSE)auto_set_proj_env(verbose = FALSE)
verbose |
If |
Called automatically from .onLoad; call manually after
installing PROJ / GDAL via Homebrew if you want to refresh the
env without restarting R.
Invisibly, a named list with PROJ_LIB and
GDAL_DATA (the values that were set, or
NA_character_ if a value was already present
or no candidate was found).
Walks 'raster_root' and returns the folder names that contain a
valid '<NAME>.tif' raster. Useful for discovery before calling
lookup_esdb.
available_esdb_attributes(raster_root)available_esdb_attributes(raster_root)
raster_root |
Path to the unpacked ESDB raster directory (typically '<some>/ESDB-Raster-Library-1k-GeoTIFF-...'). |
A character vector of attribute names (sorted).
## Not run: available_esdb_attributes("~/data/ESDB-Raster-Library-1k-GeoTIFF-20240507") #> [1] "AGLI1NNI" "AGLI2NNI" "AGLIM1" "AGLIM2" "ALT" "ATC" "AWC_SUB" ... #> [continued: 71 attributes] ## End(Not run)## Not run: available_esdb_attributes("~/data/ESDB-Raster-Library-1k-GeoTIFF-20240507") #> [1] "AGLI1NNI" "AGLI2NNI" "AGLIM1" "AGLIM2" "ALT" "ATC" "AWC_SUB" ... #> [continued: 71 attributes] ## End(Not run)
Subsuperficial com acumulo iluvial de Al + Fe + materia organica;
espessura \>= 2.5 cm. Tipos: Bs, Bhs, Bh, ortstein. Reuso de
spodic (WRB) que ja codifica criterios essencialmente
identicos.
B_espodico(pedon, ...)B_espodico(pedon, ...)
pedon |
A |
... |
Reserved for future arguments. |
In the morphological mode the horizon is also read from its designation.
Since v0.9.247 that includes the "ir" of the older surveys (Bir,
B2ir, B22irx), the illuvial iron that the present notation
writes "s": the mode read "h" and "s" only.
Since v0.9.255 a horizon that the WRB test does not find is looked for by item (a) of the book (p. 65), in both modes. The B espodico has an "acumulacao iluvial de compostos organometalicos" and, by that item, "um horizonte E (albico ou nao) sobrejacente e cores umidas de acordo com um dos itens a seguir: 1) matiz 5YR ou mais vermelho; 2) matiz 7,5YR com valor 5 ou menor e croma 4 ou menor; 3) matiz 10YR, com valor e croma 3 ou menor; 4) cores neutras com valor 3 ou menor". A B layer of 2.5 cm or more passes when:
an E lies above it in the profile;
its moist colour is one of the four;
its organic carbon is 0.5% or more and at least twice that of the nearest E above it; and
no cerosidade is recorded in it.
The last two stand for the illuvial accumulation, which the sheets do not measure where there is no oxalate extraction. The first takes the form the book gives in item (b)(3) for aluminium and iron by oxalate, "valor 0,50 ou maior, sendo este valor pelo menos o dobro do encontrado no horizonte sobrejacente"; the second keeps out the B whose illuvial material is clay. It is a reading by analogy, decided on 2026-10-13, and not the letter of the book: the colours alone are those of the B textural of many an Argissolo below an E. Items (b) and (c), the cementation and the ortstein, are not tested.
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Subsuperficial sob A/Ap/AB com alteracao fisica e quimica incipiente, NAO satisfazendo a B textural / latossolico / nitico / espodico / planico, com:
espessura \>= 10 cm;
textura francoarenosa ou mais fina;
< 50% estrutura da rocha original;
evidencias de pedogenese (cor mais viva OR remocao de
carbonatos OR designation Bw/Bi);
NAO satisfaz: argic, ferralic, espodic, planic, e nao tem duripa/petrocalcico/fragipa.
B_incipiente(pedon, min_thickness = 10)B_incipiente(pedon, min_thickness = 10)
pedon |
A |
min_thickness |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
The requirements of the book that the data of a profile can show (v0.9.241):
(d) texture francoarenosa or finer;
(g) cation exchange capacity below 17 cmolc per kg of clay, with no correction for carbon;
(e) a molecular ratio SiO2/Al2O3 (Ki) of 2.2 or less, where the
sulfuric attack is recorded (sio2_sulfuric_pct,
al2o3_sulfuric_pct): a layer with a Ki above 2.20 is no
B latossolico (v0.9.243);
(h) cerosidade, if present, at most few and weak: a layer with a larger amount or a higher grade is no B latossolico (a range counts by its upper end, the requirement being a maximum);
(b) a thickness of 50 cm or more, of the horizon: of the adjoining sub-horizons that meet the other requirements, taken together;
it "nao apresenta caracteristicas diagnosticas de horizontes glei,
B textural, B nitico e plintico": the layers of a
B_textural, of a horizonte glei, of a horizonte
plintico and of a B_nitico are no B latossolico.
Since v0.9.249 they take out their own layers only: until then the
glei and the plinthic horizon were those of WRB (gleyic
properties, plinthic horizon), and one of them, or a B nitico,
anywhere in the profile voided the B latossolico of the whole
profile.
Where the designations are recorded, only B horizons are candidates: the B latossolico is a subsurface horizon below the A. Items (a) structure, (c) rock structure and (f) weatherable minerals are not tested.
B_latossolico( pedon, min_thickness = 50, max_cec_per_clay = NULL, engine = NULL, ... )B_latossolico( pedon, min_thickness = 50, max_cec_per_clay = NULL, engine = NULL, ... )
pedon |
A |
min_thickness |
Minimum thickness of the horizon, in cm (50). |
max_cec_per_clay |
CEC per kg clay the horizon must stay below.
Defaults to |
engine |
One of |
... |
Reserved for future arguments. |
Until v0.9.240 the 50 cm were asked of each layer on its own, so that a B latossolico described as B1, B21 and B22 of 35 cm each was none; and since v0.9.61 a B textural did not exclude it unless its clay films were common or more, on a rule the comments attributed to Cap 18 of the book, which deals with families and series.
In the morphological mode a "Bw" or "Bo" of a tropical profile stands for the B latossolico when the data do not show it.
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Subsuperficial nao hidromorfico, textura argilosa/muito argilosa (clay \>= 35% desde a superficie), com pequeno incremento de argila (B/A \<= 1.5), estrutura em blocos sub/angulares ou prismatica grau moderado/forte, cerosidade no minimo comum + moderada, espessura \>= 30 cm. Argila ativ baixa OR ativ alta + carater aluminico.
B_nitico( pedon, min_thickness = 30, min_clay_pct = 35, max_b_a_ratio = 1.5, min_cerosidade = c("common", "many", "abundant", "strong") )B_nitico( pedon, min_thickness = 30, min_clay_pct = 35, max_b_a_ratio = 1.5, min_cerosidade = c("common", "many", "abundant", "strong") )
pedon |
A |
min_thickness |
Numeric threshold or option (see Details). |
min_clay_pct |
Numeric threshold or option (see Details). |
max_b_a_ratio |
Numeric threshold or option (see Details). |
min_cerosidade |
Terms of the amount of cerosidade that satisfy criterion (c). The lowest of them on the scale none < few < common < many sets the threshold (the default is "common", the "comum" of SiBCS), and an amount of that class or above passes, in English or Portuguese. A term the scale does not know passes only if it is literally listed. |
The amount of cerosidade (clay_films_amount) and the type of
structure (structure_type) are read as the field sheet words them,
in English or in Portuguese, whatever the case and the accents: "Comum",
"Abundante" and "Prismatica que se desfaz" (written with its accent) of the
Brazilian surveys count as "common", "many" and "prismatic" do. Until v0.9.226 the amount was
compared with the literal English terms of min_cerosidade, so no
profile described in Portuguese could have a B nitico.
The criteria of the B nitico are minima ("cerosidade em quantidade no minimo comum e com grau forte ou moderado", "estrutura ... de grau de desenvolvimento moderado ou forte"), and a range meets a minimum only if all of it does: an amount or a grade written as a range is read by its lower end. "Pouca a comum" is below "comum" and, since v0.9.231, "Fraca a moderada" is below "moderada" for the cerosidade and for the structure.
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
"E um tipo especial de horizonte B textural, com ou sem carater sodico, subjacente a horizontes A ou E, apresentando mudanca textural abrupta ou transicao abrupta associada a relacao textural com valor dentro do especificado para o horizonte B textural (subitem h), porem calculado entre o primeiro sub-horizonte B e o horizonte imediatamente acima (A ou E)".
B_planico(pedon)B_planico(pedon)
pedon |
A |
Since v0.9.244 the horizon is looked for where the book puts it, in the first B sub-horizon, below an A or an E, by one of the two:
a mudanca_textural_abrupta from the A or E to it; or
a transition recorded as abrupt (boundary_distinctness) with
a ratio of its clay to that of the horizon above over the limit of
item (h) of the B textural (1.50, 1.70 or 1.80).
As a type of B textural, that sub-horizon has a texture francoarenosa or finer (p. 54): one known to be coarser is no B planico, whatever its clay over that of the E. The structure and the colours below are asked of that first sub-horizon. Until v0.9.243 any layer with a jump of clay over the layer above it could be the B planico, the second way was not tested, and the structure and the colours were asked of the layer with the jump. A profile with no horizon designation at all is still tested that way.
The structure (p. 65): "Apresenta estrutura prismatica, colunar ou em
blocos angulares e subangulares grandes ou medios e, as vezes, estrutura
macica". It is tested where the sheet records it
(structure_type, structure_size): a prismatic, columnar or
massive structure passes; blocks pass when medium or larger, or when
their size is not recorded; any other recorded structure does not pass.
The colours "devem atender a pelo menos um dos seguintes requisitos" (p. 65-66):
(a) the matrix colour, with or without mottles: "Matiz 10YR ou mais amarelo, cromas <= 3" or "Matizes 7,5YR ou 5YR, cromas <= 2";
(b) "Coloracao variegada com pelo menos uma cor apresentando matiz
e croma conforme especificado no item (a)" (variegated_colors);
(c) "matiz 10YR ou mais amarelo, cromas >= 4, combinado com
mosqueado de croma conforme especificado no item (a)": a mottle
colour (mottle_colors) that satisfies item (a).
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
The B textural as the book states it: a subsurface horizon of texture francoarenosa or finer, at least 7.5 cm thick (thickness items a to e), that meets one or more of the items below (v0.9.241).
(f) an E horizon above the B, the B having more clay than the horizons above it and being no B espodico, plintico or planico;
(g) a mudanca textural abrupta from the A or E to the B (Cap 1,
p 30-31): at least twice the clay when the A or E has less than
200 g/kg, 200 g/kg more otherwise, within 7.5 cm. The distance is
read from the distinctness of the transition
(boundary_distinctness: abrupt or clear); where it is not
recorded the two layers are compared;
(h) the relacao textural B/A of footnote 4, above 1.50, 1.70 or
1.80 according to the clay of the A
(test_ratio_textural_sibcs);
(i) where the increase is below item (h), the cerosidade of one or more sub-horizons of the upper part of the B (read as its upper half): (1) texture media with no macroaggregates and cerosidade of moderate grade; (2) texture media with prismatic or blocky structure of moderate or strong grade and cerosidade of at least moderate grade; (3) texture argilosa or muito argilosa with that structure and cerosidade at least common and weak or few and moderate; (4) relacao textural of 1.4 or more with a fragipa within 200 cm, the B being no B espodico;
(j) with a discontinuity of parent material between the A or E and the B, or with only a ploughed layer above the B, items (h) or (i) are needed.
Amounts and grades written as ranges are read by their lower end, the requirements being minima. Lamellae (item d) are not tested.
B_textural(pedon, ...)B_textural(pedon, ...)
pedon |
A |
... |
Passed to |
Until v0.9.240 this function was the WRB argic horizon, whose
clay increase (6 percentage points, a ratio of 1.4 or 20 points, between a
layer and the least clayey layer anywhere above it) is not the one of the
book, joined to item (h); items (f), (g) and (i) were not tested.
The layers returned are the B sub-horizons (BC excluded) of texture
francoarenosa or finer; evidence$upper_layers are those that carry
the evidence, from the top of the B down.
The items are stated for the A, E and B horizons. A profile with no horizon designation at all (depth slices, for instance) cannot be read by them and is tested as before, by the clay increase between layers.
In the morphological mode
(options(soilKey.morphological_inference = TRUE)) a "t" in the
designation of a B horizon stands for the B textural when the items do not
show it. The diagnostic engine
(options(soilKey.diagnostic_engine = "aqp")) does not change this
test: it changed the argic horizon that this function used to be.
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Runs classification_robustness on each pedon in a
list and returns a tidy data.frame with one row per pedon. Useful
for paper-grade claims like "85
to a 5
batch_robustness(pedons, ...)batch_robustness(pedons, ...)
pedons |
List of |
... |
Passed to |
A data.frame with columns id, baseline,
robustness, n_flipped.
## Not run: pedons <- list(make_ferralsol_canonical(), make_luvisol_canonical(), make_chernozem_canonical()) batch_robustness(pedons, system = "wrb2022", n = 50) #> id baseline robustness n_flipped #> 1 FR-canon-01 Ferralsols 0.96 2 #> 2 LV-canon-01 Luvisols 1.00 0 #> 3 CH-canon-01 Chernozems 0.94 3 ## End(Not run)## Not run: pedons <- list(make_ferralsol_canonical(), make_luvisol_canonical(), make_chernozem_canonical()) batch_robustness(pedons, system = "wrb2022", n = 50) #> id baseline robustness n_flipped #> 1 FR-canon-01 Ferralsols 0.96 2 #> 2 LV-canon-01 Luvisols 1.00 0 #> 3 CH-canon-01 Chernozems 0.94 3 ## End(Not run)
Benchmark soilKey WRB predictions against AfSP ground truth
benchmark_afsp(pedons, verbose = TRUE)benchmark_afsp(pedons, verbose = TRUE)
pedons |
A list of |
verbose |
Print progress. |
List with accuracy, n_compared, confusion,
per_class_recall.
Runs classify_wrb2022, classify_sibcs, and
classify_usda on each PedonRecord loaded
from a BDsolos CSV via load_bdsolos_csv, then compares
each predicted classification against the corresponding BDsolos
reference label (reference_sibcs, reference_wrb,
reference_st) and reports per-system accuracy, per-class
recall, and a confusion matrix.
benchmark_bdsolos( pedons, systems = c("wrb2022", "sibcs", "usda"), sibcs_level = c("order", "subordem"), max_n = NULL, verbose = TRUE, sampling_type = "Perfil completo" )benchmark_bdsolos( pedons, systems = c("wrb2022", "sibcs", "usda"), sibcs_level = c("order", "subordem"), max_n = NULL, verbose = TRUE, sampling_type = "Perfil completo" )
pedons |
A list of |
systems |
Character vector. Any subset of |
sibcs_level |
One of |
max_n |
Optional integer; cap classification at the first
|
verbose |
If |
sampling_type |
The kinds of sampling point the figures of each
system are computed on, as |
A list with elements:
per_system – named list (one entry per requested
system) of list(accuracy, n_compared, n_correct,
n_errors, confusion, per_class, by_sampling_type,
sampling_type) (or
list(accuracy = NA_real_, message) when no
reference labels were present). by_sampling_type is a
data frame with one row per kind of point and one for all the
records (n_compared, n_correct,
accuracy), or NULL when no pedon carries the
field; sampling_type is the kinds the main figures were
computed on (NULL for all).
coverage – named list of
list(n_with_ref, n_total, pct) per system.
config – named list capturing
n_pedons, systems, sibcs_level, soilKey_version,
timestamp.
BDsolos densely populates reference_sibcs (~82
of the v0.9.59 audit) but sparsely populates reference_wrb and
reference_st (UF-dependent; ~5
states). The function always reports the per-system label coverage
($coverage) so the caller can judge how representative each
accuracy figure is.
SiBCS comparison is at level = "order" by default, which
converts the BDsolos all-caps Portuguese label (e.g.
"ARGISSOLO VERMELHO Tb EUTROFICO ...") to the soilKey plural
Title Case form ("Argissolos") via
normalise_febr_sibcs. Set sibcs_level =
"subordem" to compare the first two SiBCS tokens (Ordem + Subordem).
WRB and USDA comparisons are at the Reference Soil Group / Order
level: normalise_febr_wrb() strips qualifier parens and
pluralises the bare RSG ("Xanthic Ferralsol" ->
"Ferralsols"); normalise_febr_usda() maps the suffix of
the last subgroup token to the USDA Order ("Typic
Haplorthox" -> "Oxisols").
Pedons without a reference label for a given system are silently
excluded from THAT system's comparison (but still classified for the
other two systems). If a system has zero pedons with a reference
label, the corresponding $per_system entry has
accuracy = NA_real_ and message = "no_reference_labels".
Classifier errors are caught per-pedon and recorded in
n_errors; they do not abort the run.
The export marks each record as "Perfil completo", "Perfil
parcial" or "Amostra extra" (site$sampling_type, read by
load_bdsolos_csv since v0.9.242). An extra sample is not a
described profile: in most cases it is two sampled layers, and the
thickness a diagnostic horizon is asked for cannot be read from it. The
figures of each system (accuracy, n_compared,
n_correct, confusion, per_class) are therefore those
of the complete profiles by default, and by_sampling_type gives the
same counts for every kind and for all the records together. Pedons that
carry no site$sampling_type (another source, a hand-made list) are
all counted, as before.
load_bdsolos_csv,
benchmark_lucas_2018, classify_all,
normalise_febr_sibcs,
normalise_febr_wrb,
normalise_febr_usda.
## Not run: # Single UF -- typical SiBCS-dense slice peds <- load_bdsolos_csv("RJ.csv") bench <- benchmark_bdsolos(peds, systems = c("sibcs", "wrb2022", "usda")) bench$coverage # how many pedons had each reference label bench$per_system$sibcs$accuracy bench$per_system$sibcs$confusion # Subordem level bench2 <- benchmark_bdsolos(peds, systems = "sibcs", sibcs_level = "subordem") ## End(Not run)## Not run: # Single UF -- typical SiBCS-dense slice peds <- load_bdsolos_csv("RJ.csv") bench <- benchmark_bdsolos(peds, systems = c("sibcs", "wrb2022", "usda")) bench$coverage # how many pedons had each reference label bench$per_system$sibcs$accuracy bench$per_system$sibcs$confusion # Subordem level bench2 <- benchmark_bdsolos(peds, systems = "sibcs", sibcs_level = "subordem") ## End(Not run)
Classifies each pedon read by read_isis with the WRB 2022 and
Soil Taxonomy keys and sets the result beside the names ISRIC gives the
profile. The WRB comparison uses the Reference Soil Group, and only when
ISRIC's name is from the 2022 edition; the USDA one uses the order (ISRIC's
USDA names are from the 1975 to 1999 editions, so subgroups are shown but
not scored).
benchmark_isis(pedons)benchmark_isis(pedons)
pedons |
A list of |
A data frame, one row per profile, with ISRIC's and soilKey's names,
wrb_agree and usda_order_agree (NA where ISRIC gives
no comparable name) and the number of close calls of each key.
For each pedon in pedons, attaches the canonical Reference
Soil Group at its coordinate via lookup_esdb, runs
classify_wrb2022 (or classify_sibcs),
and tabulates predicted vs reference. Optionally fills missing
texture from ISRIC SoilGrids 250m before classifying so that
WRB diagnostic horizons that depend on clay (argic, ferralic,
nitic) are reachable.
benchmark_lucas_2018( pedons, esdb_root, attribute = "WRBLV1", fill_texture_from = NULL, fill_topsoil_from = c("none", "soilgrids", "spectra"), fill_subsoil_from = c("none", "soilgrids"), fill_properties = c("clay", "sand", "silt", "phh2o", "soc", "cec", "bdod", "nitrogen", "cfvo"), ossl_models = NULL, classify_with = c("wrb2022", "sibcs"), max_n = NULL, soilgrids_lookup_fn = lookup_soilgrids, verbose = TRUE )benchmark_lucas_2018( pedons, esdb_root, attribute = "WRBLV1", fill_texture_from = NULL, fill_topsoil_from = c("none", "soilgrids", "spectra"), fill_subsoil_from = c("none", "soilgrids"), fill_properties = c("clay", "sand", "silt", "phh2o", "soc", "cec", "bdod", "nitrogen", "cfvo"), ossl_models = NULL, classify_with = c("wrb2022", "sibcs"), max_n = NULL, soilgrids_lookup_fn = lookup_soilgrids, verbose = TRUE )
pedons |
List of |
esdb_root |
Path to the unpacked ESDB raster directory
(containing the |
attribute |
ESDB attribute to use as reference. Default
|
fill_texture_from |
Deprecated alias for
|
fill_topsoil_from |
One of |
fill_subsoil_from |
One of |
fill_properties |
Character vector of SoilGrids properties
to fill when |
ossl_models |
Required when |
classify_with |
One of |
max_n |
Optional integer cap on the number of pedons benchmarked. Useful for quick development runs. |
soilgrids_lookup_fn |
Internal: SoilGrids lookup function
(defaults to |
verbose |
If |
This closes Route B of the v0.9.27 EU-LUCAS roadmap end-to-end:
v0.9.44 lookup_esdb provides the reference label;
v0.9.49 (this) provides the loader and the comparison loop;
v0.9.48 lookup_soilgrids fills texture; v0.9.46
predict_from_spectra and v0.9.47
predict_munsell_from_spectra can fill the
chemistry / Munsell gaps when Vis-NIR is available.
A list with elements:
predictionsdata.frame with one row per pedon:
point_id, lon, lat, country, predicted,
reference_code, reference_name, agree.
confusionConfusion table (predicted vs reference) over in-scope rows.
accuracyOverall fraction of correct classifications among in-scope rows.
per_rsgPer-RSG recall data.frame.
n_in_scopeNumber of pedons with both predicted and reference set.
n_totalTotal pedons benchmarked.
n_errorsNumber of pedons where the classifier errored out.
errorsList of (i, id, error) tuples for
classifier errors.
configRecap of arguments used.
load_lucas_soil_2018,
lookup_esdb,
lookup_soilgrids.
## Not run: pedons <- load_lucas_soil_2018( "soil_data/eu_lucas/LUCAS-SOIL-2018-data-report-readme-v2/LUCAS-SOIL-2018-v2", countries = c("ES"), max_n = 50) bench <- benchmark_lucas_2018( pedons, esdb_root = "soil_data/eu_lucas/ESDB-Raster-Library-1k-GeoTIFF-20240507", fill_texture_from = "soilgrids") bench$accuracy bench$per_rsg ## End(Not run)## Not run: pedons <- load_lucas_soil_2018( "soil_data/eu_lucas/LUCAS-SOIL-2018-data-report-readme-v2/LUCAS-SOIL-2018-v2", countries = c("ES"), max_n = 50) bench <- benchmark_lucas_2018( pedons, esdb_root = "soil_data/eu_lucas/ESDB-Raster-Library-1k-GeoTIFF-20240507", fill_texture_from = "soilgrids") bench$accuracy bench$per_rsg ## End(Not run)
Classifies NatSoil pedons with classify_asc3 and compares
the order with the one the surveyors gave (site$reference_asc_order).
A pedon is decided when no order before the assigned one was left
undecided for missing data; the agreement is given for all pedons and for
the decided ones. The surveys predate the 3rd edition's Arenosols (2021),
whose soils earlier editions placed in the Tenosols and Rudosols: the
edition figures count an Arenosol given to a surveyed Tenosol or
Rudosol as agreement.
benchmark_natsoil(pedons, cores = 1L, verbose = TRUE, family = FALSE)benchmark_natsoil(pedons, cores = 1L, verbose = TRUE, family = FALSE)
pedons |
A list of |
cores |
Number of processes ( |
verbose |
Print a summary. |
family |
Also derive the families ( |
A list: n; accuracy and accuracy_edition;
decided (count), decided_accuracy and
decided_accuracy_edition; by_confidence (a data frame by
the surveyors' confidence, 1 = all necessary analytical data); recall
by surveyed order; confusion (rows the survey, columns soilKey);
first_undecided (the first order left undecided, among
provisional pedons); suborders, the same for the suborders where
the key has them (overall, and over the pedons whose order agrees);
great_groups, the same for the great groups (overall, and over the
pedons whose order and suborder agree); subgroups, the same for
the subgroups (over the pedons whose order, suborder and great group
agree); families (with family = TRUE), each family
criterion against the surveyors' family codes (site$reference_asc_family),
over the pedons whose order (and, for the Hydrosols, suborder) agrees;
and results, one row per pedon.
load_natsoil_pedons, classify_asc3.
Classifies NPDB pedons (load_npdb_pedons) with
classify_cssc3 and compares the result with the survey's
classification at the level asked.
benchmark_npdb( pedons, level = c("order", "great_group", "subgroup"), set_aside = "Chernozemic", cores = 1L, verbose = TRUE )benchmark_npdb( pedons, level = c("order", "great_group", "subgroup"), set_aside = "Chernozemic", cores = 1L, verbose = TRUE )
pedons |
A list of |
level |
|
set_aside |
Reference orders reported apart ( |
cores |
Number of processes ( |
verbose |
Print a summary. |
The records hold no soil climate and no dry colour, which the key reads
for the Chernozemic order and its great groups (Ch 3, p. 34; Ch 5, p. 63)
and for the Gray Brown Luvisols; the orders named in set_aside
(by default the Chernozemic) are therefore reported apart, with where they
land, and left out of accuracy. A result is provisional when an
undecided class comes before the one assigned ($provisional_because
of classify_cssc3); accuracy_decided counts only the
results that are not provisional at the level asked or above.
Pedons from npdb_scenario carry estimates as ranges; each
is classified at its central estimate and at every combination of the
ends of its ranges (and of the moisture subclasses between its two
estimates), and a class counts as decided only where every
version gives it and none is provisional (otherwise the central class is
reported as provisional). Run such pedons with
set_aside = character(0) to include the Chernozems.
A list: level; accuracy (share of agreement outside
set_aside); accuracy_decided; n_compared;
n_decided; accuracy_all (all orders); set_aside (a
table of where those pedons land); confusion;
per_class_recall; predictions (one row per pedon;
scenario marks pedons classified at the ends of their ranges and
scenario_split those whose versions disagree).
Generates n synthetic pedons (5 horizons each, with the
chemistry / morphology populated for typical Argissolo /
Latossolo / Cambissolo cases), calls each classifier on each
pedon, and reports per-call latency + total throughput.
benchmark_performance( n = 100L, systems = c("wrb2022", "sibcs", "usda"), include_familia = FALSE, seed = 42L, verbose = TRUE )benchmark_performance( n = 100L, systems = c("wrb2022", "sibcs", "usda"), include_familia = FALSE, seed = 42L, verbose = TRUE )
n |
Integer. Number of synthetic pedons to generate. Default 100; pass 1000 or higher for batch-level measurements. |
systems |
Character vector. Which classifiers to time.
Default |
include_familia |
Pass-through to |
seed |
RNG seed for reproducibility. Default 42. |
verbose |
If |
Designed to be a one-shot reproducible benchmark: the synthetic pedons use a fixed RNG seed so timings on the same machine are comparable across releases.
A list with elements:
summarydata.frame: system, n_pedons,
total_seconds, mean_seconds, median_seconds,
pedons_per_minute.
per_pedondata.frame with one row per
(pedon, system) call: i, system,
seconds, status.
configlist with n, seed,
soilKey_version, R_version,
platform.
## Not run: bench <- benchmark_performance(n = 100) bench$summary #> system n_pedons total_seconds mean_seconds median_seconds pedons_per_minute #> 1 wrb2022 100 ~ 5-12 0.05-0.12 ~ ~ #> 2 sibcs 100 ~ 5-15 0.05-0.15 ~ ~ #> 3 usda 100 ~ 4-10 0.04-0.10 ~ ~ ## End(Not run)## Not run: bench <- benchmark_performance(n = 100) bench$summary #> system n_pedons total_seconds mean_seconds median_seconds pedons_per_minute #> 1 wrb2022 100 ~ 5-12 0.05-0.12 ~ ~ #> 2 sibcs 100 ~ 5-15 0.05-0.15 ~ ~ #> 3 usda 100 ~ 4-10 0.04-0.10 ~ ~ ## End(Not run)
Runs classify_sibcs on each pedon and compares against
the curator-validated reference label (Order / Suborder / Great
Group / Subgroup). Returns per-level accuracy and the confusion
matrix at the requested granularity.
benchmark_redape( pedons, level = c("order", "subordem", "gde_grupo", "subgrupo"), verbose = TRUE )benchmark_redape( pedons, level = c("order", "subordem", "gde_grupo", "subgrupo"), verbose = TRUE )
pedons |
List of |
level |
One of |
verbose |
Print progress (default |
A list with accuracy, n_compared,
confusion, per_class_recall, and the per-pedon
predictions table. predictions now also includes
columns ref_norm and pred_norm – the canonical
comparison keys – for downstream auditing.
Earlier versions accepted the level argument but always used
rsg_or_order for the prediction and the order field for the
reference, so all four levels reported identical accuracy. v0.9.81
reads the level-specific slots from res$trace (subordem,
grande_grupo, subgrupo) and concatenates the matching reference
fields, applying SiBCS-aware Portuguese pluralisation so the
comparison key matches the predictor's plural Title Case form.
Classifies each pedon in pedons against the named system,
compares against the published reference (e.g.
site$reference_wrb), and returns a confusion matrix +
top-1 / top-3 accuracy + bootstrap CI on top-1.
benchmark_run_classification( pedons, system = c("wrb2022", "sibcs", "usda"), level = c("order", "subgroup", "subordem", "great_group", "suborder"), boot_n = 1000L )benchmark_run_classification( pedons, system = c("wrb2022", "sibcs", "usda"), level = c("order", "subgroup", "subordem", "great_group", "suborder"), boot_n = 1000L )
pedons |
List of |
system |
One of |
level |
Granularity of the comparison:
|
boot_n |
Bootstrap replicates for CI (default 1000). |
A list with elements accuracy_top1,
accuracy_ci, confusion, and
per_pedon (one row per pedon with predicted vs
reference).
The honest measurement that has been data-blocked until a spectra-bearing,
labelled dataset exists. For each cross-validation fold it calibrates a
spectral library on the training profiles, then classifies the held-out
profiles twice – OFF (spectra-only pedon, no lab attributes) and
ON (fill_from_spectra predicts the lab attributes from
the scan first) – and scores both against the reference label. Non-circular:
the calibration library never includes a test profile.
benchmark_spectral_fill( reflectance, metadata, id_col = "id", system = c("sibcs", "wrb2022", "usda"), profile_col = NULL, folds = 5L, properties = NULL, method = c("mbl", "plsr_local", "pretrained"), wavelengths = NULL, resample_to = NULL, property_map = NULL, label_map = NULL, normalize = c("auto", "none", "percent"), fold_id = NULL, verbose = TRUE )benchmark_spectral_fill( reflectance, metadata, id_col = "id", system = c("sibcs", "wrb2022", "usda"), profile_col = NULL, folds = 5L, properties = NULL, method = c("mbl", "plsr_local", "pretrained"), wavelengths = NULL, resample_to = NULL, property_map = NULL, label_map = NULL, normalize = c("auto", "none", "percent"), fold_id = NULL, verbose = TRUE )
reflectance |
Reflectance data: a matrix / data.frame with rows =
samples and columns named by wavelength (nm); OR a long data.frame with
|
metadata |
A data.frame with one row per sample carrying |
id_col |
Sample identifier column shared by both tables (default
|
system |
One of |
profile_col |
Column grouping samples into profiles (default |
folds |
Number of CV folds (default 5). |
properties |
Attributes to predict from spectra (default the
|
method |
Spectral model: |
wavelengths |
Optional explicit wavelength vector (nm) when the reflectance columns are not wavelength-named. |
resample_to |
Optional target wavelength grid (nm) to linearly resample
every spectrum onto (e.g. |
property_map, label_map
|
Optional named lists overriding the alias
auto-detection, e.g. |
normalize |
One of |
fold_id |
Optional integer vector (one per profile, in sorted-id order) to use fixed folds instead of the deterministic modulo split. |
verbose |
Print a one-line summary (default |
A list with accuracy_off, accuracy_on, delta,
n, per-fold rows, and the per-profile predictions frame.
read_spectral_library, fill_from_spectra
Runs a system's soilKey classifier on every dataset that has reference labels for that system, then pools the results into a single nation-/world-wide accuracy estimate.
benchmark_unified( systems = c("all", "wrb2022", "sibcs", "usda"), datasets = c("all", "bdsolos", "febr", "kssl", "lucas_esdb"), paths = NULL, max_n_per_dataset = NULL, engine = c("soilkey", "aqp", "both"), harmonize = FALSE, gapfill = FALSE, verbose = TRUE )benchmark_unified( systems = c("all", "wrb2022", "sibcs", "usda"), datasets = c("all", "bdsolos", "febr", "kssl", "lucas_esdb"), paths = NULL, max_n_per_dataset = NULL, engine = c("soilkey", "aqp", "both"), harmonize = FALSE, gapfill = FALSE, verbose = TRUE )
systems |
Character vector. Any subset of |
datasets |
Character vector. Any subset of
|
paths |
Named list of dataset paths. Element names should
match those in |
max_n_per_dataset |
Optional integer to cap per-dataset
sample size (useful for development / debugging).
|
engine |
Currently forwarded to Phase-1 aqp wiring. One of
|
harmonize |
If |
gapfill |
If not |
verbose |
If |
A list with elements:
per_system – per-system pooled
list(accuracy, n_compared, n_correct, confusion,
per_class).
per_system_per_dataset – per-(system, dataset)
same shape, for breakdown.
coverage – per-(system, dataset) sample sizes
and label coverage.
config – captures systems, datasets,
engine, soilKey_version, timestamp.
| Dataset | Systems with reference labels |
| BDsolos | SiBCS (dense), WRB (sparse), USDA (sparse) |
| FEBR superconjunto | SiBCS, WRB, USDA (most rows have all 3) |
| KSSL+NASIS | USDA only (samp_taxsubgrp universal) |
| LUCAS + ESDB raster | WRB (via lookup_esdb on coords) |
For each (system, dataset) pair, this function:
Loads pedons via the appropriate load_* helper.
Filters to pedons with a populated reference label for the requested system.
Normalises both reference and predicted labels via
normalise_febr_*() / KSSL canonicalisation helpers.
Calls the system's classifier and records pred-vs-ref.
Then pools per-system results across datasets.
For datasets with morphological data (BDsolos / FEBR), the diagnostics that pivot Argissolos / Latossolos / Cambissolos classification can be run with two engines:
engine = "soilkey" (default) – the hand-coded WRB
6/1.4/20 thresholds.
engine = "aqp" – aqp::getArgillicBounds /
getCambicBounds (KST 13ed 3/1.2/8 thresholds).
On the v0.9.62 RJ benchmark (722 perfis), aqp was 14.8 pp stricter
on argic and 40.6 pp more permissive on cambic; the SiBCS
Argissolos / Latossolos / Cambissolos boundary is sensitive to
both. engine is currently forwarded to a future v0.9.63
wired argic() / cambic(); for now,
benchmark_unified() reports separately per engine when
engine = "both".
benchmark_bdsolos, benchmark_lucas_2018,
benchmark_run_classification,
harmonize_to_gsm.
Convenience wrapper: applies annotate_wrb_from_usda
to attach derived WRB labels, runs classify_wrb2022
on each pedon, and returns top-1 accuracy + per-RSG recall.
benchmark_wrb_vs_usda(pedons, verbose = TRUE)benchmark_wrb_vs_usda(pedons, verbose = TRUE)
pedons |
List of |
verbose |
Print progress. |
A list with accuracy, n_compared,
confusion, per_class_recall.
For each taxon (the first word of the reference label at the requested level),
averages each attribute across the calibration pedons into the six standard
depth slices (0-5 ... 100-200 cm). The result feeds
gapfill_by_predicted_taxon. Calibrate on a set DISJOINT from the
pedons you will fill (e.g. a train split) to keep the fill non-circular.
build_taxon_profiles(pedons, ref_field = "reference_sibcs", attrs = NULL)build_taxon_profiles(pedons, ref_field = "reference_sibcs", attrs = NULL)
pedons |
A list of |
ref_field |
Site field holding the reference label (default
|
attrs |
Attributes to profile (default the continuous gap-fill set). |
A named list taxon -> attr -> numeric(6) (NA where a taxon has
no measured value in a slice).
Calcaric material (WRB 2022 Ch 3.3.3): \>= 2% CaCO3 throughout the fine earth, primary carbonates from the parent material.
calcaric_material(pedon, min_caco3_pct = 2)calcaric_material(pedon, min_caco3_pct = 2)
pedon |
A |
min_caco3_pct |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Tests whether any horizon meets the calcic horizon criteria. The calcic horizon is a horizon of secondary carbonate accumulation, diagnostic for Calcisols and qualifying many other RSGs.
calcic(pedon, min_thickness = 15, min_caco3_pct = 15)calcic(pedon, min_thickness = 15, min_caco3_pct = 15)
pedon |
A |
min_thickness |
Minimum thickness in cm (default 15). |
min_caco3_pct |
Minimum CaCO3 percent in fine earth (default 15). |
Sub-tests called:
test_caco3_concentration – CaCO3 >= 15%.
test_minimum_thickness – thickness >= 15 cm.
v0.2 limitations: the WRB criterion of "5% absolute or relative more CaCO3 than the underlying horizon" is not enforced; this captures true calcic horizons but may also mark uniformly carbonate-rich substrates that are not pedologically calcic. Cementation (petrocalcic) is not yet detected. Both refinements are scheduled for v0.3.
The WRB calcic horizon follows WRB 2022 Ch 3.1.4 (p. 37-38) criterion by
criterion: criterion 2 is protocalcic properties (secondary carbonates on
5% of the exposed area, secondary_carbonates_pct) or
5% more CaCO3 than an underlying layer with no lithic
discontinuity between; a layer of a petrocalcic horizon is not calcic; the
15 cm are those of the adjoining layers. A layer whose criterion 2 cannot be
decided (secondary carbonates not recorded) is undecided, not calcic. The
USDA calcic horizon and the SiBCS horizonte calcico keep the earlier
reading.
IUSS Working Group WRB (2022). World Reference Base for Soil Resources, 4th edition. International Union of Soil Sciences, Vienna. Chapter 3 – Calcic horizon.
Tests whether any horizon meets the cambic horizon criteria. The cambic horizon is a subsurface horizon with evidence of pedological alteration that does not meet the criteria for any stronger diagnostic horizon. It is the diagnostic of Cambisols.
cambic(pedon, min_thickness = 15, min_top_cm = 5, engine = NULL)cambic(pedon, min_thickness = 15, min_top_cm = 5, engine = NULL)
pedon |
A |
min_thickness |
Minimum thickness in cm (default 15). |
min_top_cm |
Minimum top depth (cm) for a horizon to be considered cambic-eligible (default 5). Anchors the candidate set to subsurface layers. Since v0.9.314 the WRB reading asks it only when it is given. |
engine |
v0.9.63+. One of |
v0.2 implementation tests three conditions:
thickness >= 15 cm (test_minimum_thickness)
texture sandy loam or finer (test_texture_argic)
v0.2 limitations: WRB 2022 also excludes profiles with spodic, calcic, gypsic, plinthic, vertic, and several other diagnostic horizons. Those exclusions, plus the WRB criteria of "evidence of alteration" (color/structure differences from parent material, carbonate removal), are scheduled for v0.3.
The WRB cambic horizon follows WRB 2022 Ch 3.1.5 (p. 39-40): criterion 4 is read layer by layer, so a layer that forms part of an argic, ferralic, calcic, mollic or other listed horizon (or of a layer with andic properties) is set aside, not the whole profile; the subsurface layers are those below the layer at the mineral soil surface that are not A horizons; the 15 cm are those of the adjoining layers; a layer whose texture or structure is not recorded leaves the result undecided. Criterion 3 is not tested. The USDA keys keep the earlier reading.
IUSS Working Group WRB (2022), Chapter 3, Cambic horizon.
Wraps aqp::getCambicBounds() in soilKey's
DiagnosticResult contract. The aqp test enforces the
KST 13ed cambic criteria:
Texture finer than loamy fine sand (i.e. NOT in the sandy-texture pattern).
Soil structure or absence of rock structure.
Evidence of pedogenic alteration (chroma / value / clay).
NOT meeting argic / oxic / spodic / mollic criteria.
soilKey's cambic (and the SiBCS proxy
B_incipiente) implements similar logic but with
SiBCS / WRB-flavoured exclusions; the aqp engine here is an
independent canonical reference.
cambic_aqp(pedon, argi_bounds = NULL, ...)cambic_aqp(pedon, argi_bounds = NULL, ...)
pedon |
A |
argi_bounds |
Optional |
... |
Reserved for future arguments. |
A DiagnosticResult with name =
"cambic_aqp".
cambic (soilKey hand-coded),
aqp::getCambicBounds.
Reads one of the parsed WRB 2022 / Keys to Soil Taxonomy datasets from the installed SoilTaxonomy package (NCSS-tech, GPL-3). soilKey ships no copy of these data: install SoilTaxonomy from CRAN to use this function.
canonical_reference( name = c("WRB_4th_2022", "ST_criteria_13th", "ST_features"), prefer_pkg = TRUE )canonical_reference( name = c("WRB_4th_2022", "ST_criteria_13th", "ST_features"), prefer_pkg = TRUE )
name |
One of |
prefer_pkg |
Retained for compatibility and no longer used. Until
v0.9.203 |
The dataset as the original R object (list or data.frame).
wrb2022_canonical, kst13_canonical,
st_features_canonical.
Maps both obsolete (pre-KST 13ed) and modern Great Group names to a single canonical key, so that direct equality between predicted and reference Great Group names ignores edition-driven renaming. Names that have no known mapping pass through unchanged.
canonicalise_kst13ed_gg(gg)canonicalise_kst13ed_gg(gg)
gg |
Character vector of Great Group names (lower case, no whitespace). |
Examples of the canonicalisation (each pair is rendered equivalent):
"haplaquolls" (KST 8) === "endoaquolls" (KST 13ed)
"pellusterts" (KST 8) === "hapluderts" (KST 13ed)
"camborthids" (KST 8) === "haplocambids" (KST 13ed)
"vitrandepts" (KST 8) === "vitrudands" (KST 13ed)
Character vector of canonical keys. Unmapped names pass through. NA stays NA. Empty input returns empty vector.
Soil Survey Staff (2022), Keys to Soil Taxonomy 13ed, Ch 4 (Order keys); previous editions for the obsolete names.
Diagnostico parametrizado quantidade x intensidade de cerosidade
(clay films / cutans). Consume as colunas v0.7.2
clay_films_amount (ordinal: few/pouca, common/comum,
many/abundante, continuous/continua) e clay_films_strength
(ordinal: weak/fraca, moderate/moderada, strong/forte; "shiny"
mapeado a "strong"), introduzidas em substituicao ao legado
clay_films.
cerosidade(pedon, min_amount = "common", min_strength = "moderate")cerosidade(pedon, min_amount = "common", min_strength = "moderate")
pedon |
A |
min_amount |
Quantidade minima: |
min_strength |
Intensidade minima: |
Discriminante critico Nitossolos vs Argissolos no Cap 13:
Nitossolos exigem cerosidade comum + moderada
(defaults).
DiagnosticResult; passed = TRUE se ao
menos um horizonte B atende ambos os limiares.
Embrapa (2018), SiBCS 5a ed., Cap 13 (Nitossolos), p 207; Cap 1 (atributos diagnosticos).
A thick, well-structured, very dark surface horizon with a high base saturation (WRB 2022 3.1.6, pp. 40-41). Every layer of the horizon, from the mineral soil surface down, must have: (1) \>= 50% fine earth and no mulmic material; (2) granular structure, subangular blocky structure of average size \<= 2 cm (very fine, fine or medium), or cloddy / agricultural structure; (3) \>= 1% SOC; (4) moist value \<= 3, dry value \<= 5 and moist chroma \<= 2, or the carbonate-rich (15-40% CaCO3, \>= 1.5% SOC) or the \>= 40% CaCO3 / loamy-sand (value \<= 5, \>= 2.5% SOC) alternatives; (5) \>= 1% more SOC than a parent-material layer of moist value \<= 4, where one is recorded; (6) BS \>= 50%. The layers together must be (7) \>= 30 cm thick. Worm holes belong to the Vermic qualifier, not to this horizon.
chernic(pedon, min_thickness = 30)chernic(pedon, min_thickness = 30)
pedon |
A |
min_thickness |
Minimum thickness in cm (default 30). |
A missing dry value is taken as the moist value plus one, as in the mollic colour test. A missing BS is read from pH (Annex 2, Table 9.2).
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Tests whether a profile satisfies the Chernozem RSG criteria: a mollic horizon plus secondary carbonates somewhere in the profile, plus chroma (moist) <= 2 in at least one layer of the upper 20 cm.
chernozem(pedon, max_chroma_upper = 2)chernozem(pedon, max_chroma_upper = 2)
pedon |
A |
max_chroma_upper |
Maximum moist chroma in the upper part (default 2, per WRB 2022). |
IUSS Working Group WRB (2022), Chapter 5, Chernozems.
WRB-canonical: chernic horizon AND, starting \<= 50 cm below the
lower limit of the mollic horizon and (if a petrocalcic horizon is
present) above it, a layer with protocalcic properties \>= 5 cm thick
OR a calcic horizon AND base saturation \>= 50% from the mineral
soil surface to the protocalcic / calcic layer throughout. Protocalcic
properties are visible secondary carbonates
(protocalcic_properties); where BS is not recorded it is
read from pH (WRB 2022 Annex 2, Table 9.2).
chernozem_strict(pedon, min_bs = 50, max_top_cm = 50, strict = NULL)chernozem_strict(pedon, min_bs = 50, max_top_cm = 50, strict = NULL)
pedon |
A |
min_bs |
Minimum base saturation % above the carbonate layer (default 50). |
max_top_cm |
Maximum depth of the carbonate layer below the lower limit of the mollic horizon, cm (default 50). |
strict |
Logical or |
v0.3.4 strengthens the previous v0.2 chernozem (which only required mollic + chernic_color) by adding the protocalcic / calcic gate and the BS \>= 50% requirement.
Note: the v0.2 chernozem() diagnostic remains available as a
less-strict variant; chernozem_strict() is what the v0.3.4
key.yaml uses for the CH RSG.
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
With strict = TRUE the base-saturation floor above the
carbonate-bearing layer is raised from 50% to 80%, in line with
the very high base status expected of a textbook Chernozem.
Claric material (WRB 2022 Ch 3.3.4): light-coloured fine earth with Munsell criteria.
claric_material(pedon)claric_material(pedon)
pedon |
A |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
For a given PedonRecord, perturb a chosen list of
horizon attributes by a configured fractional amount, re-classify
under the requested system, and report how often the classification
$rsg_or_order (or full $name) matches the unperturbed
baseline.
classification_robustness( pedon, system = c("wrb2022", "sibcs", "usda"), level = c("order", "name"), n = 50L, perturbations = NULL, provenance_aware = FALSE, seed = 42L )classification_robustness( pedon, system = c("wrb2022", "sibcs", "usda"), level = c("order", "name"), n = 50L, perturbations = NULL, provenance_aware = FALSE, seed = 42L )
pedon |
A |
system |
One of |
level |
Either |
n |
Number of Monte-Carlo perturbed runs (default 50). |
perturbations |
Named list. Each name is a horizon column;
each element is a function taking the original value and
returning a perturbed value. NA-tolerant. Ignored when
|
provenance_aware |
If |
seed |
Random seed for reproducibility. |
Default perturbation panel:
clay_pct: ±5
sand_pct: ±5
silt_pct: ±5
ph_h2o: ±0.2 absolute
oc_pct: ±10
A list with elements baseline (the unperturbed
classification name), n (number of MC runs),
robustness (fraction of perturbed runs matching
baseline), flipped_to (table of alternative
classifications when the perturbation flipped the result).
## Not run: p <- make_ferralsol_canonical() classification_robustness(p, system = "wrb2022", n = 50) #> $baseline : "Ferralsols" #> $robustness : 0.96 (48 / 50 perturbed runs landed on Ferralsols) #> $flipped_to : table(c("Cambisols" = 1, "Acrisols" = 1)) ## End(Not run)## Not run: p <- make_ferralsol_canonical() classification_robustness(p, system = "wrb2022", n = 50) #> $baseline : "Ferralsols" #> $robustness : 0.96 (48 / 50 perturbed runs landed on Ferralsols) #> $flipped_to : table(c("Cambisols" = 1, "Acrisols" = 1)) ## End(Not run)
ClassificationResult: structured outcome of running a key
ClassificationResult: structured outcome of running a key
Returned by classify_wrb2022 (and the future
classify_sibcs). Carries the full decision trace — which RSGs
were tested, which passed, which failed, which were indeterminate
because of missing data — plus the assigned class, qualifiers,
ambiguities (RSGs that nearly satisfied), missing data that would
refine the result, the provenance-aware evidence grade, and any
biogeographical or prior-based warnings.
systemCharacter. "WRB 2022" or "SiBCS 5".
nameCharacter. Full classification name with
qualifiers (e.g.
"Rhodic Ferralsol (Clayic, Dystric, Humic)").
rsg_or_orderCharacter. Bare RSG (WRB) or order (SiBCS), e.g.
"Ferralsols".
qualifiersList. Principal and supplementary qualifiers in canonical order.
traceList. One element per RSG tested (in key order),
each with code, name, passed,
evidence, missing.
ambiguitiesList. RSGs that came close to passing — useful hints for follow-up measurements.
missing_dataCharacter vector. Attributes whose measurement would refine or resolve the result.
evidence_gradeCharacter. "A" (measured), "B"
(spectra-predicted), "C" (prior-inferred),
"D" (VLM-extracted), "E"
(user-assumed), or NA_character_ when no
horizon carries a soil property (only depths and
designations; since v0.9.213), so nothing in the
class was verified.
prior_checkList or NULL. Result of the spatial-prior sanity check (consistent / inconsistent / not run).
warningsCharacter vector. Free-form warnings.
system_idCharacter. Registry id of the system (see
soilkey_systems), e.g.
"wrb2022"; since v0.9.265.
levelsdata.frame with one row per level of the
key that assigned a class (level,
code, name), top level first; set by
the generic classifier of ordered keys and
NULL for WRB, SiBCS and USDA, whose levels
are in trace.
provisional_becauseCharacter vector. In a first-match key a class
that could not be decided for lack of data, tested
before the one assigned, makes the assignment
provisional; these are those classes, as
"<level>:<code>". Empty when the assignment
is firm or the classifier does not report it.
new()
Build a ClassificationResult.
ClassificationResult$new( system, name, rsg_or_order = NA_character_, qualifiers = list(), trace = list(), ambiguities = list(), missing_data = character(0), evidence_grade = NA_character_, prior_check = NULL, warnings = character(0), system_id = NULL, levels = NULL, provisional_because = character(0) )
systemSystem name.
nameClassification name.
rsg_or_orderRSG (WRB) or order (SiBCS).
qualifiersList of qualifier names.
traceList of per-RSG test entries.
ambiguitiesList of close-call RSGs.
missing_dataCharacter vector.
evidence_gradeSingle character A/B/C/D or NA.
prior_checkList or NULL.
warningsCharacter vector.
system_idRegistry id of the system, or NULL.
levelsAssigned class per level (data.frame), or NULL.
provisional_becauseCharacter vector of undecided classes tested before the assigned ones.
print()
Pretty-print the result with key trace, ambiguities, and warnings.
ClassificationResult$print(...)
...Ignored (S3 print signature compatibility).
summary()
Compact summary list.
ClassificationResult$summary(...)
...Ignored (S3 summary signature compatibility).
report()
Render this classification as a self-contained
report (delegates to the package-level
report generic). HTML output is
dependency-free; PDF requires rmarkdown
and a working LaTeX engine.
ClassificationResult$report(
file,
format = c("auto", "html", "pdf"),
pedon = NULL,
...
)fileOutput path. Format is inferred from the extension.
formatOne of "html" or "pdf" (defaults to "auto", which infers from the extension).
pedonOptional PedonRecord whose horizons /
provenance are added to the report.
...Forwarded to report_html or
report_pdf.
clone()
The objects of this class are cloneable with this method.
ClassificationResult$clone(deep = FALSE)
deepWhether to make a deep clone.
Convenience wrapper that runs classify_wrb2022,
classify_sibcs, and classify_usda on the same
PedonRecord and returns a single named list with one entry
per system (plus a summary table that's handy for reports).
classify_all( pedon, systems = "all", on_missing = c("warn", "silent", "error"), include_familia = TRUE, include_family = FALSE, specifiers = FALSE, gapfill = FALSE, ... )classify_all( pedon, systems = "all", on_missing = c("warn", "silent", "error"), include_familia = TRUE, include_family = FALSE, specifiers = FALSE, gapfill = FALSE, ... )
pedon |
A |
systems |
Character vector. Any subset of the registered systems
( |
on_missing |
One of |
include_familia |
Forwarded to |
include_family |
Forwarded to |
specifiers |
Forwarded to |
gapfill |
Forwarded to all three classifiers (default |
... |
Additional named arguments are silently ignored. |
Each classifier still produces its own ClassificationResult
with the full key trace and evidence grade – nothing is collapsed or
homogenised. The wrapper exists for ergonomics, not abstraction.
A named list with elements:
wrb – ClassificationResult from
classify_wrb2022() (or NULL if the system was
skipped or errored).
sibcs – as above, from classify_sibcs().
usda – as above, from classify_usda().
summary – a 1-row data.frame with one column
per system, holding the resulting $name (or NA
when the system was skipped / errored). Useful for tabulating
many pedons in one shot.
Pass systems = c("wrb2022", "sibcs") (or any other subset) to skip
systems you don't need. Default systems = "all" runs all three.
The systems and their aliases come from soilkey_systems.
If a single classifier raises an error, the corresponding slot of the
returned list is set to NULL and a one-line warning is emitted (so
you can rerun the offender on its own to see the full traceback). The
other classifiers still run and their results are returned. This matches
the spirit of on_missing = "warn" on the individual classifiers.
None. The classifiers do not mutate pedon; the wrapper does not
attach any side-channel state.
classify_wrb2022, classify_sibcs,
classify_usda.
pr <- make_ferralsol_canonical() all_three <- classify_all(pr) all_three$summary # WRB + USDA only (skip SiBCS): classify_all(pr, systems = c("wrb2022", "usda"))$summarypr <- make_ferralsol_canonical() all_three <- classify_all(pr) all_three$summary # WRB + USDA only (skip SiBCS): classify_all(pr, systems = c("wrb2022", "usda"))$summary
Keys a PedonRecord through the Australian Soil
Classification, 3rd edition (Isbell and the National Committee on Soil
and Terrain 2021), following the online version with its errata.
Experimental: this release keys the 15 orders (the key to soil
orders) and the suborders of all of them: the Kurosols, Sodosols,
Chromosols, Ferrosols, Dermosols, Kandosols and Vertosols (colour classes,
and the Aquic Vertosols), the Organosols (the dominant kind of peat), the
Podosols (saturation of the B, sulfuric and hypersulfidic material), the
Hydrosols (the setting, then mottling), the Calcarosols (gypsum and the
carbonate classes), the Anthroposols (the kind of human-made material),
the Arenosols and Tenosols (chernic horizons, bleaching, hard materials
within 0.5 m, carbonate, nodules, then colour) and the Rudosols (salinity,
gypsum, shells, carbic materials, hard materials, sand, gravel, layers),
and the great groups of the Kurosols, Sodosols, Chromosols, Ferrosols,
Dermosols and Kandosols (pans in or under the B, structure, plasticity,
base status, exchangeable Ca/Mg, ESP and carbonate of the B2 or B2t), the
Vertosols (the surface), Calcarosols (what the soil directly overlies,
and the B), Podosols (the kinds of Podosol B), Organosols (drainage,
acid sulfate materials, carbonate and acidity), Hydrosols (acid sulfate
materials, the upper 0.5 m, and the order the soil would key to apart
from wetness), Arenosols, Rudosols and Tenosols (what the soil directly
overlies, nodular, gypsic and argic horizons, carbonate, texture, gravel);
the Anthroposols have none in the text; and the subgroups of the
Kurosols, Sodosols and Chromosols (chernic and vertic features, bleaching,
ferric and manganic horizons, sodicity of the lower B, mottling of the
B2t, base status, carbonate) and of the Dermosols, Kandosols and
Ferrosols (the same features read on the B2, a strongly acid B2, argic and
bauxitic horizons in the B, a snuffy A), of the Vertosols and Calcarosols
(acid sulfate materials, pans, sodicity, acidity, carbonate and mottling
of the upper 0.5 m of the solum and below it, subplasticity, surface
carbonate), the Podosols (coherence of the B, pans), the Organosols
(what the organic materials overlie), and the Hydrosols, Arenosols,
Rudosols and Tenosols (peat kinds, sulfidic materials near the surface,
acidity and carbonate of the upper 1.0 m, the B, the A2, the solum or
the soil, horizons with all but the thickness; the Rudosolic and
Tenosolic great groups of the Redoxic and Oxyaquic Hydrosols take the
list of the Rudosol or Tenosol suborder the soil keys to apart from
wetness). The name is that of the deepest class assigned, in the book's
form "Subgroup, Great Group, Suborder Order" ("Bleached, Eutrophic, Red
Chromosol"); rsg_or_order keeps the order. With
include_family = TRUE the family follows the name as the book
writes it ("Bleached, Eutrophic, Red Chromosol; thick, non-gravelly,
loamy/clayey, deep"): see classify_asc3_family.
classify_asc3( pedon, rules = NULL, on_missing = c("warn", "silent", "error"), gapfill = FALSE, include_family = FALSE )classify_asc3( pedon, rules = NULL, on_missing = c("warn", "silent", "error"), gapfill = FALSE, include_family = FALSE )
pedon |
A |
rules |
Optional pre-loaded rule set ( |
on_missing |
One of |
gapfill |
Opt-in within-pedon gap-fill, as in
|
include_family |
Derive the family ( |
The ASC is largely morphological. The diagnostics read field texture
grades (field_texture, NCST Field Handbook codes; lab clay stands in
and is undecided near the limits), the Australian horizon notation (A1,
A2, B21t, Bhs, Bk ...; FAO/USDA designations are read by the role of each
horizon), the boundary between the A and the B, pH (strongly acid: pHw
below 5.5), ESP (sodic: 6 or more), subplasticity, free iron, grade of
pedality, carbonates and the moisture of the horizons when described
(soil_water_status: the Vertosols' cracks are not required in a
solum described moist), mottles, soft and hard carbonate, gypsum, the kind
of peat, acid sulfate tests, EC of a 1:5 extract, dry and moist strength,
ped size, nodules, pans and exchangeable bases. From the site it reads
drainage_class (Hydrosols, organic materials, Podosol suborders),
tidal_inundation (Hydrosols, organic materials),
surface_condition (a cracking
surface, Vertosols; a saline one, Salic Hydrosols), landform,
landform_element, tidal_zone, subaqueous and
salinised (Hydrosol suborders) and designation_system
("asc" for the Australian notation). The
choices where the text is silent are listed in
system.file("rules", "asc3", "readings.yaml", package = "soilKey").
A ClassificationResult with system_id
"asc3", the deepest class in name, the order in
rsg_or_order, the classes of each level in levels, the key
trace, and provisional_because (classes before the assigned ones
that could not be decided); with include_family, the family
criteria in trace$family, their names in
trace$family_label and their codes in trace$family_code.
Isbell, R.F. and the National Committee on Soil and Terrain (2021). The Australian Soil Classification, 3rd ed. CSIRO Publishing, Melbourne. Online version: www.soilscienceaustralia.org.au/asc.
make_asc3_example, classify_asc3_family,
soilkey_systems.
res <- classify_asc3(make_asc3_example("chromosols"), on_missing = "silent") res$name classify_asc3(make_asc3_example("chromosols"), on_missing = "silent", include_family = TRUE)$nameres <- classify_asc3(make_asc3_example("chromosols"), on_missing = "silent") res$name classify_asc3(make_asc3_example("chromosols"), on_missing = "silent", include_family = TRUE)$name
Places a soil in the family classes of its order (Australian Soil
Classification, 3rd edition, the 'Family Criteria' of each order page).
The family is not a level of the key: each criterion is a class of its
own, given by a one- or two-letter code. Most orders use the thickness of
the A1 horizon (of the whole A horizon in the Kurosols, Sodosols and
Chromosols and in the Kurosolic, Sodosolic and Chromosolic Hydrosols, as
the book's general rule has it), with any organic horizon over it; gravel
(2-60 mm) of the surface and A1 horizon (the larger of the estimate of the
ground surface, site$surface_gravel_pct or
site$surface_coarse_fragments_pct, and that of the A1); the field
texture of the A1 (its major part, peaty under organic surface horizons)
and the most clayey field texture of the B; soil depth; and water
repellence of the surface soil (water_repellence). The Vertosols
use laboratory clay (upper 0.1 m and the B), the Calcarosols the depth of
the first Bk horizon, the Arenosols and Rudosols the surface soil, and the
Organosols the kind and thickness of their organic materials and the
texture under them. Soil depth is the depth to rock, a cemented pan (not a
thin ironpan), another cemented layer or saprolite; otherwise, in a soil
with a B horizon, the depth to the C below it, and in a soil without one,
the depth described. The Anthroposols have no family, nor do the
Subtidal, Subaqueous and Intertidal Hydrosols. The readings where the
text is silent are in system.file("rules", "asc3", "readings.yaml",
package = "soilKey") (topic "Families").
classify_asc3_family(pedon, order = NULL, suborder = NULL, great_group = NULL)classify_asc3_family(pedon, order = NULL, suborder = NULL, great_group = NULL)
pedon |
A |
order, suborder, great_group
|
Codes of the soil's classes (as in
|
A named list of FamilyAttribute, one per criterion
of the order that applies, in the order of the book's family name:
value is the class name (NULL when undecided or when no
class fits), evidence$code the class code ("YY" undecided,
"ZZ" no class of the order fits). An empty list when the soil has
no family.
Isbell, R.F. and the National Committee on Soil and Terrain (2021). The Australian Soil Classification, 3rd ed. CSIRO Publishing, Melbourne. Online version: www.soilscienceaustralia.org.au/asc.
fam <- classify_asc3_family(make_asc3_example("chromosols")) vapply(fam, function(a) a$evidence$code, "")fam <- classify_asc3_family(make_asc3_example("chromosols")) vapply(fam, function(a) a$evidence$code, "")
Given a Vis-NIR (or MIR) spectrum and an OSSL reference library enriched with WRB / SiBCS / USDA labels, returns the K most spectrally similar profiles plus a probabilistic class prediction aggregated from their labels.
classify_by_spectral_neighbours( spectrum, ossl_library, system = c("wrb2022", "sibcs", "usda"), k = 25L, preprocess = "snv+sg1", region = NULL, verbose = TRUE )classify_by_spectral_neighbours( spectrum, ossl_library, system = c("wrb2022", "sibcs", "usda"), k = 25L, preprocess = "snv+sg1", region = NULL, verbose = TRUE )
spectrum |
Numeric vector or 1-row matrix (the query
spectrum). Must align (after preprocessing) with the
column space of |
ossl_library |
A list with |
system |
One of |
k |
Number of nearest neighbours (default 25). |
preprocess |
Pre-processing pipeline; passed to
|
region |
Optional |
verbose |
Emit a |
This is the **spectral analogy** classifier. It does not replace
the deterministic key in
classify_wrb2022 / classify_sibcs /
classify_usda; instead it provides a high-prior
"expected class" before the user has lab data, reducing the
search space when collecting confirming attributes.
A list with three elements:
distributionA data.table with columns
class, n_neighbours, probability
(= n_neighbours / k), sorted by probability.
neighboursA data.table with one row per
neighbour (top K), columns rank, distance,
class, plus any other columns present in
ossl_library$Yr.
queryThe query metadata (system, k, region filter, n_library_rows, n_filtered).
By default we compute distances on PLS scores (matching the
resemble / OSSL recipe), with PLS components fit on the OSSL
reference Yr matrix. When resemble is unavailable, we fall
back to PCA scores from stats::prcomp on the preprocessed
Xr – a defensible-but-simpler heuristic.
Optional lat / lon / radius_km arguments filter the OSSL
library to profiles within radius_km (great-circle) of the
query location before computing distances. This implements the
"biome-aware" use case the architecture document calls for: a
Cerrado profile shouldn't have its class inferred from spectral
neighbours in the Boreal taiga.
predict_ossl_mbl (predicts attributes),
classify_wrb2022 (the deterministic key).
## Not run: # Toy run against the bundled demo library (synthetic): data(ossl_demo_sa) # Inject a fake label column for the demo (real OSSL has it): ossl_demo_sa$Yr$wrb_rsg <- sample(c("FR", "AC", "LX", "AL"), nrow(ossl_demo_sa$Yr), replace = TRUE) query <- ossl_demo_sa$Xr[1, ] res <- classify_by_spectral_neighbours(query, ossl_demo_sa, k = 10) res$distribution # ranked classes res$neighbours # the 10 most similar profiles ## End(Not run)## Not run: # Toy run against the bundled demo library (synthetic): data(ossl_demo_sa) # Inject a fake label column for the demo (real OSSL has it): ossl_demo_sa$Yr$wrb_rsg <- sample(c("FR", "AC", "LX", "AL"), nrow(ossl_demo_sa$Yr), replace = TRUE) query <- ossl_demo_sa$Xr[1, ] res <- classify_by_spectral_neighbours(query, ossl_demo_sa, k = 10) res$distribution # ranked classes res$neighbours # the 10 most similar profiles ## End(Not run)
Keys a PedonRecord through the Canadian System of Soil
Classification, 3rd edition (Soil Classification Working Group 1998).
Experimental: this release keys the ten orders (Key to Soil
Orders, Ch 3, pp. 33-34), their 31 great groups (Key to Soil Great Groups,
pp. 35-36) and their 231 subgroups (Key to Soil Subgroups, pp. 37-51).
The name is the deepest class assigned: the subgroup (e.g. "Terric
Mesisol"), or the great group (e.g. "Solonetz") when no subgroup can be
given: the Solonetzic subgroups are named by the colour of the A, and the
key has no other subgroup for a Solonetzic soil without an A (one eroded
down to its solonetzic B); the order is in rsg_or_order and every
level in levels.
classify_cssc3( pedon, rules = NULL, on_missing = c("warn", "silent", "error"), gapfill = FALSE )classify_cssc3( pedon, rules = NULL, on_missing = c("warn", "silent", "error"), gapfill = FALSE )
pedon |
A |
rules |
Optional pre-loaded rule set ( |
on_missing |
One of |
gapfill |
Opt-in within-pedon gap-fill, as in
|
The Canadian keys are written largely in terms of horizon designations,
which the book defines partly by measurable properties. Each diagnostic
reads the measured properties first (podzolic B chemistry with
pyrophosphate-extractable Fe and Al, the Bt clay increase, the solonetzic
B Ca/Na ratio, the chernozemic A, the gley colours) and the surveyor's
designations in the Canadian notation second (Bt, Bf, Bm, Btj, Bn, Bv,
Bss, Bg, Cz...). When the assigned order rests on designations alone, a
warning says so. The choices where the book is silent are listed in
system.file("rules", "cssc3", "readings.yaml", package = "soilKey").
The chernozemic A horizon includes a soil-climate criterion (mean annual
soil temperature at least 0 C, moisture subclass drier than humid), read
from site$mean_annual_soil_temp_C and
site$soil_moisture_subclass, or approximated from the USDA regimes.
Without it the Chernozemic order is undecided and any order keyed after it
is reported as provisional ($provisional_because). The Gray and
Dark Gray subgroups of the Solods and Solodized Solonetz also ask for a
subhumid climate (site$soil_moisture_subclass).
A ClassificationResult with system_id
"cssc3", the deepest class assigned in name, the order in
rsg_or_order, every level in levels, the key trace, and
provisional_because.
Soil Classification Working Group (1998). The Canadian System of Soil Classification, 3rd ed. Agriculture and Agri-Food Canada Publication 1646. NRC Research Press, Ottawa.
make_cssc3_example, soilkey_systems.
res <- classify_cssc3(make_cssc3_example("podzolic"), on_missing = "silent") res$nameres <- classify_cssc3(make_cssc3_example("podzolic"), on_missing = "silent") res$name
The shortest path from a spreadsheet to an answer. Reads file with
read_pedon_csv and returns the WRB 2022 / SiBCS / USDA names as
a one-row data.frame. Missing attributes are handled silently
(on_missing = "silent").
classify_csv( file, site = NULL, sep = "auto", systems = c("wrb", "sibcs", "usda") )classify_csv( file, site = NULL, sep = "auto", systems = c("wrb", "sibcs", "usda") )
file |
Path to a |
site |
Optional named list of site metadata (see |
sep |
Field separator. |
systems |
Character vector of systems to run; any of |
The full ClassificationResult objects (with the key trace,
evidence grade, qualifiers, ...) and the parsed PedonRecord are
attached as attributes "results" and "pedon" for anyone who
wants to dig deeper.
A one-row data.frame with one column per system.
f <- system.file("extdata", "perfil_exemplo.csv", package = "soilKey") classify_csv(f)f <- system.file("extdata", "perfil_exemplo.csv", package = "soilKey") classify_csv(f)
Highest-level entry point of the soilKey VLM pipeline. Given a soil-description PDF and / or a profile-wall photograph, this function:
classify_from_documents( pdf = NULL, image = NULL, fieldsheet = NULL, pedon = NULL, provider = "auto", model = NULL, systems = c("wrb", "sibcs", "usda"), report = NULL, overwrite = FALSE, verbose = TRUE )classify_from_documents( pdf = NULL, image = NULL, fieldsheet = NULL, pedon = NULL, provider = "auto", model = NULL, systems = c("wrb", "sibcs", "usda"), report = NULL, overwrite = FALSE, verbose = TRUE )
pdf |
Optional path to a soil-description PDF. |
image |
Optional path to a profile-wall image (JPG / PNG); if supplied, Munsell extraction is attempted with the configured provider. |
fieldsheet |
Optional path to a site-metadata field sheet (image or PDF). |
pedon |
Optional existing |
provider |
Either a provider name passed to
|
model |
Optional model identifier; passed through to
|
systems |
Character vector listing which classification
systems to run; subset of
|
report |
Optional output path for a self-contained
report ( |
overwrite |
When merging extracted values into an existing
pedon, allow VLM-extracted attributes to clobber
already-recorded ones. Default |
verbose |
Emit cli progress messages. Default
|
Constructs a vision-language provider chat object via
vlm_provider (defaults to local Ollama with
Gemma 4 edge for institutional independence and data
sovereignty).
Extracts horizons from pdf via
extract_horizons_from_pdf, Munsell colours
from image via
extract_munsell_from_photo, and site
metadata from fieldsheet via
extract_site_from_fieldsheet. Every
extracted attribute is stamped source =
"extracted_vlm" in the PedonRecord's provenance log.
Runs the three deterministic keys
(classify_wrb2022,
classify_sibcs,
classify_usda). The VLM never classifies –
the package's architectural invariant is preserved.
Optionally renders a one-pager HTML / PDF report via
report.
At least one of pdf, image or fieldsheet
must be supplied; you can also pass an existing partially-filled
PedonRecord via pedon and let this function fill
the gaps.
A list with elements:
pedonThe (mutated) PedonRecord.
classificationsNamed list with up to three
ClassificationResult objects keyed by
wrb, sibcs, usda.
reportPath to the rendered report file (if
report = ... was supplied), else NULL.
providerThe chat-provider object actually used (useful for downstream debugging or cost accounting).
The default provider = "ollama" runs the entire VLM pipeline
on the user's machine via Gemma 4 (edge variant, ~3 GB, multimodal
text+image). No part of the soil description, photograph or
field sheet ever leaves the local network. This is the
recommended configuration for governmental surveys, indigenous
land studies, and unpublished research data; it also makes the
pipeline reproducible without an internet connection. Cloud
providers ("anthropic", "openai", "google")
remain one argument away when they are the right call.
The VLM never classifies. Every extracted value carries
source = "extracted_vlm"; the deterministic keys
consume the resulting PedonRecord unaware of how
each value was obtained.
Provenance is preserved end-to-end. The
evidence_grade on each
ClassificationResult reflects whether decisive
attributes came from measured,
predicted_spectra, extracted_vlm,
inferred_prior, or user_assumed – so a
caller always knows how robust the classification is.
Authority order is enforced. A pre-existing
measured value is never silently overwritten by a
later extracted_vlm value (unless
overwrite = TRUE).
vlm_provider,
extract_horizons_from_pdf,
classify_wrb2022,
report.
## Not run: # The simplest possible end-to-end call -- local Gemma 4 edge. res <- classify_from_documents( pdf = "perfil_042_descricao.pdf", image = "perfil_042_parede.jpg", report = "perfil_042.html" ) res$classifications$wrb$name #> "Geric Rhodic Ferralsol (Clayic, Dystric, Epic, Ferric, Humic)" # Cloud provider for a one-shot, production run res <- classify_from_documents( pdf = "perfil_042_descricao.pdf", provider = "anthropic" ) # Different Gemma 4 size on Ollama res <- classify_from_documents( pdf = "perfil_042_descricao.pdf", provider = "ollama", model = "gemma4:31b" ) ## End(Not run)## Not run: # The simplest possible end-to-end call -- local Gemma 4 edge. res <- classify_from_documents( pdf = "perfil_042_descricao.pdf", image = "perfil_042_parede.jpg", report = "perfil_042.html" ) res$classifications$wrb$name #> "Geric Rhodic Ferralsol (Clayic, Dystric, Epic, Ferric, Humic)" # Cloud provider for a one-shot, production run res <- classify_from_documents( pdf = "perfil_042_descricao.pdf", provider = "anthropic" ) # Different Gemma 4 size on Ollama res <- classify_from_documents( pdf = "perfil_042_descricao.pdf", provider = "ollama", model = "gemma4:31b" ) ## End(Not run)
A no-lab-data pipeline: profile photographs are sent to a vision-language
model for Munsell-colour and (optionally) site-metadata extraction; the
missing horizon attributes are back-filled from a SoilGrids depth prior;
and the WRB 2022, SiBCS 5 and USDA Soil Taxonomy keys are run on the
assembled PedonRecord.
classify_from_photos( images, lat = NULL, lon = NULL, country = NULL, provider = NULL, systems = c("wrb", "sibcs", "usda"), soilgrids = TRUE, depth_profiles = NULL, on_missing = "silent" )classify_from_photos( images, lat = NULL, lon = NULL, country = NULL, provider = NULL, systems = c("wrb", "sibcs", "usda"), soilgrids = TRUE, depth_profiles = NULL, on_missing = "silent" )
images |
Either a character vector of profile-photo paths, or a
named list with elements |
lat, lon
|
Optional decimal-degree coordinates. When supplied they
seed |
country |
Optional ISO-2 country code; passed through to the constructed pedon's site metadata. |
provider |
A vision-language provider: an ellmer chat object
for live use, or a |
systems |
Character vector, any subset of |
soilgrids |
If |
depth_profiles |
Optional named list of six-slice SoilGrids depth
profiles, forwarded to |
on_missing |
Forwarded to the classifiers; default |
Because every value originates from a photograph or a spatial prior, the
classification's evidence grade is low by construction (D for
VLM-extracted attributes, C where a SoilGrids prior contributed).
The result is a screening estimate, not a substitute for a described and
sampled profile.
A named list with one ClassificationResult per
requested system ($wrb, $sibcs, $usda),
the constructed $pedon, its $provenance ledger,
and a one-row $summary data frame. If extraction yields
no horizons the list instead carries $error and a
NULL pedon.
extract_munsell_from_photo,
apply_soilgrids_depth_prior,
compute_per_attribute_evidence_grade.
## Not run: # Live use with an ellmer chat: res <- classify_from_photos( images = list(profile = "profile.jpg", fieldsheet = "sheet.jpg"), lat = -22.7, lon = -43.6, country = "BR", provider = ellmer::chat_anthropic()) res$wrb$name res$wrb$evidence_grade # "D" or "C" ## End(Not run)## Not run: # Live use with an ellmer chat: res <- classify_from_photos( images = list(profile = "profile.jpg", fieldsheet = "sheet.jpg"), lat = -22.7, lon = -43.6, country = "BR", provider = ellmer::chat_anthropic()) res$wrb$name res$wrb$evidence_grade # "D" or "C" ## End(Not run)
Keys a PedonRecord through the Hungarian diagnostic soil
classification of Micheli et al. (2024, second approximation), following
its key to the soil types. Experimental: this release keys the
15 types (Laptalaj, Antropogen talaj, Koves-sziklas vaztalaj,
Kozethatasu talaj, Szolonyec talaj, Szoloncsak talaj, Duzzado agyagtalaj,
Reti talaj, Karbonat talaj, Mezosegi talaj, Agyagbemosodasos talaj,
Homoktalaj, Barnafold, Hordalektalaj, Foldeskopar). The subtype and
variety properties that the system adds to the name are not keyed yet.
classify_hscs2024( pedon, rules = NULL, on_missing = c("warn", "silent", "error"), gapfill = FALSE )classify_hscs2024( pedon, rules = NULL, on_missing = c("warn", "silent", "error"), gapfill = FALSE )
pedon |
A |
rules |
Optional pre-loaded rule set ( |
on_missing |
One of |
gapfill |
Opt-in within-pedon gap-fill, as in
|
The names are the Hungarian singular, as the text's naming example writes
them; levels$name_en gives an English gloss. The key reads the FAO
(2006) horizon notation the text adopts (an l or r suffix shows reductive
conditions; i slickensides; k carbonates; n sodium; p ploughing; t clay
accumulation; u artefacts; w a cambic horizon), moist and dry Munsell
colours, texture (Hungarian names of the USDA triangle the text prints,
English names, or lab clay, silt and sand), organic carbon, bulk density,
CaCO3, effervescence, secondary carbonates, base saturation, exchangeable
Na, Mg and the CEC, structure, slickensides, cracks, clay films, coarse
fragments, artefacts, the layer origin, the dipyridyl test
(childs_test), redoximorphic features, and the total water-soluble
salts (soluble_salts_pct, Hungarian method). From the site it reads
land_use, methane_odour, geomembrane,
mechanical_mixing_depth_cm and anthropic_truncation. Features
a describer records when met (artefacts, mottles, secondary carbonates,
cracks) are absent when not recorded. The choices where the text is
silent are listed in
system.file("rules", "hscs2024", "readings.yaml", package = "soilKey").
A ClassificationResult with system_id
"hscs2024", the type in name and rsg_or_order, the
type with its English gloss in levels, the key trace, and
provisional_because (types before the assigned one that could
not be decided).
Micheli E., Fuchs M., Lang V., Csorba A., Dobos E., Szegi T., Kele G. (2024). A diagnosztikus szemleletu hazai talajosztalyozasi rendszer. Utmutato. Masodik kozelites. Magyar Agrar- es Elettudomanyi Egyetem, Godollo.
make_hscs2024_example, soilkey_systems.
res <- classify_hscs2024(make_hscs2024_example("steppe"), on_missing = "silent") res$name res$levelsres <- classify_hscs2024(make_hscs2024_example("steppe"), on_missing = "silent") res$name res$levels
Keys a PedonRecord through the New Zealand Soil
Classification, 4th edition (Manaaki Whenua - Landcare Research 2026),
following its Key to Soil Orders and keys to groups and subgroups.
Experimental: this release keys the 15 orders (Organic, Gley,
Ultic, Podzol, Allophanic, Pumice, Melanic, Semiarid, Oxidic, Granular,
Pallic, Brown, Anthropic, Recent, Raw Soils), their 77 groups (since
0.9.298, e.g. Orthic Brown Soils, Perch-gley Pallic Soils) and their 336
subgroups (keyed from 0.9.299 to 0.9.302, e.g. Peaty Orthic Gley Soils,
Humose Orthic Podzol Soils, Mottled Fragic Pallic Soils, Typic Orthic
Brown Soils); seven groups have no subgroups and keep the group name. The
Cryic Soils of the appendix are not keyed.
classify_nzsc4( pedon, rules = NULL, on_missing = c("warn", "silent", "error"), gapfill = FALSE )classify_nzsc4( pedon, rules = NULL, on_missing = c("warn", "silent", "error"), gapfill = FALSE )
pedon |
A |
rules |
Optional pre-loaded rule set ( |
on_missing |
One of |
gapfill |
Opt-in within-pedon gap-fill, as in
|
The NZSC reads horizon notations and field tests. The diagnostics read
the New Zealand notation (Ah, E, Bw, Bt, Bg, Bh, Bs, Bo, Bx, Bw(g), Bhm,
Bsm, Blm, CR, R, Of, Om, Oh, Lm, Lh, an e prefix for anthropic soil
material; FAO designations are read by the same letters), moist Munsell
colours, texture (field_texture words or codes, or lab clay, silt
and sand), pH, P retention (phosphate_retention_pct), dry bulk
density, volcanic glass, coarse fragments and their origin, structure,
clay coatings, carbonate, ESP, and the field tests naf_test
(reactive-aluminium test: none, slight, moderate, strong),
childs_test, sensitivity_class, fluidity_class,
stickiness and strength_moist. From the site it reads
drainage_class, parent_material (Melanic Soils),
anthropic_truncation and overthickened_a (the note to the
key on overthickened A horizons), and designation_system. The
groups also read the packing (packing_degree), Ksat
(ksat_mm_h), penetration resistance, where the redox segregations
are (redox_segregations_location), sulfate S, roots, a Maori
cultural layer (maori_cultural_layer) and the colour of coatings;
and, on the site, soil_temp_30cm_C, mean_annual_air_temp_C,
surface_water, methane_odour,
mechanical_mixing_depth_cm and artificially_drained. The
subgroups also read sulfidic S (sulfidic_s_pct), the EC of a 1:5
extract (ec_1to5_dS_m), the share of Sphagnum in the fibres
(sphagnum_fibres_pct), a shelly layer (shelly_layer),
exchangeable Ca and Mg, clay films, the colour of coatings on pores
(pore_coatings_hue_moist, pore_coatings_value_moist,
pore_coatings_chroma_moist), the weathering of rock fragments
(weathering_stage, weathered_fragments_pct) and the
cementation class; on the site, mechanical_mixing_purpose and
acid_neutralising_amendment (Mixed and Fill Anthropic Soils).
Features
a describer records when met (stratification, nodules, cracks, refuse or
cultural layers, permafrost, surface water) are absent when not recorded.
The choices where the text is silent are listed in
system.file("rules", "nzsc4", "readings.yaml", package = "soilKey").
A ClassificationResult with system_id
"nzsc4", the deepest class in name (the subgroup, or the
group where no subgroup is keyed yet), the order in
rsg_or_order, the classes of each level in levels, the key
trace, and provisional_because (classes before the assigned one
that could not be decided).
Manaaki Whenua - Landcare Research (2026). New Zealand Soil Classification. 4th ed. doi:10.7931/dl1-lrss-4-2026.
make_nzsc4_example, soilkey_systems.
res <- classify_nzsc4(make_nzsc4_example("brown"), on_missing = "silent") res$nameres <- classify_nzsc4(make_nzsc4_example("brown"), on_missing = "silent") res$name
Builds one PedonRecord per profile from a table with one row
per horizon, and classifies each with classify_all. The
column named by id says which profile a horizon belongs to; the
other columns use soilKey's names (horizon_attribute_spec),
or are renamed and converted by map. Site properties
(site_attribute_spec), such as soil_moisture_regime,
come from sites.
classify_profiles( horizons, sites = NULL, id = "profile_id", map = NULL, systems = "all", on_missing = "silent", ... )classify_profiles( horizons, sites = NULL, id = "profile_id", map = NULL, systems = "all", on_missing = "silent", ... )
horizons |
A |
sites |
Optional site properties: a |
id |
Name of the column that identifies the profile, in
|
map |
Optional |
systems, on_missing
|
Forwarded to |
... |
Other arguments forwarded to |
The names are checked once for the whole table: a horizon column or site
property that no key reads is named in one warning (see
unrecognised_attributes), not once per profile. Within a
profile the horizons are put in order of top_cm. A profile that
cannot be built or classified gets its reason in the error column,
and the others are classified as usual.
A data.frame with one row per profile, in the order of
their first horizon in horizons: the id column, one column
per system with the name of the class (as in the summary of
classify_all), missing (the attributes the keys
asked for and did not find, comma-separated) and error (NA,
or why the profile could not be classified). The attributes
"results" and "pedons" hold the full
classify_all results and the pedons, in lists named by
profile id.
classify_all for one pedon,
classify_csv for one profile in a spreadsheet,
unrecognised_attributes to check the names first.
h <- rbind( cbind(profile_id = "p1", as.data.frame(make_ferralsol_canonical()$horizons)), cbind(profile_id = "p2", as.data.frame(make_phaeozem_canonical()$horizons))) s <- data.frame(profile_id = c("p1", "p2"), soil_moisture_regime = c("udic", "ustic")) res <- classify_profiles(h, sites = s, systems = "usda") res[, c("profile_id", "usda", "error")] # Columns named and measured differently: rename and convert with `map`. h2 <- h names(h2)[names(h2) == "oc_pct"] <- "ORGC" h2$ORGC <- h2$ORGC * 10 # g/kg m <- data.frame(from = "ORGC", to = "oc_pct", factor = 0.1) classify_profiles(h2, sites = s, map = m)[, c("profile_id", "wrb", "sibcs", "usda")]h <- rbind( cbind(profile_id = "p1", as.data.frame(make_ferralsol_canonical()$horizons)), cbind(profile_id = "p2", as.data.frame(make_phaeozem_canonical()$horizons))) s <- data.frame(profile_id = c("p1", "p2"), soil_moisture_regime = c("udic", "ustic")) res <- classify_profiles(h, sites = s, systems = "usda") res[, c("profile_id", "usda", "error")] # Columns named and measured differently: rename and convert with `map`. h2 <- h names(h2)[names(h2) == "oc_pct"] <- "ORGC" h2$ORGC <- h2$ORGC * 10 # g/kg m <- data.frame(from = "ORGC", to = "oc_pct", factor = 0.1) classify_profiles(h2, sites = s, map = m)[, c("profile_id", "wrb", "sibcs", "usda")]
v0.7 ligou as 13 ordens; v0.7.1 desce ao 2o nivel (subordens) via
run_sibcs_subordem; v0.7.3 desce ao 3o nivel (Grandes
Grupos) via run_sibcs_grande_grupo para as ordens
progressivamente wiradas em
inst/rules/sibcs5/grandes-grupos/<ordem>.yaml (Cap 14
Organossolos primeiro). Quando a subordem ainda nao tem bloco de
Grandes Grupos, ou quando nenhum Grande Grupo passa (e nao ha
catch-all default), a classificacao para no 2o nivel.
classify_sibcs( pedon, rules = NULL, on_missing = c("warn", "silent", "error"), include_familia = FALSE, gapfill = FALSE )classify_sibcs( pedon, rules = NULL, on_missing = c("warn", "silent", "error"), include_familia = FALSE, gapfill = FALSE )
pedon |
A |
rules |
Conjunto de regras pre-carregado. |
on_missing |
Um de |
include_familia |
Quando |
gapfill |
Preenchimento opcional de lacunas por interpolacao
intra-perfil, default |
Um ClassificationResult cujo name eh o
nome completo da classe atribuida no nivel mais profundo
(Grande Grupo > Subordem > Ordem) e rsg_or_order eh
o nome da ordem (e.g. "Organossolos"). Os codigos de cada
nivel e o trace ficam em $trace.
pedon <- make_latossolo_canonical() res <- classify_sibcs(pedon) res$namepedon <- make_latossolo_canonical() res <- classify_sibcs(pedon) res$name
Aplica as dimensoes pertinentes a ordem do solo e devolve uma
lista nomeada de FamilyAttribute. O label
textual da Familia eh formado adicionando-se cada value
nao-nulo apos a designacao do 4o nivel, separados por
virgulas (Cap 18, p 281).
classify_sibcs_familia( pedon, ordem_code = NULL, sg_code = NULL, max_depth_cm = 200, nome_superior = NULL )classify_sibcs_familia( pedon, ordem_code = NULL, sg_code = NULL, max_depth_cm = 200, nome_superior = NULL )
pedon |
A |
ordem_code |
Codigo da ordem (1 letra: "P", "L", ...). Se
|
sg_code |
Codigo do subgrupo do 4o nivel (e.g. "PVdAr"). Opcional; usado para ajustes especificos por SG (e.g. forcar subgrupamento textural em arenicos/espessarenicos). |
max_depth_cm |
Profundidade da secao de controle (default 200 cm). |
nome_superior |
Nome da classe nos niveis mais altos (e.g. o nome do subgrupo). Opcional; quando ja diz Eutroficos / Distroficos, a saturacao por bases nao e repetida, e quando ja diz Aluminicos, o termo "alico" nao e repetido (Cap 18, p 285). |
Esta funcao NAO eh uma chave determinista: cada perfil recebe SIMULTANEAMENTE todos os adjetivos pertinentes (multi-rotulo).
Lista nomeada de FamilyAttribute.
Implementadas 5 dimensoes – grupamento textural, subgrupamento textural, distribuicao de cascalhos, constituicao esqueletica, tipo de horizonte superficial. Outras dimensoes (prefixos epi/ meso/endo, saturacao de bases, alico, mineralogia, atividade da argila, oxidos de ferro, andico, especificos de Organossolos) adicionadas em sub-commits subsequentes.
Embrapa (2018), SiBCS 5a ed., Cap 18, pp 281-288.
Walks the canonical USDA key (Order -> Suborder -> Great Group -> Subgroup) using YAML rule files at:
inst/rules/usda/key.yaml: Order key (12 entries)
inst/rules/usda/suborders/<order>.yaml
inst/rules/usda/great-groups/<order>.yaml
inst/rules/usda/subgroups/<order>.yaml
classify_usda( pedon, rules = NULL, on_missing = c("warn", "silent", "error"), include_family = FALSE, infer_temperature = TRUE, gapfill = FALSE )classify_usda( pedon, rules = NULL, on_missing = c("warn", "silent", "error"), include_family = FALSE, infer_temperature = TRUE, gapfill = FALSE )
pedon |
A |
rules |
Optional pre-loaded rule set. |
on_missing |
One of |
include_family |
If |
infer_temperature |
When deriving the family, infer the soil
temperature regime from latitude/elevation if
|
gapfill |
Opt-in within-pedon depth gap-fill, default |
With include_family = TRUE it additionally derives the 5th
category, the family – a set of class modifiers
(particle-size, mineralogy, CEC-activity, reaction, temperature
regime, depth) PREPENDED to the subgroup name, e.g. "fine,
kaolinitic, isohyperthermic Rhodic Hapludox". See
classify_usda_family.
A ClassificationResult with deepest-level
taxon name. Each level's trace is in $trace; the family
attributes are in $trace$family.
Soil Survey Staff (2022). Keys to Soil Taxonomy, 13th edition. USDA Natural Resources Conservation Service.
pedon <- make_ferralsol_canonical() res <- classify_usda(pedon) res$name # include the 5th (family) level: classify_usda(pedon, include_family = TRUE)$namepedon <- make_ferralsol_canonical() res <- classify_usda(pedon) res$name # include the 5th (family) level: classify_usda(pedon, include_family = TRUE)$name
Runs the applicable family-modifier dimensions and returns them as a named
list of FamilyAttribute objects (multi-label; each dimension
is orthogonal). Mirrors classify_sibcs_familia.
classify_usda_family( pedon, order_code = NULL, subgroup_code = NULL, infer_temperature = TRUE )classify_usda_family( pedon, order_code = NULL, subgroup_code = NULL, infer_temperature = TRUE )
pedon |
A |
order_code |
Optional USDA order code (selects applicable dimensions). |
subgroup_code |
Optional subgroup code (reserved for refinements). |
infer_temperature |
Passed to
|
Named list of FamilyAttribute objects.
Soil Survey Staff (2022), KST 13th ed., Ch. 16–17.
family_label_usda, classify_usda.
Sends a soilKey PedonRecord to the SmartSolosExpert
REST endpoint maintained by Embrapa (Glauber Vaz's PROLOG-based
implementation of the SiBCS classifier) and returns the resulting
four-level classification (Ordem / Subordem / Grande Grupo /
Subgrupo) wrapped in a soilKey
ClassificationResult.
classify_via_smartsolos_api( pedon, api_key = Sys.getenv("AGROAPI_TOKEN"), endpoint = c("classification", "verification"), drenagem = NULL, reference_sibcs = NULL, base_url = "https://api.cnptia.embrapa.br/smartsolos/expert/v1", timeout_seconds = 30, post_fn = NULL, verbose = TRUE )classify_via_smartsolos_api( pedon, api_key = Sys.getenv("AGROAPI_TOKEN"), endpoint = c("classification", "verification"), drenagem = NULL, reference_sibcs = NULL, base_url = "https://api.cnptia.embrapa.br/smartsolos/expert/v1", timeout_seconds = 30, post_fn = NULL, verbose = TRUE )
pedon |
A |
api_key |
Bearer token. Defaults to
|
endpoint |
One of |
drenagem |
Optional drainage class. Integer 1..8 or
Portuguese string ( |
reference_sibcs |
Optional named list ( |
base_url |
Override base URL. Default
|
timeout_seconds |
HTTP timeout (default 30). |
post_fn |
Internal: function with signature
|
verbose |
If |
This is an **external classifier** – the package does not host or
replicate the PROLOG rules. The function exists so soilKey users
can cross-validate the local classifier against an authoritative
Embrapa-hosted reference. Use the "verification" endpoint to
compare against your own user-supplied reference classification
(the API returns a per-level match summary with counters
L0..L4).
Authentication: register a free AgroAPI account at
https://www.agroapi.cnptia.embrapa.br/portal/, subscribe to
the SmartSolosExpert API and generate an access token. Pass it via
the AGROAPI_TOKEN environment variable or the
api_key argument.
A ClassificationResult with
system = "SiBCS 5a edicao (SmartSolosExpert API)"
and the four taxonomic levels in
rsg_or_order (Ordem) and qualifiers
(Subordem / GdeGrupo / Subgrupo). Verification-mode
responses additionally carry trace$smartsolos_summary
(the per-level match counters L0..L4).
Vaz, G. J., Silva Neto, L. de F. da, & Barbedo, J. G. A. (2025). SmartSolos Expert: an expert system for Brazilian soil classification. Smart Agricultural Technology, 10, 100735. doi:10.1016/j.atech.2024.100735.
Vaz, G. J., Silva Neto, L. de F. da, Lima, R. N., & Oliveira, S. R. de M. (2019). Uma API para a classificacao de solos do Brasil. In Anais do 12 Congresso Brasileiro de Agroinformatica (SBIAGRO 2019), pp. 63-72. Ponta Grossa.
Vaz, G. J., Silva Jr, A. F., & Silva Neto, L. de F. da (2023). Brazilian soil data for taxonomic classification. Redape, V1. doi:10.48432/PYKKA7.
classify_sibcs for the local PROLOG-free
classifier; compare_smartsolos for a
side-by-side comparison helper;
benchmark_redape for the gold-standard
curated dataset published by the same authors.
## Not run: Sys.setenv(AGROAPI_TOKEN = "<your token>") res <- classify_via_smartsolos_api(make_argissolo_canonical()) res$rsg_or_order # "ARGISSOLO" res$qualifiers #> $subordem "VERMELHO" #> $gde_grupo "Distrofico" #> $subgrupo "tipico" ## End(Not run)## Not run: Sys.setenv(AGROAPI_TOKEN = "<your token>") res <- classify_via_smartsolos_api(make_argissolo_canonical()) res$rsg_or_order # "ARGISSOLO" res$qualifiers #> $subordem "VERMELHO" #> $gde_grupo "Distrofico" #> $subgrupo "tipico" ## End(Not run)
Convenience wrapper that routes classify_wrb2022 /
classify_sibcs / classify_usda
through whichever engine the heuristic recommends for the
specific pedon.
classify_with_engine_heuristic( pedon, system = c("wrb2022", "sibcs", "usda"), min_score = 3L, ... )classify_with_engine_heuristic( pedon, system = c("wrb2022", "sibcs", "usda"), min_score = 3L, ... )
pedon |
A |
system |
One of |
min_score |
Forwarded to |
... |
Forwarded to the underlying classifier. |
The result of the chosen classifier (a
ClassificationResult). The chosen engine is
captured in $trace$engine_used.
Runs n Monte-Carlo perturbations of a pedon and tallies the
resulting classes into an empirical posterior. Unlike
classification_robustness, the perturbation magnitude of
every (horizon, attribute) cell is scaled by its provenance
evidence grade (see get_perturbation_scale): an A-grade
measurement is nudged by a few percent, an E-grade assumption by a
third of its value. The posterior therefore reflects not just how
close the profile sits to a key boundary, but how trustworthy the
inputs that placed it there actually are.
classify_with_uncertainty( pedon, n = 200L, system = c("wrb2022", "sibcs", "usda"), level = c("rsg", "name"), scales = NULL, sensitivity = TRUE, seed = 42L )classify_with_uncertainty( pedon, n = 200L, system = c("wrb2022", "sibcs", "usda"), level = c("rsg", "name"), scales = NULL, sensitivity = TRUE, seed = 42L )
pedon |
A |
n |
Number of Monte-Carlo draws (default 200). |
system |
One of |
level |
|
scales |
Optional named list overriding the default per-grade
magnitudes; each element has the shape returned by
|
sensitivity |
If |
seed |
Random seed for reproducibility. |
A list of class "soilkey_uncertainty" with elements:
posterior (named numeric vector summing to 1, sorted
descending), top1 (the modal class), entropy
(Shannon entropy of the posterior, natural log), sensitivity
(a data.table of attribute / importance,
or NULL), n_runs, n_success,
baseline, system and level.
classification_robustness,
get_perturbation_scale,
compute_per_attribute_evidence_grade.
p <- make_ferralsol_canonical() u <- classify_with_uncertainty(p, n = 50, system = "wrb2022") u$posterior # P(RSG = x) u$entropy # near 0 for a robust profilep <- make_ferralsol_canonical() u <- classify_with_uncertainty(p, n = 50, system = "wrb2022") u$posterior # P(RSG = x) u$entropy # near 0 for a robust profile
High-level classification entry point. Pre-computes the implemented
diagnostic horizons (argic, ferralic, mollic) for transparent
reporting, runs the key, and assembles a
ClassificationResult with the trace, ambiguities,
missing-data hints, evidence grade, and (in future) prior sanity
check.
classify_wrb2022( pedon, prior = NULL, prior_threshold = 0.01, on_missing = c("warn", "silent", "error"), rules = NULL, strict = NULL, specifiers = FALSE, gapfill = FALSE )classify_wrb2022( pedon, prior = NULL, prior_threshold = 0.01, on_missing = c("warn", "silent", "error"), rules = NULL, strict = NULL, specifiers = FALSE, gapfill = FALSE )
pedon |
A |
prior |
Optional spatial prior – a |
prior_threshold |
Probability below which the prior triggers an "inconsistent" warning (default 0.01). |
on_missing |
One of |
rules |
Optional pre-loaded rule set. |
strict |
Logical or |
specifiers |
Logical. When |
gapfill |
Opt-in within-pedon depth gap-fill, default |
pedon <- make_ferralsol_canonical() res <- classify_wrb2022(pedon) res$namepedon <- make_ferralsol_canonical() res <- classify_wrb2022(pedon) res$name
Useful after pointing options(soilKey.kst13_dir) at other copies
of the files mid-session.
Frees ~3.1 MB.
clear_kst13_cache()clear_kst13_cache()
NULL, invisibly. Called for its side effect of emptying the KST 13th-edition lookup cache.
Removes the per-region cache files written by
download_ossl_subset. Useful when a stale cache is
suspected or when disk space is tight.
clear_ossl_cache(region = NULL, cache_dir = NULL, verbose = TRUE)clear_ossl_cache(region = NULL, cache_dir = NULL, verbose = TRUE)
region |
Optional character vector of regions to clear; the
default |
cache_dir |
Cache directory (defaults to the soilKey user-cache dir). |
verbose |
If |
Invisibly, the character vector of files that were removed.
A subsurface horizon with a massive or weak subangular blocky structure, poor in organic matter and iron oxides, with a kaolinite-dominated, low-activity clay fraction, and hard when dry. It is the diagnostic basis of the Cohesic qualifier and corresponds to the caracter coeso of the Brazilian SiBCS (typical of the coastal "Tabuleiros" Latossolos and Argissolos).
cohesic( pedon, max_oc = 0.5, min_clay = 15, max_cec_per_clay = 24, min_thickness = 10 )cohesic( pedon, max_oc = 0.5, min_clay = 15, max_cec_per_clay = 24, min_thickness = 10 )
pedon |
A |
max_oc |
Maximum soil organic carbon (%), default 0.5. |
min_clay |
Minimum clay (%), default 15. |
max_cec_per_clay |
Maximum CEC in cmol_c per kg clay, default 24. |
min_thickness |
Minimum thickness in cm, default 10. |
Diagnostic criteria (all required): mineral material with (1) < 0.5% soil organic carbon; (2) >= 15% clay; (3) a CEC (by 1 M NH4OAc, pH 7) of < 24 cmol_c per kg clay; (4) a massive or weak subangular blocky structure; (5) not cemented; (6) a rupture-resistance class, when dry, of at least hard; and (7) a thickness of >= 10 cm.
IUSS Working Group WRB (2022), Chapter 3.1.7, Cohesic horizon.
Given a list of priors (each a data.table with rsg_code,
probability), pools them into a single distribution using a
weighted geometric mean and renormalises to sum to 1.
combine_priors(priors, weights = NULL, epsilon = 1e-06)combine_priors(priors, weights = NULL, epsilon = 1e-06)
priors |
A list of |
weights |
Optional non-negative numeric vector of length
|
epsilon |
Smoothing floor for classes missing from a prior (default 1e-6). Must be > 0 – otherwise any class missing from a single prior is suppressed entirely. |
Geometric pooling has two desirable properties for soil-class priors:
externally Bayesian (the pooled posterior under any common likelihood matches what one would get by individual updates), and
zero-preserving: a class assigned probability 0 by any
prior is suppressed in the pooled distribution. To avoid
that, classes absent from a given prior are imputed with
the smoothing constant epsilon.
A data.table with columns rsg_code,
probability, sorted by descending probability.
Runs the soilKey hand-coded diagnostic and the aqp wrapper on the same pedon, returns both results plus an agreement flag. Useful for A/B benchmarks and for choosing which engine to use per dataset.
compare_engines(pedon, diagnostic = c("argic", "cambic"))compare_engines(pedon, diagnostic = c("argic", "cambic"))
pedon |
A |
diagnostic |
One of |
A list with soilkey, aqp, agree.
Runs both classify_sibcs (local) and
classify_via_smartsolos_api (remote PROLOG via
Embrapa AgroAPI) on the same PedonRecord and tabulates
agreement at each of the four SiBCS categorical levels.
compare_smartsolos(pedon, ...)compare_smartsolos(pedon, ...)
pedon |
A |
... |
Forwarded to |
A list with local and remote
ClassificationResults plus a one-row
agreement data.frame with columns
ordem, subordem, gde_grupo, subgrupo, n_match.
## Not run: Sys.setenv(AGROAPI_TOKEN = "<your token>") cmp <- compare_smartsolos(make_argissolo_canonical()) cmp$agreement ## End(Not run)## Not run: Sys.setenv(AGROAPI_TOKEN = "<your token>") cmp <- compare_smartsolos(make_argissolo_canonical()) cmp$agreement ## End(Not run)
Calcula o indice molar Ki = SiO2 / Al2O3 a partir de teores percentuais por ataque sulfurico-NaOH (Embrapa Manual de Metodos). Massas molares: 60.08 (SiO2), 101.96 (Al2O3):
compute_ki(sio2_pct, al2o3_pct)compute_ki(sio2_pct, al2o3_pct)
sio2_pct |
Teor de SiO2 por ataque sulfurico (%). |
al2o3_pct |
Teor de Al2O3 por ataque sulfurico (%). |
Ki (molar) = (% SiO2 / 60.08) / (% Al2O3 / 101.96)
1.6973 (% SiO2 / % Al2O3)
Ki molar (numeric); NA se algum input for NA ou Al2O3 0.
Embrapa (2018), SiBCS 5a ed., Cap 1, p 32; Embrapa Manual de Metodos de Analise de Solo (3a ed., 2017).
compute_ki(sio2_pct = 18, al2o3_pct = 20) # ~1.53, abaixo do limite latossolicocompute_ki(sio2_pct = 18, al2o3_pct = 20) # ~1.53, abaixo do limite latossolico
Calcula o indice molar Kr = SiO2 / (Al2O3 + Fe2O3) usando massas molares 60.08 (SiO2), 101.96 (Al2O3) e 159.69 (Fe2O3):
compute_kr(sio2_pct, al2o3_pct, fe2o3_pct)compute_kr(sio2_pct, al2o3_pct, fe2o3_pct)
sio2_pct |
Teor de SiO2 por ataque sulfurico (%). |
al2o3_pct |
Teor de Al2O3 por ataque sulfurico (%). |
fe2o3_pct |
Teor de Fe2O3 por ataque sulfurico (%). |
Kr (molar) = (% SiO2 / 60.08) / (% Al2O3 / 101.96 + % Fe2O3 / 159.69)
Kr molar (numeric); NA se algum input for NA ou denominador
0.
Embrapa (2018), SiBCS 5a ed., Cap 1, p 32.
compute_kr(sio2_pct = 18, al2o3_pct = 20, fe2o3_pct = 12)compute_kr(sio2_pct = 18, al2o3_pct = 20, fe2o3_pct = 12)
Resolves the evidence grade of every (horizon, attribute) cell
that carries a provenance entry. Where a cell has more than one entry
(a value re-sourced over the profile's lifetime) the most authoritative
source wins, mirroring PedonRecord's own authority order.
compute_per_attribute_evidence_grade(pedon)compute_per_attribute_evidence_grade(pedon)
pedon |
A |
Grades: A measured, B predicted from spectra, C
inferred from a spatial prior, D extracted by a vision-language
model, E user-assumed.
A data.table with columns horizon_idx,
attribute and grade, sorted by horizon then
attribute. A pedon with no provenance entries yields a
zero-row table.
classify_from_photos, the global
evidence grade reported on every ClassificationResult.
p <- make_ferralsol_canonical() compute_per_attribute_evidence_grade(p) # all-measured -> all grade Ap <- make_ferralsol_canonical() compute_per_attribute_evidence_grade(p) # all-measured -> all grade A
Consolidated material below the soil. v0.3.3: detects via designation
R or Cr on the lowermost (or any) layer.
continuous_rock(pedon)continuous_rock(pedon)
pedon |
A |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Measures, by NAME, exactly which canonical taxa/qualifiers the package's
deterministic rule base registers, replacing hand-maintained coverage
claims with an auditable, reproducible diff. For "usda_subgroup" the
canonical reference is the Soil Taxonomy 13th-edition subgroup set from
kst13_codes; for "wrb_qualifiers" it is the WRB 2022
principal + supplementary qualifier set from wrb2022_canonical.
coverage_report( system = c("usda_subgroup", "usda_great_group", "usda_suborder", "wrb_qualifiers", "wrb_horizons", "wrb_properties", "wrb_materials", "wrb_rsg", "sibcs"), write = FALSE, report_dir = NULL )coverage_report( system = c("usda_subgroup", "usda_great_group", "usda_suborder", "wrb_qualifiers", "wrb_horizons", "wrb_properties", "wrb_materials", "wrb_rsg", "sibcs"), write = FALSE, report_dir = NULL )
system |
Which axis to measure. USDA taxon levels against the Soil
Taxonomy 13th-edition code set ( |
write |
If |
report_dir |
Directory for the Markdown report when |
Invisibly, a list with $overall (one-row data frame:
system, level, canonical_n, registered_n,
covered_n, missing_n, pct), $by_group (per
order, or per principal/supplementary), $missing (canonical names
not registered), $extra (registered names absent from the canonical
set), and – for "wrb_qualifiers" – $stubs (functions that
exist but are inert). A compact summary is printed as a side effect.
# WRB diagnostic horizons are measured against soilKey's own table, offline. cov <- coverage_report("wrb_horizons") cov$overall # The USDA axes read the KST 13th edition from ncss-tech/SoilKnowledgeBase, # downloaded on first use, so they need a connection the first time. usda <- try(coverage_report("usda_subgroup"), silent = TRUE) if (!inherits(usda, "try-error")) head(usda$missing)# WRB diagnostic horizons are measured against soilKey's own table, offline. cov <- coverage_report("wrb_horizons") cov$overall # The USDA axes read the KST 13th edition from ncss-tech/SoilKnowledgeBase, # downloaded on first use, so they need a connection the first time. usda <- try(coverage_report("usda_subgroup"), silent = TRUE) if (!inherits(usda, "try-error")) head(usda$missing)
Tests whether continuous frozen / permafrost material occurs within
the upper max_top_cm. Two alternative paths qualify per WRB
2022:
Permafrost temperature: a layer at top_cm <=
max_top_cm (default 100) with
permafrost_temp_C <= max_temp_C (default 0 C).
Designation pattern: a layer at top_cm <=
max_top_cm with designation containing suffix
"f" (frozen) or matching "^Cf" / "perma".
Used as a fallback when the temperature field is not in the
pedon (typical of legacy survey data).
Either path qualifies. Diagnostic of Cryosols. When neither passes and
the site has a soil temperature regime warmer than gelic (cryic, frigid,
mesic, thermic, hyperthermic or an iso form;
site$soil_temperature_regime), the answer is no: those regimes
have no permafrost (KST 13, Ch. 3, p. 50).
cryic_conditions(pedon, max_top_cm = 100, max_temp_C = 0)cryic_conditions(pedon, max_top_cm = 100, max_temp_C = 0)
pedon |
A |
max_top_cm |
Maximum top depth (cm) (default 100). |
max_temp_C |
Maximum mean annual permafrost-zone temperature (deg C) for the temperature path (default 0). |
IUSS Working Group WRB (2022), Chapter 5, Cryosols.
A perennially frozen horizon in mineral or organic material (permafrost).
The permafrost logic is shared with cryic_conditions; this
exposes it under the canonical WRB 2022 horizon name so that
coverage_report("wrb_horizons") reports it, and returns a
DiagnosticResult named "cryic".
cryic_horizon(pedon, ...)cryic_horizon(pedon, ...)
pedon |
A |
... |
Passed to |
IUSS Working Group WRB (2022), Chapter 3.1.8, Cryic horizon.
DiagnosticResult: structured outcome of a diagnostic test
DiagnosticResult: structured outcome of a diagnostic test
Returned by every WRB or SiBCS diagnostic function (e.g.
argic, ferralic, mollic). A
DiagnosticResult never reduces to a bare TRUE/FALSE — it always carries
(a) which layers satisfied the criteria, (b) the per-sub-test evidence,
(c) which attributes would have been required but are missing, and
(d) the literature reference for the diagnostic definition.
passed is TRUE/FALSE/NA; NA means the
test could not be evaluated because critical attributes were missing.
This three-valued semantics propagates through the rule engine — an
indeterminate test does not silently fail.
nameCharacter. Name of the diagnostic (e.g. "argic").
passedLogical. TRUE, FALSE, or NA.
layersInteger vector. Indices of horizons that satisfy the diagnostic.
evidenceNamed list. Sub-test results, each itself a list with
at least passed, layers, and missing.
missingCharacter vector. Attribute names that would have been needed but were NA.
referenceCharacter. Literature citation for this diagnostic.
notesCharacter. Free-form notes (interpretation choices, edge cases hit).
new()
Build a DiagnosticResult.
DiagnosticResult$new( name, passed = NA, layers = integer(0), evidence = list(), missing = character(0), reference = NA_character_, notes = NA_character_ )
nameDiagnostic name.
passedTRUE/FALSE/NA.
layersInteger vector of horizon indices that satisfied.
evidenceNamed list of sub-test results.
missingCharacter vector of missing attribute names.
referenceCitation string.
notesFree-form notes.
print()
Pretty-print the result with sub-test breakdown.
DiagnosticResult$print(...)
...Ignored (S3 print signature compatibility).
as_list()
Return the result as a plain list (for serialization).
DiagnosticResult$as_list()
clone()
The objects of this class are cloneable with this method.
DiagnosticResult$clone(deep = FALSE)
deepWhether to make a deep clone.
Negacao operacional de eutrofico: V < 50% no
horizonte diagnostico subsuperficial.
distrofico(pedon, max_v = 50)distrofico(pedon, max_v = 50)
pedon |
A |
max_v |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
kdo|do|magn as proxy when ratio data missing.Dolomitic material (WRB 2022 Ch 3.3.5): \>= 2% Mg-rich carbonate,
CaCO3/MgCO3 < 1.5. v0.3.3: detects via designation pattern
kdo|do|magn as proxy when ratio data missing.
dolomitic_material(pedon)dolomitic_material(pedon)
pedon |
A |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Drives the Embrapa BDsolos web form via headless Chrome
(chromote) to produce a CSV of all profiles + all attributes.
Marked **experimental**: heavy queries (no UF filter) frequently
overload the Embrapa server. Prefer filter_uf = batches of
one or two states at a time and stitch the resulting CSVs.
download_bdsolos( out_path, accept_terms = FALSE, filter_uf = NULL, attributes = "default", timeout_seconds = 600, chromote_session = NULL, verbose = TRUE )download_bdsolos( out_path, accept_terms = FALSE, filter_uf = NULL, attributes = "default", timeout_seconds = 600, chromote_session = NULL, verbose = TRUE )
out_path |
File path for the downloaded CSV. |
accept_terms |
Logical. Must be |
filter_uf |
Optional 2-letter UF code (e.g. |
attributes |
Character vector. Which attribute groups to
request. Defaults to the full SiBCS-classification-relevant
set (Identificacao + Localizacao + Classificacao for Pontos
de Amostragem, Identificacao + Morfologicas + Fisicas +
Quimicas for Horizontes; Mineralogicas excluded for
performance). Pass |
timeout_seconds |
Total timeout for the AJAX query. Default 600 (10 min). |
chromote_session |
Optional pre-built |
verbose |
If |
Per the Embrapa terms-of-use, the data is licensed for personal /
academic use and publications must cite the source per ABNT.
Set accept_terms = TRUE to acknowledge this and let
the function click "Concordo" on your behalf.
File path to the downloaded CSV (invisible).
load_bdsolos_csv,
inspect_bdsolos_csv.
## Not run: # Single UF (fast, recommended) download_bdsolos("soil_data/bdsolos/RJ.csv", accept_terms = TRUE, filter_uf = "RJ") # Stitch multiple UFs for (uf in c("RJ", "SP", "MG", "ES")) { download_bdsolos(file.path("soil_data/bdsolos", paste0(uf, ".csv")), accept_terms = TRUE, filter_uf = uf) } # Then load all of them csvs <- list.files("soil_data/bdsolos", "\\.csv$", full.names = TRUE) all_pedons <- unlist(lapply(csvs, load_bdsolos_csv), recursive = FALSE) length(all_pedons) ## End(Not run)## Not run: # Single UF (fast, recommended) download_bdsolos("soil_data/bdsolos/RJ.csv", accept_terms = TRUE, filter_uf = "RJ") # Stitch multiple UFs for (uf in c("RJ", "SP", "MG", "ES")) { download_bdsolos(file.path("soil_data/bdsolos", paste0(uf, ".csv")), accept_terms = TRUE, filter_uf = uf) } # Then load all of them csvs <- list.files("soil_data/bdsolos", "\\.csv$", full.names = TRUE) all_pedons <- unlist(lapply(csvs, load_bdsolos_csv), recursive = FALSE) length(all_pedons) ## End(Not run)
soilKey ships four large benchmark caches (KSSL, KSSL+NASIS, AfSP,
WoSIS stratified) that are too large to embed in the CRAN source
tarball. Since v0.9.94 they are pinned to a versioned GitHub Release
and downloaded on demand into the user cache directory at
tools::R_user_dir("soilKey", "data").
download_extdata_cache( which = "all", release = NULL, overwrite = FALSE, verbose = TRUE )download_extdata_cache( which = "all", release = NULL, overwrite = FALSE, verbose = TRUE )
which |
Character vector of cache names to download.
|
release |
Release tag to pull from. |
overwrite |
If |
verbose |
Print progress (default |
On first call to any of load_kssl_sample(),
load_kssl_nasis_sample(), load_afsp_sample(), or
load_wosis_stratified_sample(), soilKey checks for the file
in the user cache. If missing, the loader prompts (interactive
sessions only) to download. Use download_extdata_cache()
to eagerly populate the cache without prompting.
Invisibly, a named character vector of local paths to the downloaded files.
## Not run: # Download every lazy-fetch cache once, ahead of any benchmark run: download_extdata_cache() # Or just the WRB AfSP sample: download_extdata_cache("afsp_sample") ## End(Not run)## Not run: # Download every lazy-fetch cache once, ahead of any benchmark run: download_extdata_cache() # Or just the WRB AfSP sample: download_extdata_cache("afsp_sample") ## End(Not run)
Fetches a region-filtered subset of the Open Soil Spectral Library
(Sanderman et al. 2024) and assembles it into the
'list(Xr, Yr, metadata)' shape consumed by
predict_ossl_mbl and
predict_ossl_plsr_local. The result is cached under
'tools::R_user_dir("soilKey", "cache")' so subsequent calls in the
same session (or future R sessions) skip the network.
download_ossl_subset( region = c("global", "south_america", "north_america", "europe", "africa", "asia", "oceania"), properties = c("clay_pct", "sand_pct", "silt_pct", "cec_cmol", "bs_pct", "ph_h2o", "oc_pct", "fe_dcb_pct", "caco3_pct"), wavelengths = 350:2500, endpoint = NULL, cache_dir = NULL, force = FALSE, verbose = TRUE )download_ossl_subset( region = c("global", "south_america", "north_america", "europe", "africa", "asia", "oceania"), properties = c("clay_pct", "sand_pct", "silt_pct", "cec_cmol", "bs_pct", "ph_h2o", "oc_pct", "fe_dcb_pct", "caco3_pct"), wavelengths = 350:2500, endpoint = NULL, cache_dir = NULL, force = FALSE, verbose = TRUE )
region |
One of |
properties |
Character vector of OSSL property names to keep
in 'Yr' (drops other reference columns to keep the artefact
small). Defaults to the WRB-relevant set used by
|
wavelengths |
Integer vector of wavelengths (nm) the returned
|
endpoint |
OSSL HTTP endpoint serving the JSON manifest;
overrideable via |
cache_dir |
Cache directory; defaults to
|
force |
If |
verbose |
If |
This function intentionally does not fall back to the synthetic predictor on network failure – a missing OSSL artefact is a real condition that the caller must handle, and silent fallback would make benchmarks meaningless.
A list with elements Xr (numeric matrix, rows =
training profiles, columns = wavelengths in nm),
Yr (data.frame with the requested property columns,
rows aligned to Xr), and metadata (snapshot
date, region, n profiles, source URL, and the SHA-256 of
the cache file). Pass it as the ossl_library
argument to fill_from_spectra or
predict_ossl_mbl.
Sanderman, J., Savage, K., Dangal, S.R.S., Duran, G., Rivard, C.,
Cardona, M.T., Sandzhieva, A., Aramian, A. & Safanelli, J.L. (2024).
Soil Spectroscopy for Global Good – the Open Soil Spectral Library
(OSSL). https://soilspectroscopy.org/.
Fetches a region-filtered slice of the Open Soil Spectral Library
via download_ossl_subset and post-joins WRB
Reference Soil Group labels from WoSIS GraphQL by spatial
nearest-neighbour. The resulting artefact has the canonical
list(Xr, Yr, metadata) shape – with extra columns in
Yr: wrb_rsg, wrb_label_source,
wrb_label_distance_km, plus optionally sibcs_ordem
and usda_order when translate_systems = TRUE.
download_ossl_subset_with_labels( region = c("global", "south_america", "north_america", "europe", "africa", "asia", "oceania"), max_distance_km = 5, wosis_endpoint = NULL, translate_systems = TRUE, max_to_label = Inf, verbose = TRUE, query_fn = NULL, ... )download_ossl_subset_with_labels( region = c("global", "south_america", "north_america", "europe", "africa", "asia", "oceania"), max_distance_km = 5, wosis_endpoint = NULL, translate_systems = TRUE, max_to_label = Inf, verbose = TRUE, query_fn = NULL, ... )
region |
OSSL region filter; one of |
max_distance_km |
WoSIS spatial-join tolerance in kilometres (default 5). Profiles whose nearest WRB-labeled WoSIS neighbour is farther than this are left unlabeled. |
wosis_endpoint |
Override for the WoSIS GraphQL endpoint
(default |
translate_systems |
If |
max_to_label |
Maximum number of profiles to query against
WoSIS (default |
verbose |
Emit |
query_fn |
Optional injection of the per-coordinate WoSIS
query function. Default uses
|
... |
Forwarded to |
A list with Xr (numeric matrix), Yr (data
frame with the labels attached), and metadata
(list with the OSSL fetch metadata + the join statistics:
number of profiles labeled, average / max distance,
WoSIS endpoint, snapshot date).
OSSL stores Vis-NIR / MIR spectra and lab data but typically lacks
WRB Reference Soil Group labels on most profiles (KSSL data is
USDA-flavoured; non-US contributions are inconsistent). WoSIS, by
contrast, archives ~228 000 profiles with WRB labels but no
spectra. This function bridges the two so the user can run
classify_by_spectral_neighbours on a real-data
OSSL library without having to do the spatial join themselves.
WRB labels obtained via spatial join are weak labels. The same physical location may have been classified differently across surveys (different WRB editions, different interpretations). Each row carries:
wrb_label_source = "wosis_spatial_join": label
inherited from a WoSIS neighbour within
max_distance_km.
wrb_label_distance_km: the distance to that
neighbour (NA when no neighbour was found within
tolerance).
wrb_label_source = "ossl_native": label was
already present in OSSL Yr (rare; preserved verbatim).
wrb_label_source = "missing": no neighbour within
tolerance; the row stays unlabeled and will be skipped
downstream.
Treat the labels as priors, not ground truth.
download_ossl_subset, classify_by_spectral_neighbours.
## Not run: # Real OSSL South-America subset with WRB labels: lib <- download_ossl_subset_with_labels( region = "south_america", max_distance_km = 10 ) table(lib$Yr$wrb_rsg, useNA = "always") table(lib$Yr$wrb_label_source) # Drop into the spectral analogy classifier: res <- classify_by_spectral_neighbours( spectrum = my_query_spectrum, ossl_library = lib, k = 25, region = list(lat = -22.7, lon = -43.7, radius_km = 500) ) ## End(Not run)## Not run: # Real OSSL South-America subset with WRB labels: lib <- download_ossl_subset_with_labels( region = "south_america", max_distance_km = 10 ) table(lib$Yr$wrb_rsg, useNA = "always") table(lib$Yr$wrb_label_source) # Drop into the spectral analogy classifier: res <- classify_by_spectral_neighbours( spectrum = my_query_spectrum, ossl_library = lib, k = 25, region = list(lat = -22.7, lon = -43.7, radius_km = 500) ) ## End(Not run)
Enumerates the dataset via the Dataverse API and downloads all
JSON profile files (the structured / interoperable format used
by the curators) into dest_dir. Skips files already
present unless overwrite = TRUE.
download_redape_dataset( dest_dir, dataset_doi = .REDAPE_GEOTAB_DOI, include_rtf = FALSE, overwrite = FALSE, verbose = TRUE )download_redape_dataset( dest_dir, dataset_doi = .REDAPE_GEOTAB_DOI, include_rtf = FALSE, overwrite = FALSE, verbose = TRUE )
dest_dir |
Destination directory for the JSON files. |
dataset_doi |
DOI of the dataset (default: the Vaz 2023 dataset). |
include_rtf |
If |
overwrite |
If |
verbose |
Print progress (default |
Character vector of paths to the downloaded files.
Vaz, G. J., Silva Jr, A. F., & Silva Neto, L. de F. da (2023). Brazilian soil data for taxonomic classification. Redape, V1. doi:10.48432/PYKKA7.
Tests for >= 10% volume of duripan nodules (Si-cemented) within a horizon at least 10 cm thick. Diagnostic of Durisols.
duric_horizon(pedon, min_thickness = 10, min_duripan_pct = 10)duric_horizon(pedon, min_thickness = 10, min_duripan_pct = 10)
pedon |
A |
min_thickness |
Minimum thickness (cm; default 10 per WRB 2022). |
min_duripan_pct |
Minimum duripan volume % (default 10 per WRB 2022). |
v0.3.1: thresholds aligned with WRB 2022 Ch 3.1.7 (10%, 10 cm) – previous v0.3 used 15%/15 cm. Petroduric (cemented continuous duripan) detection still deferred and will be added in v0.4.
IUSS Working Group WRB (2022), Chapter 3.1.7 – Duric horizon (p. 41).
Reuso de duric_horizon (WRB Ch 3.1): subsuperficial
cimentado por silica, continuo ou em \>= 50% volume.
duripa(pedon, ...)duripa(pedon, ...)
pedon |
A |
... |
Reserved for future arguments. |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Adds any missing canonical columns as NAs of the right type and reorders canonical columns first. Extra user-supplied columns are preserved at the end. Coerces character values to numeric where the schema requires it.
Column names are recognised tolerantly before coercion: an exact canonical
name always wins, but names differing only in capitalisation or separators
(pH_H2O, PH.H2O -> ph_h2o) and a small table of common
analytical abbreviations (Clay -> clay_pct, SOC ->
oc_pct, CEC -> cec_cmol, ...) are mapped to their
canonical form rather than silently ignored. See inst/ATTRIBUTES.md
for the complete list of recognised names and accepted aliases.
ensure_horizon_schema(h)ensure_horizon_schema(h)
h |
Input data.frame or data.table. |
A data.table with the canonical horizon columns present, in
canonical order, with extra columns preserved at the end.
h <- ensure_horizon_schema(data.frame(top_cm = 0, bottom_cm = 20)) "designation" %in% names(h) # capitalisation and common abbreviations are recognised: h2 <- ensure_horizon_schema(data.frame(pH_H2O = 5.4, Clay = 32, SOC = 1.1)) h2$ph_h2oh <- ensure_horizon_schema(data.frame(top_cm = 0, bottom_cm = 20)) "designation" %in% names(h) # capitalisation and common abbreviations are recognised: h2 <- ensure_horizon_schema(data.frame(pH_H2O = 5.4, Clay = 32, SOC = 1.1)) h2$ph_h2o
Returns TRUE se a saturacao por bases (V%) >= 50% no horizonte diagnostico subsuperficial (B ou C). 65% para A chernozemico.
eutrofico(pedon, min_v = 50)eutrofico(pedon, min_v = 50)
pedon |
A |
min_v |
Numeric threshold or option (see Details). |
Since v0.9.257, in a profile with a B horizon the base saturation is
judged as the key and the definitions of the classes ask for it, "na maior
parte dos primeiros 100 cm do horizonte B (inclusive BA)": it is high when
the B layers with V of min_v or more make more than half of the
thickness of that section, among the layers where V is recorded. The BC is
not part of the section. Until v0.9.256 one layer of B or of C with a high
V was enough. A profile with no B is read as before, in its C layers, or in
all of its layers when it has no C either.
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Given a parsed tests block from a YAML key entry, evaluates
the appropriate combinator and returns a list with passed,
evidence, missing, and (optionally) notes.
evaluate_rsg_tests(pedon, tests)evaluate_rsg_tests(pedon, tests)
pedon |
A |
tests |
A |
A list summarising the test outcome.
Reads a PDF (typically a soil survey chapter, field-sheet scan, or
thesis appendix), prompts the configured VLM to extract horizon
attributes against inst/schemas/horizon.json, and merges
the result into pedon. Every extracted attribute is recorded
with source = "extracted_vlm" and the model's reported
confidence and verbatim source quote.
extract_horizons_from_pdf( pedon, pdf_path = NULL, provider, max_retries = 3L, overwrite = FALSE, prompt_name = "extract_horizons", schema_name = "horizon", pdf_text = NULL )extract_horizons_from_pdf( pedon, pdf_path = NULL, provider, max_retries = 3L, overwrite = FALSE, prompt_name = "extract_horizons", schema_name = "horizon", pdf_text = NULL )
pedon |
A |
pdf_path |
Path to the PDF file. Either |
provider |
A chat provider from |
max_retries |
Integer; how many times to re-prompt on validation failure. Default 3. |
overwrite |
If |
prompt_name |
Override the default prompt template
( |
schema_name |
Override the default schema ( |
pdf_text |
Optional alternative to |
The PedonRecord's authority order guarantees that values already
tagged "measured" are never silently overwritten by VLM
extraction unless overwrite = TRUE.
If the PDF is long (more than ~30,000 characters), it is chunked page-by-page and each page is sent independently. This is a conservative-but-simple strategy; for very long surveys callers should pre-chunk and call this function once per profile.
Invisibly, the (mutated) pedon. Carries a
"vlm_extraction" attribute with the parsed response,
number of attempts, and number of provenance entries added.
If pdftools is not installed -> error.
If the PDF cannot be read -> error.
If the VLM response fails JSON parse / schema validation
after max_retries + 1 attempts -> error from
validate_or_retry.
Sends the photo to a multimodal VLM with a prompt that asks the
model to estimate Munsell hue / value / chroma per visible horizon
(when a Munsell reference card is in frame). Recorded as
extracted_vlm with the model's self-reported confidence;
photos without a reference card should yield confidence below 0.5
per the prompt specification.
extract_munsell_from_photo( pedon, image_path, provider, max_retries = 3L, overwrite = FALSE, prompt_name = "extract_munsell_from_photo", schema_name = "munsell" )extract_munsell_from_photo( pedon, image_path, provider, max_retries = 3L, overwrite = FALSE, prompt_name = "extract_munsell_from_photo", schema_name = "munsell" )
pedon |
A |
image_path |
Path to the image file (JPG / PNG). |
provider |
A chat provider from |
max_retries |
Integer; how many times to re-prompt on validation failure. Default 3. |
overwrite |
If |
prompt_name |
Override the default prompt template
( |
schema_name |
Override the default schema ( |
Quantitative non-color attributes (clay %, CEC, pH, etc.) are never extracted from photos, by prompt-level instruction. If the model returns one anyway, it is silently dropped.
Invisibly, the mutated pedon, with the photo added
to pedon$images.
Sends a photographed / scanned field sheet to a multimodal VLM and
merges the extracted site-level metadata (lat, lon, elevation,
parent material, land use, etc.) into pedon$site. Existing
fields are preserved unless overwrite = TRUE; only NULL
fields are filled.
extract_site_from_fieldsheet( pedon, image_path, provider, max_retries = 3L, overwrite = FALSE, prompt_name = "extract_site_metadata", schema_name = "site" )extract_site_from_fieldsheet( pedon, image_path, provider, max_retries = 3L, overwrite = FALSE, prompt_name = "extract_site_metadata", schema_name = "site" )
pedon |
A |
image_path |
Path to the field-sheet image. |
provider |
A chat provider from |
max_retries |
Integer; how many times to re-prompt on validation failure. Default 3. |
overwrite |
If |
prompt_name |
Override the default prompt template
( |
schema_name |
Override the default schema ( |
Invisibly, the mutated pedon.
Classifica a mineralogia da argila para Argissolos, Cambissolos,
Plintossolos, Luvissolos, Nitossolos, Vertissolos, Chernossolos,
Planossolos, Gleissolos quando ha informacao quantitativa de
atividade da argila e/ou Ki/Kr. Cobre as classes nao endereçadas
por familia_mineralogia_argila_latossolo:
esmectitica: T_argila >= ta_threshold (default
27 cmolc/kg argila), indicando dominancia de argilas 2:1
expansivas (esmectita / vermiculita / micas hidratadas).
caulinitica: Ki >= ki_caulinitico_min (default
0.75) e Kr >= kr_caulinitico_min (default 0.75),
alem de T_argila < ta_threshold.
oxidica: Kr < kr_caulinitico_min, indicando
predominancia de oxihidrooxidos de Fe e Al.
mista: nenhum dos outros gates fechou
conclusivamente – evidencia heterogenea ou incompleta.
Quando os tres atributos (T_argila, Ki, Kr) estiverem ausentes, o
resultado fica NULL e os atributos faltantes sao reportados.
familia_mineralogia_argila_geral( pedon, max_depth_cm = 200, ta_threshold = 27, ki_caulinitico_min = 0.75, kr_caulinitico_min = 0.75 )familia_mineralogia_argila_geral( pedon, max_depth_cm = 200, ta_threshold = 27, ki_caulinitico_min = 0.75, kr_caulinitico_min = 0.75 )
pedon |
A |
max_depth_cm |
Profundidade da secao de controle (default 200). |
ta_threshold |
Limite cmolc/kg argila para esmectitica (default 27). |
ki_caulinitico_min |
Limite Ki para caulinitica (default 0.75). |
kr_caulinitico_min |
Limite Kr para caulinitica vs oxidica (default 0.75). |
Embrapa (2018), SiBCS 5a ed., Cap 18, p 286-287.
Classe S4-like para atributos de Familia (5o nivel SiBCS)
Classe S4-like para atributos de Familia (5o nivel SiBCS)
Estrutura categorica (em vez de booleana) que representa um
adjetivo composto da Familia. value eh o adjetivo
atribuido (string) ou NULL quando a dimensao nao se
aplica ou nao foi possivel determinar.
nameNome da dimensao (e.g. "grupamento_textural").
valueAdjetivo atribuido (e.g. "argilosa") ou NULL.
evidenceLista nomeada com valores intermediarios.
missingVetor de colunas necessarias mas indisponiveis.
referenceString com referencia bibliografica.
new()
Build a FamilyAttribute.
FamilyAttribute$new( name, value = NULL, evidence = list(), missing = character(0), reference = "" )
nameNome da dimensao (e.g. "grupamento_textural").
valueAdjetivo atribuido (e.g. "argilosa") ou NULL.
evidenceLista nomeada com valores intermediarios.
missingVetor de colunas necessarias mas indisponiveis.
referenceString com referencia bibliografica.
print()
Pretty-print the attribute.
FamilyAttribute$print(...)
...Ignored (S3 print signature compatibility).
clone()
The objects of this class are cloneable with this method.
FamilyAttribute$clone(deep = FALSE)
deepWhether to make a deep clone.
Returns a data.frame listing FEBR dataset IDs that have at least
one Munsell-related column populated in their camada table,
with metadata: n_horizons, n_finite_munsell,
coverage, column_pattern.
febr_index_munsell(min_coverage = 0.1, refresh = FALSE, verbose = TRUE)febr_index_munsell(min_coverage = 0.1, refresh = FALSE, verbose = TRUE)
min_coverage |
Drop datasets whose Munsell coverage (fraction of horizons with non-NA hue) is below this. Default 0.1. |
refresh |
Logical. If |
verbose |
If |
Backed by a precomputed cache shipped in
R/sysdata.rda (.FEBR_MUNSELL_INDEX; results of the
May 2026 scan over 249 datasets). On first call after install,
returns the cache instantly. Pass refresh = TRUE to
re-scan FEBR live (slow, network-dependent; updates the
in-memory copy but does not modify the bundled cache).
A data.frame sorted by n_finite_munsell
descending.
Tests whether any horizon meets the ferralic horizon criteria. The ferralic horizon is a subsurface horizon resulting from long and intense weathering, characterized by very low cation exchange capacity per unit clay – the canonical "low-activity clay" signal that defines the Ferralsol RSG.
ferralic( pedon, min_thickness = 30, max_cec = NULL, engine = NULL, cec_inclusive = FALSE )ferralic( pedon, min_thickness = 30, max_cec = NULL, engine = NULL, cec_inclusive = FALSE )
pedon |
A |
min_thickness |
Minimum thickness in cm (default 30). |
max_cec |
CEC (1M NH4OAc, pH 7) per kg clay that a ferralic
horizon must stay below (default |
engine |
One of |
cec_inclusive |
|
Sub-tests called:
test_ferralic_texture – texture sandy loam or
finer.
test_cec_per_clay – CEC / clay < 16 (or < 20
under engine = "aqp") cmol_c/kg clay. Until v0.9.212 a
value equal to the limit passed; WRB 2022 Ch 3.1.10 criterion 3
is "< 16 cmolc kg-1 clay".
test_ferralic_thickness – thickness >= 30 cm.
v0.3.1 alignment with WRB 2022 Ch 3.1.10 (p. 44): the older "ECEC <= 12 cmol_c/kg clay" gate was removed because it is not in the canonical text – only CEC (1M NH4OAc, pH 7) < 16 is required.
v0.9.67 regional tolerance: BDsolos RJ benchmark (n=722 perfis)
showed 88/115 Latossolos failing the strict 16-cmol gate because
Embrapa lab methodology often reads CEC at 17-20 on profiles that
are unambiguously Latossolos by every other criterion. The
engine = "aqp" threshold of 20 closes that gap without
redefining the WRB threshold itself; users targeting strict
WRB 2022 fidelity should keep engine = "soilkey".
The weatherable-mineral test (<= 10% by volume), water-dispersible-clay test, and stratification / rock-structure exclusions remain deferred (they need mineralogical data outside the canonical horizon schema) and are refinements rather than gates.
IUSS Working Group WRB (2022). World Reference Base for Soil Resources, 4th edition. International Union of Soil Sciences, Vienna. Chapter 3.1.10 – Ferralic horizon (p. 44).
WRB-canonical: ferralic horizon \<= 150 cm AND no argic horizon starting above (or at the upper limit of) the ferralic, UNLESS the argic in its upper 30 cm or throughout has one or more of:
< 10% water-dispersible clay; OR
DeltapH (pH_KCl - pH_water) \>= 0; OR
\>= 1.4% soil organic carbon.
v0.3.4 enforces all three exception paths. The DeltapH check uses
ph_kcl and ph_h2o; the WDC check uses
water_dispersible_clay_pct (introduced in v0.3.3 schema), a clay
content in % of the fine earth.
ferralsol(pedon, strict = NULL)ferralsol(pedon, strict = NULL)
pedon |
A |
strict |
Logical or |
v0.9.310: the ferralic horizon must start <= 150 cm from the mineral soil surface; an argic horizon counts when it starts above or at the upper limit of the ferralic horizon (not only when it lies wholly above it); and an exception must hold throughout the upper 30 cm of the argic horizon (or all of it when it is thinner). Data that do not decide an exception leave the gate undecided (NA).
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
When an argic horizon sits above the ferralic, the default gate
keeps the profile as a Ferralsol if any one of the three
exception paths (WDC \< 10%, DeltapH \>= 0, SOC \>= 1.4%) holds.
With strict = TRUE the gate requires at least two of
the three – a single weak indicator no longer rescues a profile
with a translocated-clay argic from being keyed out of Ferralsols.
v0.9.309: the criteria of WRB 2022 Ch 3.1.11 (p. 45). The horizon consists
of mineral material, is >= 15 cm thick and is not part of a petroplinthic,
pisoplinthic or plinthic horizon, and has, in one or more subhorizons,
(a) >= 15% of its area as coarse (> 20 mm) masses inside aggregates that
are black or have a hue redder than 7.5YR and a chroma >= 5, moist, or
(b) >= 5% concretions or nodules, at least weakly cemented, reddish or
blackish, > 2 mm (ferric_nodules_pct). Until v0.9.308 soilKey read
it from Fe-dithionite >= 5%, which is not a criterion of the text: a red
Ferralsol with 6% Fe-dithionite and no nodules became Ferric (ISRIC's
KE009). soilKey records no size for mottles, so criterion (a) is met only
by nodules; mottles of the right colours leave it undecided, and a layer
with no mottles and no nodules recorded as such does not meet it.
ferric(pedon, min_thickness = 15, min_nodules_pct = 5)ferric(pedon, min_thickness = 15, min_nodules_pct = 5)
pedon |
A |
min_thickness |
Minimum thickness (cm; default 15). |
min_nodules_pct |
Minimum nodules, % (default 5). |
IUSS Working Group WRB (2022), Chapter 3.1.11, Ferric horizon.
Queries the "Derived Normal Climate Data" of Agriculture and Agri-Food Canada (30-year normals on a 5 km grid, Open Government Licence - Canada) at each point: the monthly mean air temperature of every month, and the monthly minimum and maximum temperature and the precipitation from April to October (the growing season of these normals). The values come from the AAFC map service (one request per variable and per thousand points); no file is downloaded. Needs the httr and jsonlite packages and an internet connection.
fetch_aafc_normals(lat, lon, period = "1961-1990", id = NULL, verbose = TRUE)fetch_aafc_normals(lat, lon, period = "1961-1990", id = NULL, verbose = TRUE)
lat, lon
|
Decimal degrees (WGS 84). |
period |
One of |
id |
Optional identifiers, returned as the first column. |
verbose |
Print progress. |
A data frame with id, lat, lon and one column
per variable (ta_m01 to ta_m12, tn_m04 to
tn_m10, tx_m04 to tx_m10, ac_m04 to
ac_m10; degrees Celsius and mm), with the period and the source
as attributes. Points outside the grid get NA.
Agriculture and Agri-Food Canada. Derived Normal Climate Data. Open Government Portal (dataset 3a060b8f-e662-4a60-b297-3bed859ffc8a), Open Government Licence - Canada.
npdb_soil_climate, npdb_scenario
## Not run: nm <- fetch_aafc_normals(lat = 52.13, lon = -106.67) npdb_soil_climate(nm) ## End(Not run)## Not run: nm <- fetch_aafc_normals(lat = 52.13, lon = -106.67) npdb_soil_climate(nm) ## End(Not run)
Reads NatSoil, the national soil site database of CSIRO, through its
public API and saves the JSON it returns in dir: first every
public site (pages of page_size sites, without horizons, in
dir/sites), then, for each site whose licence allows external use
(and, by default, that carries an order of the Australian Soil
Classification), its horizons, samples and laboratory results (one file
per site in dir/profiles). Files already in dir are not
downloaded again, so an interrupted run can be resumed. The data are
licensed per site, most under CC BY 4.0; cite them as each site's
citation field says (kept in site$citation by
load_natsoil_pedons).
fetch_natsoil( dir, classified_only = TRUE, max_sites = Inf, page_size = 200L, pause = 0.3, verbose = TRUE )fetch_natsoil( dir, classified_only = TRUE, max_sites = Inf, page_size = 200L, pause = 0.3, verbose = TRUE )
dir |
Folder for the downloaded files (created when missing). |
classified_only |
Download profiles only for sites with an ASC order. |
max_sites |
Maximum number of profiles to download in this call. |
page_size |
Sites per page in the site pass. |
pause |
Seconds to wait between requests. |
verbose |
Print progress. |
The whole site pass is about 150 requests and the profile pass one request per site (about 9,800 with an ASC order), with a pause between them.
Invisibly, a data frame of the sites selected for the profile
pass: agency_code, proj_code, s_id, the ASC order
given (asc_order), file and whether it is on disk
(fetched).
CSIRO. CSIRO National Soil Site Database (NatSoil). https://doi.org/10.25919/sg5w-ny87
load_natsoil_pedons, benchmark_natsoil.
## Not run: fetch_natsoil("natsoil") peds <- load_natsoil_pedons("natsoil") benchmark_natsoil(peds) ## End(Not run)## Not run: fetch_natsoil("natsoil") peds <- load_natsoil_pedons("natsoil") benchmark_natsoil(peds) ## End(Not run)
Material organico pouco decomposto: >= 40% de fibras esfregadas OU indice de von Post H1-H4. Discrimina Organossolos Fibricos no 3o nivel.
fibrico(pedon)fibrico(pedon)
pedon |
A |
Embrapa (2018), SiBCS 5a ed., Cap 14 (Organossolos), pp 224-226.
Given a PedonRecord carrying a spectra$vnir
matrix (rows = horizons, columns = wavelengths in nm), pre-processes
the spectra, predicts the requested soil properties using the chosen
OSSL-backed method, and writes the predictions into the pedon's
horizons table via pedon$add_measurement(..., source =
"predicted_spectra"). Each call updates the pedon's provenance log
so that downstream classification can derive an evidence grade.
fill_from_spectra( pedon, library = "ossl", region = c("global", "south_america", "north_america", "europe", "africa"), properties = c("clay_pct", "sand_pct", "silt_pct", "cec_cmol", "bs_pct", "ph_h2o", "oc_pct", "fe_dcb_pct", "caco3_pct"), method = c("mbl", "plsr_local", "pretrained"), preprocess = "snv+sg1", k_neighbors = 100L, overwrite = FALSE, ossl_library = getOption("soilKey.ossl_library"), ossl_models = getOption("soilKey.ossl_models"), verbose = TRUE )fill_from_spectra( pedon, library = "ossl", region = c("global", "south_america", "north_america", "europe", "africa"), properties = c("clay_pct", "sand_pct", "silt_pct", "cec_cmol", "bs_pct", "ph_h2o", "oc_pct", "fe_dcb_pct", "caco3_pct"), method = c("mbl", "plsr_local", "pretrained"), preprocess = "snv+sg1", k_neighbors = 100L, overwrite = FALSE, ossl_library = getOption("soilKey.ossl_library"), ossl_models = getOption("soilKey.ossl_models"), verbose = TRUE )
pedon |
A |
library |
Currently only |
region |
One of |
properties |
Character vector of OSSL-supported property names to predict. Default covers the most-requested WRB/SiBCS-relevant attributes. |
method |
One of |
preprocess |
Pre-processing pipeline; passed to
|
k_neighbors |
Number of neighbours for memory-based methods. |
overwrite |
If |
ossl_library |
Optional OSSL library object (see
|
ossl_models |
Optional named list of pretrained models (see
|
verbose |
If |
By default, predicted values do not overwrite measured
values (the add_measurement() authority logic protects them).
Setting overwrite = TRUE forces overwrite of any non-measured
value.
The mutated pedon, invisibly. Provenance entries with
source = "predicted_spectra" are added per
(horizon, property).
preprocess_spectra, predict_ossl_mbl,
predict_ossl_plsr_local,
predict_ossl_pretrained,
pi_to_confidence.
High-level helper that runs
predict_munsell_from_spectra per horizon over the
Vis-NIR spectra in pedon$spectra$vnir and writes the
resulting hue / value / chroma back to the matching horizon rows
via pedon$add_measurement(..., source = "predicted_spectra").
fill_munsell_from_spectra(pedon, overwrite = FALSE, verbose = TRUE)fill_munsell_from_spectra(pedon, overwrite = FALSE, verbose = TRUE)
pedon |
A |
overwrite |
If |
verbose |
If |
This is the operational answer to the v0.9.35 Argissolo color
confusion: when surveyor Munsell colors are missing and the user
has Vis-NIR (e.g. from OSSL), call this helper, then re-run
classify_sibcs – the v0.9.45
"color-undetermined" fallback will lift, and the classification
will descend to subordem / grande grupo / subgrupo with proper
evidence_grade.
The pedon, invisibly. Provenance entries with
source = "predicted_spectra" are appended.
Tests whether the profile shows fluvic material features: alternating textures across consecutive horizons within the upper 100 cm AND an irregular (non-monotone) organic carbon pattern with depth. Diagnostic of Fluvisols.
fluvic_material(pedon, max_top_cm = 100, min_clay_swing = 8)fluvic_material(pedon, max_top_cm = 100, min_clay_swing = 8)
pedon |
A |
max_top_cm |
Maximum top depth (cm) considered (default 100). |
min_clay_swing |
Minimum absolute clay-percent change between consecutive layers required to count as alternation (default 8 percentage points). |
Sub-test: test_fluvic_stratification.
v0.3 limitations: WRB 2022 fluvic material also requires age (typically <100 years for sediment freshness), which v0.3 does not check (no temporal fields in the schema). The stratification proxy is conservative – truly heterogeneous floodplain profiles with dramatic texture swings will pass; subtle alluvial sequences may miss. v0.4 will refine.
Fluvic material follows WRB 2022 Ch 3.3.6 (p. 87) layer by layer:
fluviatile, marine or lacustrine origin (rock_origin,
layer_origin, else the site's parent material); strata that are
obvious (the clay reversal above, or a sand reversal of 15%) OR
evidenced by two or more layers with more SOC than the layer directly above
( 0.2%, 25% relative and 0.2% absolute,
not of a natric or spodic horizon); and a single grain, massive, platy or
weak subangular blocky structure (granular or subangular blocky in a layer
of higher SOC). The layers returned are those that meet the three. An
origin, a texture or a structure that is not recorded leaves the result
undecided. The SiBCS carater fluvico keeps the earlier reading.
IUSS Working Group WRB (2022), Chapter 3, Fluvic material.
A surface horizon of well-aerated organic material, i.e. organic
material that is not water-saturated for long periods. It is the
aerobic twin of the histic_horizon: both consist of organic
material, but the histic horizon is water-saturated for >= 30 consecutive
days in most years while the folic horizon is saturated for < 30 days and is
not drained.
folic(pedon, min_oc = 20, max_saturation_days = 30, min_thickness = 10)folic(pedon, min_oc = 20, max_saturation_days = 30, min_thickness = 10)
pedon |
A |
min_oc |
Minimum soil organic carbon (%) for organic material, default 20 (WRB 2022 Ch 3.3.13; it was 12 until v0.9.312). |
max_saturation_days |
Maximum consecutive water-saturation days that still count as well-aerated, default 30. |
min_thickness |
Minimum thickness in cm, default 10. |
Diagnostic criteria (all required): organic material that (1) is saturated with water for < 30 consecutive days in most years and is not drained; and (2) has a thickness of >= 10 cm.
IUSS Working Group WRB (2022), Chapter 3.1.12, Folic horizon.
Format a WRB 2022 soil name with qualifiers
format_wrb_name( rsg_name, principal = character(0), supplementary = character(0) )format_wrb_name( rsg_name, principal = character(0), supplementary = character(0) )
rsg_name |
Full RSG name (e.g. "Ferralsols"). |
principal |
Character vector of principal-qualifier names, in the
order they are written (as |
supplementary |
Character vector of supplementary-qualifier names, in the order they are written. |
The name as WRB 2022 Chapter 2.2 writes it, e.g. "Geric Rhodic Ferralsol (Clayic, Eutric, Ferric, Humic)".
x/Bx.Fragic horizon (WRB 2022): a high-bulk-density horizon with restricted
rooting. v0.3.3: detects via bulk_density_g_cm3 >= 1.65 AND structure
grade massive/very firm OR designation pattern x/Bx.
fragic(pedon, min_thickness = 15, min_bd = 1.65)fragic(pedon, min_thickness = 15, min_bd = 1.65)
pedon |
A |
min_thickness |
Numeric threshold or option (see Details). |
min_bd |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Reuso de fragic (WRB v0.3.3): horizonte
subsuperficial endurecido quando seco, baixa MO, BD elevada,
quebradicidade.
fragipa(pedon, ...)fragipa(pedon, ...)
pedon |
A |
... |
Reserved for future arguments. |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Inverse of as_aqp. Walks each profile in the SPC,
renames aqp's canonical horizon column names back to soilKey's
(top -> top_cm, name -> designation,
clay -> clay_pct, ...), assembles a
PedonRecord per profile, and returns the list.
from_aqp(spc)from_aqp(spc)
spc |
A |
Round-trip property: from_aqp(as_aqp(pedon)) reproduces
pedon modulo column ordering.
A list of PedonRecord objects (length =
length(spc)).
as_aqp, the forward conversion.
## Not run: pedons <- list(make_ferralsol_canonical(), make_luvisol_canonical()) spc <- as_aqp(pedons) pedons2 <- from_aqp(spc) identical(pedons[[1]]$horizons$clay_pct, pedons2[[1]]$horizons$clay_pct) #> [1] TRUE ## End(Not run)## Not run: pedons <- list(make_ferralsol_canonical(), make_luvisol_canonical()) spc <- as_aqp(pedons) pedons2 <- from_aqp(spc) identical(pedons[[1]]$horizons$clay_pct, pedons2[[1]]$horizons$clay_pct) #> [1] TRUE ## End(Not run)
Classifies pedon with NO fill to get a provisional taxon, then fills
its missing cells from taxon_profiles[[<that taxon>]] (built by
build_taxon_profiles). Non-circular: the fill is keyed on the
model's own prediction, not the reference. Each fill is written with
source = "inferred_prior" (grade C). Reachable via
gapfill = list(method = "taxon", taxon_profiles = <...>).
gapfill_by_predicted_taxon( pedon, taxon_profiles, system = c("sibcs", "wrb2022", "usda"), attrs = NULL, confidence = 0.55 )gapfill_by_predicted_taxon( pedon, taxon_profiles, system = c("sibcs", "wrb2022", "usda"), attrs = NULL, confidence = 0.55 )
pedon |
A |
taxon_profiles |
Output of |
system |
One of |
attrs |
Attributes to fill (default: those present in the matched profile). |
confidence |
Provenance confidence (default 0.55, below a coordinate prior). |
Invisibly, the mutated pedon; attribute
"gapfill_by_predicted_taxon" records the taxon + cells filled.
build_taxon_profiles, apply_soilgrids_depth_prior
Recovers cells that are exact closures of other measured columns in the same
horizon (not statistical estimates): the texture third (clay/silt/sand) when
the other two are present and sum to \< 100; effective CEC as
sum(bases) + al; aluminium saturation as 100 * al / ecec; and
base saturation as 100 * sum(bases) / cec. Every fill is written with
source = "inferred_prior" so the PedonRecord authority
order keeps it from displacing a measured value and the evidence grade drops
to "C". Companion to gapfill_within_pedon (depth
interpolation) and apply_soilgrids_depth_prior (external prior);
reachable via the gapfill = list(method = "derive") argument of the
classifiers.
gapfill_derive_horizon(pedon, overwrite = FALSE)gapfill_derive_horizon(pedon, overwrite = FALSE)
pedon |
A |
overwrite |
If |
Invisibly, the mutated pedon; attribute
"gapfill_derive_horizon" records the count filled.
gapfill_within_pedon, apply_soilgrids_depth_prior
For each requested attribute, builds a depth profile from the horizons in
which that attribute is measured (non-NA) and linearly
interpolates the value at the mid-depth of every horizon where it is missing
– but only for horizons whose mid-depth falls strictly between the
shallowest and deepest measured layer. Cells above the top or below the
bottom measured layer are left NA: the function interpolates, it never
extrapolates. Each fill is written with source = "inferred_prior", so
the PedonRecord authority order keeps it from displacing a
measured, spectra-predicted or VLM-extracted value, and any downstream
compute_evidence_grade call reports grade "C".
gapfill_within_pedon(pedon, attrs = NULL, confidence = 0.6, overwrite = FALSE)gapfill_within_pedon(pedon, attrs = NULL, confidence = 0.6, overwrite = FALSE)
pedon |
A |
attrs |
Character vector of horizon columns to fill. Defaults to the continuous depth-trending attributes a linear interpolation can reasonably estimate (clay/silt/sand, pH, organic carbon, CEC/ECEC, base/aluminium saturation, bulk density). |
confidence |
Numeric in \[0, 1\] recorded as the provenance confidence
of each interpolated cell. Defaults to |
overwrite |
If |
This is the within-pedon companion to
apply_soilgrids_depth_prior (which fills from an external
SoilGrids profile rather than from the profile's own measured layers). It is
the mechanism behind the opt-in gapfill argument of
classify_wrb2022, classify_sibcs,
classify_usda and classify_all.
Note that this mutates pedon in place (as
apply_soilgrids_depth_prior does). The gapfill argument of the
classifiers operates on a deep copy instead, so a classification call never
alters the caller's pedon.
Invisibly, the mutated pedon. An attribute
"gapfill_within_pedon" on the return value records how many
cells were filled and for which attributes.
apply_soilgrids_depth_prior, classify_all
h <- data.frame( top_cm = c(0, 20, 40, 60), bottom_cm = c(20, 40, 60, 90), clay_pct = c(15, NA, 35, 40) ) p <- PedonRecord$new(horizons = h) gapfill_within_pedon(p, attrs = "clay_pct") p$horizons$clay_pct # second horizon filled to ~25 by interpolationh <- data.frame( top_cm = c(0, 20, 40, 60), bottom_cm = c(20, 40, 60, 90), clay_pct = c(15, NA, 35, 40) ) p <- PedonRecord$new(horizons = h) gapfill_within_pedon(p, attrs = "clay_pct") p$horizons$clay_pct # second horizon filled to ~25 by interpolation
Returns the noise magnitudes used by classify_with_uncertainty
for a cell of the given evidence grade. A measurement (grade A) is
perturbed only slightly; a user-assumed value (grade E) is perturbed
heavily, reflecting how little is actually known about it.
get_perturbation_scale(grade = c("A", "B", "C", "D", "E"))get_perturbation_scale(grade = c("A", "B", "C", "D", "E"))
grade |
One of |
A list with three elements: pct (the half-width of the
multiplicative perturbation, applied to most numeric attributes),
ph_abs (the half-width of the additive perturbation applied
to pH columns) and munsell_abs (the additive half-width for
Munsell value / chroma columns).
get_perturbation_scale("A")$pct # 0.03 -- measured values barely move get_perturbation_scale("E")$pct # 0.30 -- assumptions move a lotget_perturbation_scale("A")$pct # 0.03 -- measured values barely move get_perturbation_scale("E")$pct # 0.30 -- assumptions move a lot
Tests whether the profile shows gleyic properties (WRB 2022 Ch 3.2.6,
p. 75) in a layer starting within the upper max_top_cm (default
50). Gleyic properties qualify the Gleysols and many other RSGs (Gleyic,
Endogleyic, Epigleyic qualifiers).
gleyic_properties( pedon, max_top_cm = 50, min_redox_pct = 5, stagnic_decay_factor = 3 )gleyic_properties( pedon, max_top_cm = 50, min_redox_pct = 5, stagnic_decay_factor = 3 )
pedon |
A |
max_top_cm |
Maximum top depth (cm) of a candidate layer (default 50). |
min_redox_pct |
The oximorphic features of criterion 2 are more than this % of the layer (default 5). |
stagnic_decay_factor |
Not used since v0.9.312 (the decay test was removed); kept so that existing calls still work. |
Since v0.9.312 the layer reading follows the text and Hugo's reading of
it for field descriptions that do not say where the mottles sit: a layer
has gleyic properties when its matrix has a reductimorphic colour, moist
(criterion 1: hue N, 10Y, GY, G, BG, B or PB, or hue 2.5Y or 5Y with a
chroma of 2 or less; with more than 5% oximorphic features these are read
as the gleyic features of criterion 2 over a reduced matrix); when it has
more than 5% oximorphic features and lies directly on a layer with such a
matrix (criterion 3); or when it has them and the site records
groundwater within 150 cm that is not perched
(site$groundwater_kind, site$groundwater_depth_cm). A
mottled layer with none of these is NA, unless the site records no
groundwater, a perched water table or a deeper one, or a claric layer
lies directly above it: its features are then stagnic. Continuous rock
has no gleyic properties. Until v0.9.311 the features also had to
continue with depth (a "decay" test that is not in WRB 2022 and failed
the textbook oximorphic-over-reductimorphic sequence).
Field-described Brazilian Gleissolos profiles (e.g.\ the Embrapa
Redape curated dataset) routinely encode gleyic properties via the
designation suffix g (e.g.\ Cg, Cg1, Cgn,
Apg) plus low-chroma Munsell colours (chroma \<= 2), without
recording redoximorphic_features_pct as a numeric percent.
With options(soilKey.gleyic_designation_inference = TRUE) the
function accepts a layer as gleyic when the reading above does not pass,
the designation matches [A-Z][a-z0-9]*g and
munsell_chroma_moist <= 2 (or no Munsell colour). Default is
FALSE.
IUSS Working Group WRB (2022), Chapter 3.2.6, Gleyic properties.
WRB-canonical (multi-path):
Layer \>= 25 cm starting \<= 40 cm with gleyic properties throughout AND reducing conditions in some parts of every sublayer; OR
Mollic/umbric > 40 cm thick with reducing conditions some parts of every sublayer 40 cm below mineral surface to lower limit, AND directly underneath a layer \>= 10 cm with lower limit \>= 65 cm having gleyic properties + reducing conditions; OR
Permanent saturation by water \<= 40 cm.
Path 1 reads the layers of gleyic_properties (since
v0.9.312: the matrix colour, the layer underneath and the site's
groundwater, without the old decay-with-depth test) and of
reducing_conditions; since v0.9.312 the 25 cm may be made
of adjoining sublayers (Bg1 over Bg2), counted from the mineral soil
surface, and a layer whose redox reading is undecided leaves the gate
NA when it could complete the 25 cm. Path 3 is read from the
designation (W / saturated marker). Path 2 is not implemented.
gleysol(pedon, strict = NULL)gleysol(pedon, strict = NULL)
pedon |
A |
strict |
Logical or |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
With strict = TRUE the path-1 gleyic+reducing layer must start
within the upper 25 cm (instead of 40 cm), and the path-3
designation-only fallback (a “W” / aquic marker) is disabled:
strict mode requires measured gleyic and reducing evidence.
Returns the left-hand side if it is non-NULL, otherwise the right-hand side. Re-exported so that downstream code can use the same idiom soilKey itself uses internally.
a %||% ba %||% b
a |
The candidate value. |
b |
The fallback used when |
Either a or b.
GSM standard per Arrouays et al. (2014) "GlobalSoilMap: Toward a fine-resolution global grid of soil properties". Boundaries: 0-5, 5-15, 15-30, 30-60, 60-100, 100-200 cm.
GSM_DEPTHSGSM_DEPTHS
An object of class numeric of length 7.
Tests whether any horizon meets the gypsic horizon criteria. The gypsic horizon is a horizon of secondary gypsum accumulation, diagnostic for Gypsisols.
gypsic(pedon, min_thickness = 15, min_gypsum_pct = 5)gypsic(pedon, min_thickness = 15, min_gypsum_pct = 5)
pedon |
A |
min_thickness |
Minimum thickness in cm (default 15). |
min_gypsum_pct |
Minimum gypsum percent in fine earth (default 5). |
Sub-tests called:
test_caso4_concentration – gypsum >= 5%.
test_minimum_thickness – thickness >= 15 cm.
v0.2 limitations: the WRB rule that gypsum content must exceed the underlying horizon by 1% (absolute) is not enforced. Petrogypsic (cemented) horizons are not yet detected. Both deferred to v0.3.
IUSS Working Group WRB (2022). World Reference Base for Soil Resources, 4th edition. International Union of Soil Sciences, Vienna. Chapter 3 – Gypsic horizon.
Gypsiric material (WRB 2022 Ch 3.3.7): \>= 5% gypsum that is primary (not secondary). Without a "secondary fraction" schema column, v0.3.3 treats any layer with caso4_pct >= 5 as gypsiric unless it explicitly carries gypsic-horizon designation.
gypsiric_material(pedon, min_caso4_pct = 5)gypsiric_material(pedon, min_caso4_pct = 5)
pedon |
A |
min_caso4_pct |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Runs mpspline2::mpspline_tidy() on each requested numeric
horizon attribute, producing a new PedonRecord per input pedon
whose horizons table covers the canonical GSM intervals
(GSM_DEPTHS). Categorical attributes (designation,
Munsell hue) are propagated by mode-over-depth-overlap.
harmonize_to_gsm( pedons, attributes = c("clay_pct", "silt_pct", "sand_pct", "ph_h2o", "oc_pct", "cec_cmol", "base_saturation_pct", "munsell_value_moist", "munsell_chroma_moist", "redoximorphic_features_pct"), depths = GSM_DEPTHS, lam = 0.1, verbose = TRUE )harmonize_to_gsm( pedons, attributes = c("clay_pct", "silt_pct", "sand_pct", "ph_h2o", "oc_pct", "cec_cmol", "base_saturation_pct", "munsell_value_moist", "munsell_chroma_moist", "redoximorphic_features_pct"), depths = GSM_DEPTHS, lam = 0.1, verbose = TRUE )
pedons |
A list of |
attributes |
Character vector of numeric horizon column names to harmonise. Default covers the chemistry / texture / Munsell numeric columns the soilKey diagnostics use. |
depths |
Numeric vector of GSM depth boundaries (n+1 values
for n intervals). Default |
lam |
Smoothing parameter for the spline (default 0.1, per Bishop et al. 1999 recommendation). |
verbose |
If |
A list of new PedonRecord objects with
harmonised horizons.
The Bishop et al. (1999) spline conserves the integral of the attribute over depth: if the original pedon has 30 g/kg OC over 0-15 cm, the harmonised pedon will report 30 g/kg integrated over 0-15 cm (split between 0-5 and 5-15 in proportion to the spline-implied gradient). This is a critical property for benchmark integrity: simple linear interpolation does not preserve mass and biases means upward / downward systematically.
designation and munsell_hue_moist (and other
character columns in the horizon schema) cannot be splined.
Instead, for each target GSM interval, we pick the modal value
weighted by the depth-overlap fraction with the input horizons.
Ties broken by uppermost-input-horizon precedence.
Bishop, T.F.A., McBratney, A.B., Laslett, G.M. (1999). "Modelling soil attribute depth functions with equal-area quadratic smoothing splines." Geoderma 91: 27-45.
Arrouays, D. et al. (2014). "GlobalSoilMap: Toward a fine-resolution global grid of soil properties." Advances in Agronomy 125: 93-134.
mpspline2::mpspline_tidy, GSM_DEPTHS.
Material organico em decomposicao intermediaria: 17-40% de fibras esfregadas OU indice de von Post H5-H6. Discrimina Organossolos Hemicos no 3o nivel.
hemico(pedon)hemico(pedon)
pedon |
A |
Embrapa (2018), SiBCS 5a ed., Cap 14 (Organossolos), pp 224-226.
A horizon of organic material (WRB 2022 Ch 3.1.15): organic material
(oc_pct >= min_oc, default 20, Ch 3.3.13) that is at least
min_thickness cm thick (default 10). The thickness is that of the
adjoining organic layers that run from the surface, taken together. A
layer whose organic carbon is not recorded may be organic material and
leaves the answer undecided (NA) where it could change it. The
water-saturation criterion (saturated for 30 or more consecutive days, or
drained) is not read.
histic_horizon(pedon, min_thickness = 10, min_oc = 20, surface_top_cm = 0)histic_horizon(pedon, min_thickness = 10, min_oc = 20, surface_top_cm = 0)
pedon |
A |
min_thickness |
Minimum thickness (cm), default 10. |
min_oc |
Minimum soil organic carbon (%) of organic material, default 20 (WRB 2022 Ch 3.3.13). |
surface_top_cm |
Maximum top depth (cm) of the uppermost layer of the horizon (default 0, the soil surface). |
Since v0.9.313 this is the horizon only: the Histosols are keyed by
histosol(), which reads the Chapter 4 key as worded. Until then
this function was also the Histosols gate, with organic material read at
12% organic carbon and a second path of 40 cm of organic material within
the upper 80 cm.
IUSS Working Group WRB (2022), Chapter 3.1.15, Histic horizon, and Chapter 3.3.13, Organic material.
One row per canonical horizon column (see
horizon_column_spec), in its order, with the section it
belongs to, its unit, a description and the alternative column names that
are recognised for it. The metadata come from
inst/schemas/horizon-attributes.yaml, which also records, where
known, which classification keys read an attribute, the values a
categorical attribute takes and the range of a numeric one.
horizon_attribute_spec()horizon_attribute_spec()
A data.frame with the columns name, type
("numeric" or "character"), section, unit,
description, aliases, systems and allowed
(comma-separated, empty when none), and min and max
(NA when not recorded).
horizon_column_spec, ensure_horizon_schema.
a <- horizon_attribute_spec() a[a$name %in% c("clay_pct", "cec_cmol"), c("name", "unit", "description")]a <- horizon_attribute_spec() a[a$name %in% c("clay_pct", "cec_cmol"), c("name", "unit", "description")]
Returns the schema for the horizons data.table carried by a
PedonRecord: an ordered named list mapping column names to
their R type ("numeric" or "character"). Adding a new
attribute means editing this single function.
horizon_column_spec()horizon_column_spec()
Named list of column types in canonical order.
spec <- horizon_column_spec() head(names(spec))spec <- horizon_column_spec() head(names(spec))
Hortic horizon (WRB 2022): garden / kitchen-midden topsoil. Diagnostic criteria: thickness \>= 20 cm, dark colour (mollic-like), high P (Mehlich-3 P >= 100 mg/kg or P2O5_1pct_citric >= 175 mg/kg), high SOC.
hortic(pedon, min_thickness = 20, min_oc = 1, min_p_mehlich3 = 100)hortic(pedon, min_thickness = 20, min_oc = 1, min_p_mehlich3 = 100)
pedon |
A |
min_thickness |
Numeric threshold or option (see Details). |
min_oc |
Numeric threshold or option (see Details). |
min_p_mehlich3 |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Bg|Brg immediately below
an anthraquic-like topsoil.Hydragric horizon (WRB 2022): subsoil hydric horizon under anthraquic.
v0.3.3 detects via designation pattern Bg|Brg immediately below
an anthraquic-like topsoil.
hydragric(pedon, min_thickness = 20)hydragric(pedon, min_thickness = 20)
pedon |
A |
min_thickness |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Hypersulfidic material (WRB 2022 Ch 3.3.8): \>= 0.01% inorganic sulfidic S, pH \>= 4, capable of severe acidification on aerobic incubation.
hypersulfidic_material(pedon, min_s_pct = 0.01, min_pH = 4)hypersulfidic_material(pedon, min_s_pct = 0.01, min_pH = 4)
pedon |
A |
min_s_pct |
Numeric threshold or option (see Details). |
min_pH |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
incubation_ph is measured,
a sulfidic + pH>=4 layer that stays >= 4 on incubation is the set-complement
of hypersulfidic_material and is reported here. Without an
incubation pH the two cannot be told apart, so this returns empty (the layer
is reported as potential hypersulfidic instead).Hyposulfidic material (WRB 2022 Ch 3.3.9): same inorganic sulfidic S and
field pH as hypersulfidic but does NOT consist of hypersulfidic (criterion 3
– does not acidify to pH < 4 on aerobic incubation, usually self-neutralised
by carbonate). Reachable from v0.9.128: when incubation_ph is measured,
a sulfidic + pH>=4 layer that stays >= 4 on incubation is the set-complement
of hypersulfidic_material and is reported here. Without an
incubation pH the two cannot be told apart, so this returns empty (the layer
is reported as potential hypersulfidic instead).
hyposulfidic_material(pedon, min_s_pct = 0.01, min_pH = 4)hyposulfidic_material(pedon, min_s_pct = 0.01, min_pH = 4)
pedon |
A |
min_s_pct |
Numeric threshold or option (see Details). |
min_pH |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Reads the CSV header, attempts to map each column to the soilKey
horizon schema via .bdsolos_match_column, and prints
three sections:
inspect_bdsolos_csv(path, sep = NULL)inspect_bdsolos_csv(path, sep = NULL)
path |
Path to the CSV downloaded from BDsolos. |
sep |
Field separator (default |
Mapped columns – BDsolos name -> soilKey name
Unmapped columns – columns the loader will ignore
(review these before running load_bdsolos_csv to make
sure no critical attribute is silently dropped)
Munsell coverage – whether matiz / valor / croma are present in either umido or seco variants
Run this before load_bdsolos_csv on any new CSV from
BDsolos, especially if the export schema looks unfamiliar (BDsolos
has shipped multiple schema versions over the years).
Invisibly, a list with mapped, unmapped,
munsell_present, taxon_column.
v0.9.317: the criteria of WRB 2022 Ch 3.1.18 (p. 50-51), tested on every stack of contiguous layers from the mineral soil surface (a surface horizon of mineral material), each against the layer directly below it:
soil aggregate structure or cloddy structure in 90% by
volume;
a clay content 10% (relative) and 3%
(absolute) higher than that of the layer directly buried; the fine
clay alternative is not recorded, so a smaller increase leaves it
undecided;
differences between subhorizons of < 20% (relative) or < 4% (absolute) in silt, clay and carbonates (also in the medium, fine and very fine sand, which soilKey does not record: undecided for more than one layer unless a recorded difference fails);
0.3% SOC in each layer and 0.5% on a weighted
average;
25% traces of soil animal activity (worm_holes_pct,
weighted);
evidence that the land surface has been raised: soilKey records no such evidence, so this criterion is undecided;
20 cm thick (min_thickness).
The horizon is therefore never established from the data: FALSE
when every stack fails a criterion, NA otherwise. Until v0.9.316 any
Ap or Au of 20 cm passed.
irragric(pedon, min_thickness = 20)irragric(pedon, min_thickness = 20)
pedon |
A |
min_thickness |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Returns the acknowledgement for profiles of the ISRIC World Soil Reference Collection read through the ISIS GraphQL service, with the date they were read. ISRIC asks users to cite the data it supplies in their products, web services, papers and reports.
isis_citation(accessed = Sys.Date())isis_citation(accessed = Sys.Date())
accessed |
Date the data were read (default today). |
A character string.
isis_citation(as.Date("2026-10-29"))isis_citation(as.Date("2026-10-29"))
Builds a PedonRecord from one profile as the ISIS GraphQL
service returns it (one element of the profiles list; see
read_isis, which calls this for every profile it reads).
Laboratory values are converted to soilKey units, FAO field codes to
soilKey's words, and each value records its ISIS field in the provenance.
The site carries the WRB and USDA names ISRIC gives the profile
(reference_wrb, reference_wrb_full, reference_usda,
reference_usda_subgroup and their editions), the soil moisture and
temperature regimes and the groundwater (groundwater_kind,
groundwater_depth_cm) when ISIS records them, the licence and the
citation.
isis_profile_to_pedon( profile, absent_unless_recorded = TRUE, accessed = Sys.Date() )isis_profile_to_pedon( profile, absent_unless_recorded = TRUE, accessed = Sys.Date() )
profile |
One ISIS profile, a list as parsed from the service's JSON. |
absent_unless_recorded |
If |
accessed |
Date the data were read (default today). |
A PedonRecord.
Tests whether a profile satisfies the Kastanozem RSG criteria: a mollic horizon plus secondary carbonates plus NOT-Chernozem colour (chroma (moist) > 2 in the upper 20 cm).
kastanozem(pedon, max_chroma_upper = 2)kastanozem(pedon, max_chroma_upper = 2)
pedon |
A |
max_chroma_upper |
Maximum moist chroma to qualify as Chernozem (default 2). Kastanozem requires the upper-20-cm chroma to EXCEED this value. |
IUSS Working Group WRB (2022), Chapter 5, Kastanozems.
Same structure as chernozem_strict but using the mollic
horizon (no chernic gate) and starting \<= 70 cm of mineral soil
surface.
kastanozem_strict(pedon, min_bs = 50, max_top_cm = 70, strict = NULL)kastanozem_strict(pedon, min_bs = 50, max_top_cm = 70, strict = NULL)
pedon |
A |
min_bs |
Minimum base saturation % above the carbonate layer (default 50). |
max_top_cm |
Maximum depth of the carbonate layer below the mineral soil surface, cm (default 70). |
strict |
Logical or |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
With strict = TRUE the base-saturation floor above the
carbonate-bearing layer is raised from 50% to 75%. The 70 cm
carbonate-depth window is left unchanged.
Normalises the system-dependent decision trace carried by a
ClassificationResult into a single, ordered data frame of
display rows. WRB 2022 stores a flat list of reference-soil-group test
steps; the hierarchical SiBCS and USDA keys store a nested list of phases
(orders, suborders, great groups, subgroups, family, ...), each holding
candidate steps, an assigned-taxon record, family attributes, or a bare
label. This function walks all of those shapes and returns one row per step,
in the order the key was evaluated, so every consumer (print(), the
HTML and PDF reports, the Shiny app) can render the trace uniformly.
key_trace_table(x)key_trace_table(x)
x |
A |
A data.frame with one row per trace step and columns:
phaseKey phase / level the step belongs to (e.g.
"orders", "subgrupos"); empty for the flat WRB trace.
codeTaxon or attribute code.
nameTaxon or attribute name (or attribute value).
statusOne of "passed", "failed",
"indeterminate" (a test that could not be evaluated for want of
data), "selected" (the taxon assigned at a level), or
"info" (a family attribute or label, not a pass/fail test).
missingComma-separated attributes that were missing for the step (empty when none).
n_missingInteger count of missing attributes.
A zero-row data frame with those columns when the trace is empty.
res <- classify_sibcs(make_ferralsol_canonical()) head(key_trace_table(res))res <- classify_sibcs(make_ferralsol_canonical()) head(key_trace_table(res))
Convenience wrapper for canonical_reference("ST_criteria_13th").
Returns a nested list of 3,153 parsed Keys-to-Soil-Taxonomy clauses
per chapter / page / key / taxon / code / clause / logic.
kst13_canonical(prefer_pkg = TRUE)kst13_canonical(prefer_pkg = TRUE)
prefer_pkg |
Retained for compatibility and no longer used. Until
v0.9.203 |
Source: NCSS-tech SoilTaxonomy R package. Original:
USDA-NRCS (2022). Keys to Soil Taxonomy, 13th edition.
The canonical Keys to Soil Taxonomy (13th ed.) criteria reference (a list / data.frame).
Returns the 3,153-row data.frame from
2022_KST_codes.json in NCSS-tech/SoilKnowledgeBase (GPL-3), which
soilKey downloads on first use and caches (it ships no copy; see
clear_kst13_cache). Each row is a (code, name) pair.
kst13_codes()kst13_codes()
Code structure:
Single letter ("A"-"L"): Soil Order
(Gelisols, Histosols, ..., Entisols)
Two letters ("AB", "AC", ...): Suborder
Three letters: Great Group
Four letters: Subgroup
A data.frame with columns code, name.
kst13_criteria, kst13_canonical.
Returns the parsed clause data.frame for one code (e.g. "A"
for Gelisols, "ABA" for Histels.Folistels, etc.). Each row
is one clause of the diagnostic text with content,
chapter, page columns.
kst13_criteria(code)kst13_criteria(code)
code |
Character. Taxon code in the KST 13ed code system
(e.g. |
For the full 3,153-element nested list (all codes), use
kst13_canonical (which loads the SoilTaxonomy R-package
RDA equivalent).
A data.frame with the parsed clauses for that code, or
NULL if the code is not present.
Tests whether continuous rock or rock-like material occurs within
max_depth cm of the surface. Two alternative paths qualify
per WRB 2022:
Designation: a layer at depth <= max_depth
with designation matching "^R" or "^Cr"
(continuous rock or weathered rock-like substrate).
Coarse fragments: a layer at depth <= max_depth
with coarse_fragments_pct >= min_coarse_pct (default
90% by volume), interpreted as rock-dominated even when not
R / Cr-designated.
Either path qualifies.
leptic_features(pedon, max_depth = 25, min_coarse_pct = NULL, engine = NULL)leptic_features(pedon, max_depth = 25, min_coarse_pct = NULL, engine = NULL)
pedon |
A |
max_depth |
Maximum depth (cm) at which continuous rock or rock-dominated material must appear (default 25). |
min_coarse_pct |
Minimum coarse-fragment percent for the
coarse-fragments path (default 90 in soilkey engine, 50
in aqp engine; |
engine |
One of |
IUSS Working Group WRB (2022), Chapter 5, Leptosols.
rock_origin %in% c("lacustrine", "marine") or designation pattern.Limnic material (WRB 2022 Ch 3.3.10): subaquatic deposits (coprogenous
earth, diatomaceous earth, marl, gyttja). v0.3.3: detects via
rock_origin %in% c("lacustrine", "marine") or designation pattern.
limnic_material(pedon)limnic_material(pedon)
pedon |
A |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
From Greek leimon = meadow. A subaqueous / wet-meadow horizon showing accumulation of secondary Fe/Mn (oxi)hydroxides from fluctuating redox cycles. Distinct from limnic material (Ch 3.3.10), which is the parent material; the limonic horizon is the soil horizon derived from such material plus subsequent pedogenesis.
limonic(pedon, min_thickness = 5, min_redox_pct = 5)limonic(pedon, min_thickness = 5, min_redox_pct = 5)
pedon |
A |
min_thickness |
Numeric threshold or option (see Details). |
min_redox_pct |
Numeric threshold or option (see Details). |
v0.3.5 detection: redoximorphic_features_pct \>= 5 AND designation
pattern Bm / Bjm / m as proxy for past meadow
wetness.
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Significant abrupt change in parent material between two layers. v0.3.3 simplified: detects via large discontinuity in coarse_fragments_pct (>= 10pp absolute jump) OR rock_origin difference between consecutive layers.
lithic_discontinuity(pedon)lithic_discontinuity(pedon)
pedon |
A |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
The Lixisols of the WRB 2022 key (Ch 4, p. 120): an argic horizon starting
100 cm from the mineral soil surface and a CEC of < 24 cmolc/kg
clay in some subhorizon of the argic horizon within 150 cm. The key reaches
them after the Acrisols.
lixisol(pedon, max_cec = 24, min_bs = 50)lixisol(pedon, max_cec = 24, min_bs = 50)
pedon |
A |
max_cec |
CEC per kg clay below which the clay is of low activity (default 24). |
min_bs |
Unused since v0.9.310, kept so that existing calls still run. |
IUSS Working Group WRB (2022), Chapter 4, Lixisols (p. 120).
Reads the AfSP DBase tables shipped inside AF-AfSP1.2.zip
(downloadable from
https://files.isric.org/public/afsp/AF-AfSP1.2.zip) and
converts each profile + its horizons to a soilKey
PedonRecord. Filters to profiles with a populated
WRB 2006 RSG code (i.e.\ classifiable; AfSP has ~7000 of these of
the total 18,533).
load_afsp_pedons( afsp_dir, max_n = NULL, countries = NULL, wrb_codes = NULL, verbose = TRUE )load_afsp_pedons( afsp_dir, max_n = NULL, countries = NULL, wrb_codes = NULL, verbose = TRUE )
afsp_dir |
Directory containing the extracted AfSP DBase
tables ( |
max_n |
Optional integer; take a random sample of this size from the classifiable profiles. |
countries |
Optional character vector of ISO country codes to
keep (e.g.\ |
wrb_codes |
Optional character vector of WRB 2006 RSG codes
to keep (e.g.\ |
verbose |
Print progress. |
The structure type, grade and size are AfSP class codes (FAO-ISRIC 1990,
FAO 2006). Since v0.9.312 they are read by the AfSP dictionary
(AfSP012Qry_DictioClassValues) into soilKey's words: a range of grades
by its lower end, a range of sizes with both ends, and a code the dictionary
does not define as not recorded. Each code goes to the provenance.
A list of PedonRecord objects.
Leenaars, J. G. B., van Oostrum, A. J. M., & Ruiperez Gonzalez, M.
(2014). Africa Soil Profiles Database, Version 1.2. ISRIC Report
2014/01. ISRIC – World Soil Information, Wageningen.
Project page:
https://isric.org/projects/africa-soil-profiles-database-afsp.
Returns a 120-profile snapshot from AfSP v1.2 stratified by WRB RSG (5 profiles per RSG x 24 RSGs), pre-built so users can run the African WRB benchmark offline without the 35 MB ZIP download.
load_afsp_sample()load_afsp_sample()
This is the African analogue of
load_wosis_stratified_sample (global WoSIS) and
load_kssl_nasis_sample (US KSSL+NASIS).
The snapshot was built in v0.9.77 and holds the AfSP structure codes; since
v0.9.312 they are read into words when it is loaded, as
load_afsp_pedons reads them.
A list with pedons (the PedonRecord
objects), pulled_on, source, filter.
benchmark_afsp takes this list as it is, or its
$pedons.
Leenaars, J. G. B., van Oostrum, A. J. M., & Ruiperez Gonzalez, M. (2014). Africa Soil Profiles Database, Version 1.2. ISRIC Report 2014/01.
Reads the long-format BDsolos CSV (one row per horizon, with a
profile-id key) and returns a list of PedonRecord
objects. Auto-detects the column-name convention via
inspect_bdsolos_csv and maps to the soilKey horizon
schema. Texture (argila / silte / areia) is converted from g/kg to
percent (BDsolos canonical unit).
load_bdsolos_csv(path, sep = NULL, verbose = TRUE)load_bdsolos_csv(path, sep = NULL, verbose = TRUE)
path |
Path to the BDsolos CSV. |
sep |
Field separator. Default |
verbose |
If |
Iron (v0.9.221): "CDB - Ferro (g/kg)" (dithionite-citrate-
bicarbonate, free Fe as the element) goes to fe_dcb_pct, which
the WRB Fe-dith criteria read (nitic horizon, Ferric, Ferritic);
"Ataque sulfurico - Fe2O3" (total Fe of the sulfuric attack, as
the oxide) goes to fe2o3_sulfuric_pct, which the SiBCS
ferrico / perferrico classes read; "Oxalato de Amonio - Ferro"
goes to fe_ox_pct. All three are converted from g/kg to %.
Until v0.9.220 the sulfuric Fe2O3 filled fe_dcb_pct, unconverted.
Silica and alumina (v0.9.243): "Ataque sulfurico - SiO2" and
"- Al2O3" go to sio2_sulfuric_pct and
al2o3_sulfuric_pct, converted from g/kg to %. The Ki index
(molecular SiO2 / Al2O3), which SiBCS asks of the B latossolico, is
computed from them; it reproduces the Ki column of the export.
Text of the horizon description (v0.9.245): the column
"Descricao Original" holds the field description of each horizon
as the survey wrote it. Two things are read from it where the structured
columns are empty, and the text itself is not kept: the amount of
slickensides written beside the term ("''slickenside'' comum e
moderado" fills slickensides with "Comum"; a mention with
no amount fills nothing), and a wedge-shaped or parallelepipedic
structure ("cuneiforme", "paralelepipedica", added to
structure_type; a structure "com tendencia a paralelepipedica" is
not one). SiBCS knows the vertic horizon by these two features, and the
surveys that predate the structured sheet describe them only there.
Since v0.9.251 the amount and the grade of the cerosidade are read the
same way ("cerosidade comum e moderada" fills
clay_films_amount with "Comum" and
clay_films_strength with "Moderada"), each where its own
cell is empty.
Reading (v0.9.222): the file is read with utils::read.csv2. The
export quotes every field, and its free-text fields hold line breaks and,
in some states, quotation marks of their own; read.csv2 returns
the export's records for all 27 state files. data.table::fread,
used until v0.9.221, split such records at the line breaks (in BA, GO, PI
and RS, where the lines of text became profiles of their own) or stopped
with an error that left the next fread() of the R session waiting
forever (after DF, MT, PA, PB or SP). An empty text field is NA in
every file; a quotation mark inside a text field is dropped.
Kind of sampling point (v0.9.242): the column "Tipo" of the export
goes to site$sampling_type, as written: "Perfil completo",
"Perfil parcial" or "Amostra extra". An extra sample is, in
most cases, two sampled layers of a point (a topsoil and a subsoil sample,
often with a gap between them), not a described profile: the thickness of
its layers is that of the samples. About a third of the records of the
national export are extra samples; benchmark_bdsolos
reports the kinds apart.
Profile-id columns are auto-detected: looks for any column whose
normalised name matches
"id_perfil|profile_id|cod_perfil|^perfil$|sample_id|^id$";
falls back to the first column when none match.
A list of PedonRecord objects. Each pedon
has site$id from the profile-id column, the
taxonomic reference (when present) at
site$reference_sibcs, and one horizon row per CSV
row matching the profile id.
inspect_bdsolos_csv,
download_bdsolos.
Reads the Embrapa BDsolos CSV export (or the dadosolos R package
data frame, if present). Assembles a list of PedonRecord
objects with the SiBCS classification attached as
pedon$site$reference_sibcs.
load_embrapa_pedons(csv_path, head = NULL, verbose = TRUE)load_embrapa_pedons(csv_path, head = NULL, verbose = TRUE)
csv_path |
Path to the BDsolos CSV (long format: one row per horizon, with a profile-id key and per-profile classification). |
head |
Optional integer for parser validation. |
verbose |
If |
The dadosolos / BDsolos archive ships with ~5k profiles in PT-BR
with full SiBCS classification, lab data, and horizon morphology –
the primary validation set for Brazilian-context use. Available
from https://www.bdsolos.cnptia.embrapa.br/.
A list of PedonRecord objects.
Reads the FEBR febr-superconjunto.txt export (one row per
camada / horizon, with the profile-level classification denormalised
onto every row), groups rows by (dataset_id, observacao_id),
and returns a list of PedonRecord objects with all
three reference taxa attached on $site: reference_sibcs
(raw FEBR string, e.g. "LATOSSOLO VERMELHO"),
reference_usda, reference_wrb.
load_febr_pedons( path, head = NULL, require_classification = c("sibcs", "any", "wrb", "usda"), verbose = TRUE )load_febr_pedons( path, head = NULL, require_classification = c("sibcs", "any", "wrb", "usda"), verbose = TRUE )
path |
Path to |
head |
Optional integer; if not |
require_classification |
One of |
verbose |
If |
Drops profiles whose taxon_sibcs is NA (no usable reference).
Drops camadas with no horizon-depth information (no
profund_sup / profund_inf).
A list of PedonRecord objects.
Returns a 99-profile snapshot built by joining the NCSS Lab Data
Mart (ncss_labdata.gpkg) with the companion NASIS
Morphological sqlite (NASIS_Morphological_*.sqlite) via
load_kssl_pedons_with_nasis. Pre-annotated with
derived WRB Reference Soil Group via usda_to_wrb_rsg.
load_kssl_nasis_sample()load_kssl_nasis_sample()
Compared to load_kssl_sample (KSSL lab tables only),
this sample carries the morphological evidence that several WRB
diagnostic horizons need:
| Field | KSSL-only | KSSL + NASIS | |——-|———-:|————-:| | munsell_hue_moist | 0 | munsell_value_moist | 0 | munsell_chroma_moist | 0 | munsell_hue_dry | 0 | structure_grade | 0 | structure_type | 0 | clay_films_amount | 0 | slickensides | 0
First-ever benchmark on this enriched sample (soilKey v0.9.75, full v0.9.69-72 fallback stack):
Top-1 baseline: 19.1\ **+3.5pp lift purely from NASIS morphology**)
Top-1 full stack: 20.6\
Phaeozem: 1/33 -> 2/33 (Munsell-driven mollic detection)
Podzol: 0/15 -> 1/15
Remaining ceiling driven by attributes neither dataset preserves: Solonetz needs Na/ESP, Vertisols need slickensides + cracks (NASIS records 1.7 on subsoil samples NASIS often lacks.
A list with pedons, pulled_on, source,
join_helper, cross_walk.
Beaudette, D., Skovlin, J., Roecker, S., Brown, A. (2024). aqp:
Algorithms for Quantitative Pedology. R package version 2.x.
https://github.com/ncss-tech/aqp.
## Not run: s <- load_kssl_nasis_sample() length(s$pedons) #> 99 # Munsell now populated (KSSL-only sample had 0%): mean(vapply(s$pedons, function(p) any(!is.na(p$horizons$munsell_hue_moist)), logical(1))) #> 0.99 ## End(Not run)## Not run: s <- load_kssl_nasis_sample() length(s$pedons) #> 99 # Munsell now populated (KSSL-only sample had 0%): mean(vapply(s$pedons, function(p) any(!is.na(p$horizons$munsell_hue_moist)), logical(1))) #> 0.99 ## End(Not run)
Reads the KSSL pedon CSV export (typically named
NCSS_Pedon_Layer.csv or similar) plus the lab-data CSV, joins
on pedon_key, and assembles a list of PedonRecord
objects. The published USDA Soil Taxonomy classification (from the
Series or Subgroup field) is attached as
pedon$site$reference_usda.
load_kssl_pedons(pedon_csv, layer_csv, head = NULL, verbose = TRUE)load_kssl_pedons(pedon_csv, layer_csv, head = NULL, verbose = TRUE)
pedon_csv |
Path to the pedon-level CSV (one row per profile, with site-level metadata + classification). |
layer_csv |
Path to the layer-level CSV (one row per horizon, with horizon properties). |
head |
Optional integer; if not |
verbose |
If |
KSSL is the de-facto standard for validating USDA Soil Taxonomy keys
(~50k profiles, lab-grade analytical data, professional pedon
descriptions). Get the export from the USDA-NRCS NCSS Lab Data Mart
(ncsslabdatamart.sc.egov.usda.gov).
A list of PedonRecord objects.
Reads the 'lab_combine_nasis_ncss' / 'lab_site' / 'lab_layer' /
'lab_chemical_properties' / 'lab_physical_properties' views from
the NCSS Lab Data Mart GeoPackage and assembles a list of
PedonRecord objects. Each pedon has its USDA Soil
Taxonomy Order attached as site$reference_usda, normalised
to match 'classify_usda()' output ("Mollisols", "Alfisols", ...).
load_kssl_pedons_gpkg( gpkg, head = NULL, require_b_horizon = TRUE, verbose = TRUE )load_kssl_pedons_gpkg( gpkg, head = NULL, require_b_horizon = TRUE, verbose = TRUE )
gpkg |
Path to |
head |
Optional integer; load only the first N classified pedons. Useful for parser validation. |
require_b_horizon |
If |
verbose |
If |
A list of PedonRecord objects.
Joins the NCSS Lab Data Mart GeoPackage with the NASIS
Morphological SQLite to produce PedonRecord objects whose horizons
table has BOTH lab chemistry + physics AND field morphology
(Munsell, structure, clay films, slickensides, cracks). Required
for the morphological-evidence diagnostics
(argic clay-films, vertic_horizon
slickensides, mollic_epipedon_usda Munsell, etc.) to
fire on KSSL profiles – the lab gpkg alone has none of those.
load_kssl_pedons_with_nasis( gpkg, sqlite, head = NULL, require_b_horizon = TRUE, verbose = TRUE )load_kssl_pedons_with_nasis( gpkg, sqlite, head = NULL, require_b_horizon = TRUE, verbose = TRUE )
gpkg |
Path to |
sqlite |
Path to |
head |
Optional integer; load only the first N classified pedons. Useful for parser validation / scaling. |
require_b_horizon |
If |
verbose |
If |
A list of PedonRecord objects.
Returns a 100-profile snapshot from the NCSS Lab Data Mart
(KSSL gpkg, head = 100) pre-annotated with derived WRB
Reference Soil Group via usda_to_wrb_rsg.
load_kssl_sample()load_kssl_sample()
This is the bundled offline counterpart to
load_kssl_pedons_gpkg – use this for tests and
demos when the 5.5 GB gpkg is not available locally.
Each pedon has BOTH:
site$reference_usda (Order, Suborder, Greatgroup,
Subgroup) – the canonical KSSL classification.
site$reference_wrb_from_usda – the derived WRB
RSG via the IUSS WRB 2022 Annex 6 cross-walk.
First-ever KSSL WRB benchmark (soilKey v0.9.74, full v0.9.69-72 fallback stack):
Top-1 accuracy: 20.1\
Calcisol 69\
Phaeozem / Kastanozem / Solonetz 0\ data not in KSSL lab tables (in companion NASIS).
A list with pedons, pulled_on, source,
cross_walk.
Beaudette, D., Skovlin, J., Roecker, S., Brown, A. (2024). aqp:
Algorithms for Quantitative Pedology. R package version 2.x.
https://github.com/ncss-tech/aqp.
## Not run: s <- load_kssl_sample() length(s$pedons) #> 100 table(vapply(s$pedons, function(p) p$site$reference_wrb_from_usda, character(1))) ## End(Not run)## Not run: s <- load_kssl_sample() length(s$pedons) #> 100 table(vapply(s$pedons, function(p) p$site$reference_wrb_from_usda, character(1))) ## End(Not run)
Reads the EU-LUCAS topsoil dataset joined with the ESDB profile
archive (the v3 release produced by JRC). Assembles a list of
PedonRecord objects with the WRB Reference Soil Group
attached as pedon$site$reference_wrb.
load_lucas_pedons(lucas_csv, head = NULL, verbose = TRUE)load_lucas_pedons(lucas_csv, head = NULL, verbose = TRUE)
lucas_csv |
Path to the LUCAS topsoil CSV. |
head |
Optional integer for parser validation. |
verbose |
If |
LUCAS is harvested every 3-6 years on a regular grid; the ESDB classification is updated synchronously. ~28k profile cells with WRB labels in the 2015-2018 release.
A list of PedonRecord objects.
Reads the canonical European Soil Data Centre (ESDAC) release of
LUCAS Soil 2018 Topsoil chemistry as published in the JRC report
(ESDAC dataset
https://esdac.jrc.ec.europa.eu/content/lucas-2018-topsoil-data).
The release ships ~18,984 European topsoil samples at 0-20 cm with
pH (H2O and CaCl2), EC, OC, CaCO3, P, N, K and oxalate-extractable
Al / Fe; a separate BulkDensity_2018_final-2.csv carries
bulk density at 0-10 / 10-20 / 20-30 / 0-20 cm for ~6,272 of those
points and is joined automatically when present.
load_lucas_soil_2018( path, attach_bulk_density = TRUE, countries = NULL, max_n = NULL, verbose = TRUE )load_lucas_soil_2018( path, attach_bulk_density = TRUE, countries = NULL, max_n = NULL, verbose = TRUE )
path |
Folder containing |
attach_bulk_density |
If |
countries |
Optional character vector of NUTS_0 codes
(e.g. |
max_n |
Optional integer cap on the number of pedons returned (after country filter). Useful for development. |
verbose |
If |
What's NOT in the release (and how to fill it):
Texture (clay / sand / silt) – not in this CSV.
Pass benchmark_lucas_2018(..., fill_texture_from =
"soilgrids") to fill from ISRIC SoilGrids 250m via
lookup_soilgrids.
Munsell colors – not collected by LUCAS Soil 2018.
If the user has Vis-NIR spectra (release separate ~83 GB),
use predict_munsell_from_spectra (v0.9.47).
Vis-NIR spectra – distributed separately by ESDAC.
Once downloaded and attached to the pedon's $spectra,
predict_from_spectra (v0.9.46) fills clay /
sand / silt / pH / OC / CEC.
Taxonomic reference – not in the LUCAS release;
benchmark_lucas_2018 attaches the canonical
WRB Reference Soil Group via lookup_esdb
(v0.9.44) at the pedon's coordinates.
Unit conversions applied (LUCAS -> soilKey schema):
OC, N, CaCO3, Ox_Al, Ox_Fe: g/kg ->
EC: mS/m -> dS/m (* 0.01)
P, K: mg/kg unchanged
pH: unitless
Special LUCAS string values "< LOD", "<LOD", empty
cells and "n.d." / "ND" are converted to NA
before numeric coercion.
A list of PedonRecord objects (one per LUCAS
point). Each pedon has a site$id matching the LUCAS
POINTID, site$lat / site$lon in WGS84,
and either one or two horizons (the second being 20-30 cm
when the subsoil OC / CaCO3 columns are populated).
Provenance entries from the loader use
source = "measured".
benchmark_lucas_2018,
lookup_esdb,
lookup_soilgrids.
## Not run: path <- "soil_data/eu_lucas/LUCAS-SOIL-2018-data-report-readme-v2/LUCAS-SOIL-2018-v2" pedons <- load_lucas_soil_2018(path, countries = c("ES", "PT"), max_n = 100) length(pedons) pedons[[1]] ## End(Not run)## Not run: path <- "soil_data/eu_lucas/LUCAS-SOIL-2018-data-report-readme-v2/LUCAS-SOIL-2018-v2" pedons <- load_lucas_soil_2018(path, countries = c("ES", "PT"), max_n = 100) length(pedons) pedons[[1]] ## End(Not run)
Turns the profile files saved by fetch_natsoil (or any JSON
of the NatSoil API with horizons, samples and laboratory results) into
PedonRecord objects for classify_asc3 and the
other keys. Sites whose licence does not allow external use are left out.
load_natsoil_pedons( path, classified_only = TRUE, max_n = NULL, seed = NULL, verbose = TRUE )load_natsoil_pedons( path, classified_only = TRUE, max_n = NULL, seed = NULL, verbose = TRUE )
path |
A folder (searched recursively for |
classified_only |
Keep only sites with an ASC order. |
max_n |
Optional maximum number of files read (a random sample;
a profile file of |
seed |
Optional seed for that sample. |
verbose |
Print a summary. |
The horizons keep their designation in the Australian notation (lithologic prefix, master, subdivision and suffixes), depths in cm, the field texture grade, boundary distinctness and shape, the grade and type of the first structure (lenticular when any structure is), the moist and the dry matrix colours (a colour with no moisture status is read as moist), slickensides, crack width, coarse fragments (abundance classes at their middle, added up to at most 100 %; unknown when a record has no abundance), calcareous segregations (a record with only its nature is a template and is not read; one with a form or size but no abundance counts as very few, 1 %), cementation of pans, effervescence, plasticity type and the moisture when described.
Laboratory results are matched to the horizons by depth: a sample counts
for the horizon it is filed under where they overlap, and for another one
when it lies mostly within it, weighed by the overlap (a sample with no
usable depth counts for the horizon it is filed under). Codes are matched
whatever their case, the "not recorded" methods included. A value below
the detection limit, written "<x", is read as half the limit, unless the
limit lies above a limit the keys read for that property (0.5 % CaCO3,
0.18 cmol/kg Na, an ESP of 6, 5 % free Fe, 12 % organic C, 10 % clay),
where the value is unknown and the next method is tried. pH in water is
the lab 1:5 value (method 4A1, or a pH whose method is not recorded, often
the field pH itself); the field pH is used only where the lab has no pH
at all. Organic C is the measured value, or an uncorrected Walkley-Black
value times 1.3; half the loss on ignition only in peat (an O or P
horizon, or a peat field texture). Exchangeable bases and CEC are read
whatever the extraction method; a laboratory ESP is kept as
esp_pct. Free iron is read only from dithionite extractions; most
profiles have none, which leaves the Ferrosols undecided.
The site keeps the surveyors' classification
(reference_asc_order, reference_asc_suborder,
reference_asc_great_group, reference_asc_subgroup, the
confidence reference_asc_confidence), the drainage class, the
landform pattern and element (landform, landform_element),
the surface condition, the microrelief, coordinates (GDA94), the licence
and the citation. Mottles (not biological or mechanical mixing, nor
substrate inclusions) give redoximorphic_features_pct (abundance
classes at their middle, added up) and mottle_contrast (the
strongest, faint when distinct and prominent ones are 10 % or less on
their own and faint ones make up the rest); calcareous segregations and
calcrete fragments give carbonate_soft_pct (soft segregations, root
linings, tubules, veins and crystals) and carbonate_hard_pct
(nodules, concretions, fragments and laminae, and calcrete coarse
fragments), kept only where what is recorded leaves the amount within one
carbonate class of the ASC glossary (a segregation of unknown form may be
soft or hard, a fragment of unknown lithology calcrete; coarse fragments
not recorded count as none; segregations not recorded leave the soft
amount unknown, and the hard one unless calcrete alone exceeds 50 %).
Ferruginous and bauxite nodules give ferric_nodules_pct and
bauxitic_nodules_pct; since 0.9.285 manganiferous nodules give
manganiferous_nodules_pct, and gypseous and saline segregations
gypsum_visible_pct and halite_visible_pct. Only what is
recorded counts (a segregation of unrecorded nature or form is not one of
them); the amount is NA when no segregation is recorded, and NaN when the
recorded classes leave it on either side of 20 % (50 % for halite),
which the key reads as undecided. Abundance classes of several
records are added as ranges (each class strictly between its limits).
Laboratory EC of a 1:5 extract gives ec_1to5_dS_m; the soil
strength gives strength_dry or strength_moist by the moisture
of its record; the size class of the first structure gives
ped_size_max_mm. Since 0.9.292, for the families: gravel_pct
(the coarse fragments of a gravel size class, 2-60 mm, or of no size
recorded; NaN, unknown, when such a record has no abundance),
water_repellence, and at the site the coarse fragments of the
ground surface (surface_coarse_fragments_pct, all sizes, and
surface_gravel_pct; NA when none is recorded, NaN when a record has
no abundance) and the surveyors' family codes by position
(reference_asc_family, "B;E;M;O;V").
A named list of PedonRecord objects (names are
agency_project_site).
CSIRO. CSIRO National Soil Site Database (NatSoil). https://doi.org/10.25919/sg5w-ny87
fetch_natsoil, benchmark_natsoil.
Reads the pre-packaged CSV files of the National Pedon Database (NPDB,
version 3, Agriculture and Agri-Food Canada, CanSIS) into
PedonRecord objects, with the survey's classification under
the Canadian System of Soil Classification as the reference.
load_npdb_pedons(dir, max_n = NULL, seed = NULL, verbose = TRUE)load_npdb_pedons(dir, max_n = NULL, seed = NULL, verbose = TRUE)
dir |
Folder with the NPDB CSV files. |
max_n |
Optional maximum number of pedons (a random sample). |
seed |
Optional seed for that sample. |
verbose |
Print progress. |
The NPDB is not distributed with soilKey. It is published on the Open
Government Portal of Canada under the Open Government Licence - Canada
(dataset "National Pedon Database"); download the pre-packaged CSV files
and unzip them into a folder. Info.csv and Horizons.csv are
required; Morphology.csv, Physical.csv,
Chemical.csv and Profiles.csv are read when present.
What the reader does with the records:
records are split on CR-LF only, since some fields hold a lone carriage return ("subangular\r blocky");
the designation is rebuilt in the Canadian notation from its parts
(lithologic numeral, master, suffixes, numeric modifier: "IICk1"), and
the site declares designation_system = "cssc";
depths: organic and water horizons recorded upward from the
mineral surface (top above bottom) become negative depths; a mineral
horizon with its depths reversed or negative keeps |top| with no bottom
when it is the deepest layer, and no depths otherwise; a missing top is
taken from the layer above; every profile is shifted to begin at 0
cm, and site$npdb_depth_order_mismatch flags profiles whose
depth order differs from the order of their layers;
colours: the codes ("100yr4030", "10yr2010", "025y 4020",
"10.0yr4.0/3.0", "n 50") are read with hue numbers above 0 and up to
10; of the two matrix colours, the one that is never darker within a
profile (and lighter at least once) is read as the dry colour and the
other as the moist one; when they do not separate, COLOUR_1 is
read as the moist colour and no dry colour is read;
total N: the value 9 (a no-data code) and a value repeated over three or more horizons are not read; the units are told apart by the median C:N of each pedon (of its dataset when the pedon has too few values): 5 to 40 is read as percent, 0.5 to 4 as g/kg (divided by 10), anything else is not read; a horizon whose C:N then lies outside 3 to 60 is not read either;
base saturation: computed from the exchangeable bases and the CEC (at most 100 %) when they are recorded, the recorded value being kept when it agrees with it (one dataset records something else in that column);
pH: a dataset whose pH in CaCl2 is mostly above its pH in water has the two columns swapped back;
values outside their possible range are not read;
the survey's order, great group and subgroup words are turned into
the names of the 3rd edition (1998) where they match one
(reference_cssc_order, reference_cssc_great_group,
reference_cssc_subgroup), including the subgroups the 1998
edition merged (Solodic into Solonetzic); names of earlier editions
with no 1998 equivalent are left out, and the raw words are kept in
reference_cssc_raw.
The NPDB records no soil climate (mean annual soil temperature, moisture
subclass), the chemistry of the podzolic B (pyrophosphate-extractable Fe
and Al) or the contrast of mottles. The Chernozemic order and the Gray
Brown Luvisols, which ask for the climate, are undecided on these records
(see benchmark_npdb).
A named list of PedonRecord objects (names are the
NPDB PEDON_ID).
Agriculture and Agri-Food Canada (2021). National Pedon Database, version 3. Open Government Portal, Open Government Licence - Canada.
## Not run: peds <- load_npdb_pedons("path/to/npdb_v3_csv") b <- benchmark_npdb(peds, level = "order") b$accuracy ## End(Not run)## Not run: peds <- load_npdb_pedons("path/to/npdb_v3_csv") b <- benchmark_npdb(peds, level = "order") b$accuracy ## End(Not run)
Reads the structured JSON files (one profile per file) published
by Vaz et al. 2023 at the Embrapa Redape repository (DOI
10.48432/PYKKA7) and converts each one to a soilKey
PedonRecord.
load_redape_pedons(json_dir, max_n = NULL, verbose = TRUE)load_redape_pedons(json_dir, max_n = NULL, verbose = TRUE)
json_dir |
Directory containing the GeoTab JSON files (or a character vector of file paths). |
max_n |
If non- |
verbose |
Print progress (default |
The dataset is unique in two ways:
Every profile was hand-reviewed by experienced pedologists (the curation note and author list are preserved on each pedon site record), so it is suitable as a gold-standard benchmark.
Unlike BDsolos, all profiles ship the full exchange complex
(Ca, Mg, K, Na, Al and H), so cec_cmol
(Valor T = S + H + Al) is computed directly without any
fallback option.
A list of PedonRecord objects.
Vaz, G. J., Silva Jr, A. F., & Silva Neto, L. de F. da (2023). Brazilian soil data for taxonomic classification. Redape, V1. doi:10.48432/PYKKA7.
download_redape_dataset,
benchmark_redape.
Load a soilKey rule set (YAML)
load_rules(system = "wrb2022", package = "soilKey")load_rules(system = "wrb2022", package = "soilKey")
system |
Id of a registered classification system (see
|
package |
Package owning the rule files (default |
A parsed YAML list with elements version,
source, and a system-specific taxa list
(rsgs, orders, or ordens), with the lists
of the lower levels read from their folders and, where a level
file has one, its <level>_from block (classes whose list
at that level is taken from another class of the top level).
Returns a 40-profile snapshot of WoSIS GraphQL data pulled on
2026-05-03 with continent = "South America". The data is a
frozen artefact – do NOT use it for current paper-grade
benchmarks (the WoSIS database is updated periodically; the bundled
snapshot is for reproducible tests and offline development only).
load_wosis_sample()load_wosis_sample()
For up-to-date benchmarks, call run_wosis_benchmark_graphql()
directly against the live ISRIC GraphQL endpoint.
A list as described above.
A list with elements:
profiles_raw – the parsed GraphQL response (one
element per profile; nested layer arrays).
pedons – PedonRecord objects ready for
classification (one per profile).
pulled_on – Date of the snapshot.
endpoint, filter, n_pulled – metadata.
## Not run: sample <- load_wosis_sample() length(sample$pedons) #> 40 classify_wrb2022(sample$pedons[[1]])$rsg_or_order ## End(Not run)## Not run: sample <- load_wosis_sample() length(sample$pedons) #> 40 classify_wrb2022(sample$pedons[[1]])$rsg_or_order ## End(Not run)
Returns a 130-profile snapshot of WoSIS GraphQL data pulled on 2026-05-09 with **stratified sampling by WRB Reference Soil Group**: 5 profiles per RSG across 26 RSGs (Acrisol, Andosol, Arenosol, Calcisol, Cambisol, Chernozem, Cryosol, Ferralsol, Fluvisol, Gleysol, Gypsisol, Histosol, Kastanozem, Leptosol, Luvisol, Nitisol, Phaeozem, Planosol, Plinthosol, Podzol, Regosol, Solonchak, Solonetz, Stagnosol, Umbrisol, Vertisol).
load_wosis_stratified_sample()load_wosis_stratified_sample()
This is the recommended cache for global WRB benchmarking. Compared
to load_wosis_sample() (40 SA-only profiles, mostly Solonetz
and Phaeozem from Argentina), the stratified sample provides:
Even coverage across the 26 most important RSGs.
Richer analytical attributes – CEC available on 26 ECEC on 37 in the SA snapshot).
Geographic diversity (Angola, Brazil, USA, China, Russia, South Africa, Indonesia, Argentina, etc.).
First-ever benchmark on this sample (soilKey v0.9.73, full v0.9.69-72 fallback stack):
Overall top-1 accuracy: 16.2\
Histosol 100\ from 20\ Cambisol 60\
18 RSGs at 0\ expose (Munsell colours, base saturation, sodium for Solonetz, slickensides for Vertisols, etc.). Documented data ceiling.
For the live API, call run_wosis_benchmark_graphql() or
the read_wosis_profiles_graphql(wrb_rsg = "...", n_max = N)
helper (small RSG-filtered queries are tractable; large unfiltered
pulls time out as of 2026-05).
A list with:
pedons: list of 130 PedonRecord objects.
meta: named integer vector of profiles per RSG.
pulled_on: pull date.
endpoint: ISRIC GraphQL endpoint URL.
filter: pull strategy metadata.
n_pulled: 130.
Batjes, N. H., Ribeiro, E., van Oostrum, A. (2020). Standardised soil profile data to support global mapping and modelling (WoSIS snapshot 2019). Earth System Science Data, 12, 299-320. doi:10.5194/essd-12-299-2020.
## Not run: s <- load_wosis_stratified_sample() length(s$pedons) #> 130 table(vapply(s$pedons, function(p) p$site$wosis_rsg, character(1))) #> 5 of each: Acrisol, Andosol, ... Vertisol ## End(Not run)## Not run: s <- load_wosis_stratified_sample() length(s$pedons) #> 130 table(vapply(s$pedons, function(p) p$site$wosis_rsg, character(1))) #> 5 of each: Acrisol, Andosol, ... Vertisol ## End(Not run)
Loads the requested attribute raster, reprojects WGS84 lat/lon input to the raster's native CRS (typically LAEA Europe, EPSG:3035), and extracts the value(s). When a Value Attribute Table ('.vat.dbf') is available, the integer raster value is decoded to its coded string (e.g. '21' -> '"LV"' -> Luvisol).
lookup_esdb(coords, attribute, raster_root, decode = TRUE)lookup_esdb(coords, attribute, raster_root, decode = TRUE)
coords |
A two-column matrix or data.frame with 'lon' and
'lat' (WGS84 decimal degrees) – in that order. A single
|
attribute |
Name of the ESDB attribute folder, e.g.
|
raster_root |
Path to the unpacked ESDB raster directory. |
decode |
If |
Coordinates outside the European raster footprint return 'NA' silently (rather than erroring) so vectorised calls degrade gracefully.
Character vector (decoded codes) or numeric vector (raw
values) of the same length as nrow(coords).
NA for points outside the raster footprint.
## Not run: root <- "~/data/ESDB-Raster-Library-1k-GeoTIFF-20240507" # Single point: Wageningen, Netherlands (5.66 E, 51.97 N) lookup_esdb(c(5.66, 51.97), "WRBLV1", root) #> [1] "GL" # Gleysol per the ESDB 1km raster # Vector: Lisbon + Berlin + Helsinki coords <- rbind(c(-9.14, 38.72), c(13.40, 52.52), c(24.94, 60.17)) lookup_esdb(coords, "WRBLV1", root) #> [1] "CM" "LV" "PZ" # Cambisol, Luvisol, Podzol ## End(Not run)## Not run: root <- "~/data/ESDB-Raster-Library-1k-GeoTIFF-20240507" # Single point: Wageningen, Netherlands (5.66 E, 51.97 N) lookup_esdb(c(5.66, 51.97), "WRBLV1", root) #> [1] "GL" # Gleysol per the ESDB 1km raster # Vector: Lisbon + Berlin + Helsinki coords <- rbind(c(-9.14, 38.72), c(13.40, 52.52), c(24.94, 60.17)) lookup_esdb(coords, "WRBLV1", root) #> [1] "CM" "LV" "PZ" # Cambisol, Luvisol, Podzol ## End(Not run)
MapBiomas Solos (Project MapBiomas, Brazil) distributes a national
raster of SiBCS classes at 30 m, downloadable from
https://mapbiomas.org/en/produtos. This helper mirrors the
shape of lookup_esdb but is local-file only: pass
the path of the unpacked GeoTIFF and the function reprojects the
user's WGS84 lat/lon to the raster's native CRS, extracts the
pixel and (optionally) decodes the integer class code via a
user-supplied legend.
lookup_mapbiomas_solos(coords, raster_path, legend = NULL)lookup_mapbiomas_solos(coords, raster_path, legend = NULL)
coords |
A 2-column matrix or data.frame with |
raster_path |
Path to the unpacked MapBiomas Solos GeoTIFF. |
legend |
Optional two-column data.frame
(first column = numeric value, second = SiBCS class name).
When provided, the integer raster value is decoded; when
|
MapBiomas does not bundle a '.vat.dbf'; the canonical legend is
published as a CSV / dictionary on their website. Pass it via
legend as a two-column data.frame
(value, class_name) to enable decoding.
Character vector of decoded class names (when
legend is supplied) or numeric vector of raster
values. Same length as nrow(coords). NA
for points outside the raster footprint.
lookup_esdb, lookup_soilgrids.
## Not run: tif <- "~/data/mapbiomas_solos_collection2_2023.tif" legend <- data.frame( value = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L), class_name = c("Latossolo Vermelho-Amarelo", "Latossolo Amarelo", "Argissolo Vermelho-Amarelo", "Argissolo Amarelo", "Neossolo Quartzarenico", "Cambissolo Haplico", "Espodossolo", "Gleissolo", "Nitossolo", "Planossolo", "Plintossolo", "Vertisolo", "Outros") ) lookup_mapbiomas_solos(c(-43.0, -22.0), tif, legend) ## End(Not run)## Not run: tif <- "~/data/mapbiomas_solos_collection2_2023.tif" legend <- data.frame( value = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L), class_name = c("Latossolo Vermelho-Amarelo", "Latossolo Amarelo", "Argissolo Vermelho-Amarelo", "Argissolo Amarelo", "Neossolo Quartzarenico", "Cambissolo Haplico", "Espodossolo", "Gleissolo", "Nitossolo", "Planossolo", "Plintossolo", "Vertisolo", "Outros") ) lookup_mapbiomas_solos(c(-43.0, -22.0), tif, legend) ## End(Not run)
Reads ISRIC SoilGrids 250m (Hengl et al. 2017, 2021) directly
from the ISRIC Cloud-Optimized GeoTIFF (COG) endpoint at
https://files.isric.org/soilgrids/latest/data/ – no
download required, only the pixel under each query coordinate is
transferred over HTTPS.
lookup_soilgrids( coords, property = c("clay", "sand", "silt", "phh2o", "soc", "cec", "bdod", "nitrogen", "ocd", "ocs", "cfvo"), depth = c("0-5cm", "5-15cm", "15-30cm", "30-60cm", "60-100cm", "100-200cm"), quantile = c("mean", "Q0.05", "Q0.5", "Q0.95", "uncertainty"), baseurl = "https://files.isric.org/soilgrids/latest/data", raw = FALSE )lookup_soilgrids( coords, property = c("clay", "sand", "silt", "phh2o", "soc", "cec", "bdod", "nitrogen", "ocd", "ocs", "cfvo"), depth = c("0-5cm", "5-15cm", "15-30cm", "30-60cm", "60-100cm", "100-200cm"), quantile = c("mean", "Q0.05", "Q0.5", "Q0.95", "uncertainty"), baseurl = "https://files.isric.org/soilgrids/latest/data", raw = FALSE )
coords |
A 2-column matrix or data.frame with |
property |
One of the SoilGrids 250m predicted properties:
|
depth |
Depth interval. One of |
quantile |
Output quantile. One of |
baseurl |
Base URL of the SoilGrids COG endpoint. Default is the canonical ISRIC location; override only for a local mirror. |
raw |
If |
SoilGrids stores integer rasters scaled per property; this helper applies the canonical conversion factor so the returned value is in conventional soil units (%, pH, g/kg, cmol(c)/kg, g/cm^3).
Numeric vector of length nrow(coords). NA
outside the SoilGrids footprint or on network errors.
lookup_esdb,
lookup_mapbiomas_solos.
## Not run: # Single point lookup_soilgrids(c(-43.0, -22.0), property = "phh2o", depth = "0-5cm", quantile = "mean") # Vector + multiple properties coords <- rbind(c(-43.0, -22.0), c( -9.14, 38.72)) lookup_soilgrids(coords, "clay", "0-5cm", "mean") lookup_soilgrids(coords, "phh2o", "0-5cm", "mean") ## End(Not run)## Not run: # Single point lookup_soilgrids(c(-43.0, -22.0), property = "phh2o", depth = "0-5cm", quantile = "mean") # Vector + multiple properties coords <- rbind(c(-43.0, -22.0), c( -9.14, 38.72)) lookup_soilgrids(coords, "clay", "0-5cm", "mean") lookup_soilgrids(coords, "phh2o", "0-5cm", "mean") ## End(Not run)
The Luvisols of the WRB 2022 key (Ch 4, p. 122): "Other soils having an
argic horizon starting 100 cm from the mineral soil surface".
luvisol(pedon, min_cec = 24, max_al_sat = 50)luvisol(pedon, min_cec = 24, max_al_sat = 50)
pedon |
A |
min_cec, max_al_sat
|
Unused since v0.9.310, kept so that existing calls still run. |
IUSS Working Group WRB (2022), Chapter 4, Luvisols (p. 122).
Synthetic tropical-humid Acrisol on weathered gneiss: argic horizon at Bt1 with low-activity clay (CEC/clay ~ 17 cmol_c/kg clay) and low base saturation (BS ~ 25%). v0.9.310: in Bt1 and Bt2 the exchangeable Al (0.4 until then) exceeds the exchangeable bases (lowered from 1.15 to 0.72 cmolc/kg, so that the ECEC stays below 6 cmolc/kg clay, Geric), as the WRB 2022 Acrisols ask for in 50-100 cm (Ch 4, p. 119); with Al below the bases the profile is a Lixisol. By construction:
make_acrisol_canonical()make_acrisol_canonical()
A PedonRecord.
Synthetic humid-tropical Alisol on weathered shale: argic horizon at Bt1 with high-activity clay (CEC/clay ~ 34) AND high Al saturation (Al sat ~ 70%); the canonical "young weathering on a 2:1 clay parent that has not yet released enough Al into the precipitate-stabilised pool". By construction:
make_alisol_canonical()make_alisol_canonical()
A PedonRecord.
Synthetic Andosol on volcanic tephra: very dark surface with low
bulk density (0.7 g/cm^3) and high active Al + Fe (Al_ox + 0.5 *
Fe_ox = 2.25%). By construction andic_properties
passes.
make_andosol_canonical()make_andosol_canonical()
A PedonRecord.
Synthetic Anthrosol with a hortic horizon – a long-cultivated dark
surface from sustained organic-matter additions (typical of
centuries-old kitchen-garden / homegarden soils). By construction
anthric_horizons passes via the designation pattern.
make_anthrosol_canonical()make_anthrosol_canonical()
A PedonRecord.
Synthetic coastal-dune Arenosol: sandy throughout the upper 100 cm
(silt + 2*clay << 30). By construction arenic_texture
passes uniformly while every clay-dependent diagnostic fails.
make_arenosol_canonical()make_arenosol_canonical()
A PedonRecord.
B textural com gradiente significativo, argila ativ baixa ou alta + V baixa. Catch-all final na chave – tipica do Brasil tropical.
make_argissolo_canonical()make_argissolo_canonical()
A PedonRecord populated with the canonical horizons and site metadata for this reference profile.
Small, plausible profiles written for the tests and examples, one per order of the Australian Soil Classification, with designations in the Australian notation (Field Handbook), field textures and the properties the order key reads. They are not real profiles.
make_asc3_example( order = c("anthroposols", "organosols", "podosols", "vertosols", "hydrosols", "kurosols", "sodosols", "chromosols", "calcarosols", "ferrosols", "dermosols", "kandosols", "arenosols", "rudosols", "tenosols") )make_asc3_example( order = c("anthroposols", "organosols", "podosols", "vertosols", "hydrosols", "kurosols", "sodosols", "chromosols", "calcarosols", "ferrosols", "dermosols", "kandosols", "arenosols", "rudosols", "tenosols") )
order |
One of the 15 orders, in lower case and plural:
|
A PedonRecord.
p <- make_asc3_example("kandosols") p$horizons[, c("designation", "top_cm", "bottom_cm", "field_texture")]p <- make_asc3_example("kandosols") p$horizons[, c("designation", "top_cm", "bottom_cm", "field_texture")]
Synthetic semi-arid Calcisol on calcareous loess: A horizon with modest secondary carbonate; a thick Bk1 with the diagnostic calcic horizon (35% CaCO3 over 40 cm); deepening accumulation in Bk2. By construction:
make_calcisol_canonical()make_calcisol_canonical()
A PedonRecord.
Synthetic temperate-zone Cambisol on weathered colluvium: modest subsurface alteration in Bw without meeting argic clay-increase or ferralic CEC criteria. By construction:
cambic: PASSES on Bw (thickness 35 cm, sandy
clay loam, no argic / no ferralic).
make_cambisol_canonical()make_cambisol_canonical()
A PedonRecord.
Reusa fixture WRB Cambisol – B incipiente sem ser plintico, vertico, planico, etc.
make_cambissolo_canonical()make_cambissolo_canonical()
A PedonRecord populated with the canonical horizons and site metadata for this reference profile.
Reusa fixture WRB Chernozem – A chernozemico + Bk com argila Ta + V alta. SiBCS strictos exigem (a) Bi/Bt + Ta + V alta, OR (b) calcico/petrocalcico/carbonatico + A chernozemico.
make_chernossolo_canonical()make_chernossolo_canonical()
A PedonRecord populated with the canonical horizons and site metadata for this reference profile.
Synthetic Ukrainian / Russian steppe Chernozem on loess: thick dark Ah, granular structure, secondary carbonates accumulating in the Bk. By construction:
mollic: PASSES on horizon Ah1 (moist value 2,
chroma 1, dry value 3; SOC 4%; BS 89%; thickness 30 cm;
strong granular structure).
argic: FAILS (essentially no clay
differentiation; ratios all close to 1).
ferralic: FAILS (CEC/clay ~ 120 cmol_c/kg
clay – high-activity 2:1 clay).
make_chernozem_canonical()make_chernozem_canonical()
A PedonRecord.
Synthetic Arctic Cryosol on weathered shale with permafrost at
50 cm: thawed A horizon over a frozen Bf horizon. By construction
cryic_conditions passes via the designation pattern.
make_cryosol_canonical()make_cryosol_canonical()
A PedonRecord.
Small, plausible profiles written for the tests and examples, one per order of the Canadian System of Soil Classification, with designations in the Canadian notation and the properties the order, great-group and subgroup keys read: a Brunisolic Dystric Turbic Cryosol, a Terric Humic Mesisol, an Orthic Vertisol, an Orthic Humo-Ferric Podzol, an Orthic Humic Gleysol, a Dark Brown Solonetz, an Orthic Dark Brown Chernozem, an Orthic Gray Luvisol, an Orthic Eutric Brunisol and an Orthic Regosol. They are not records of real pedons.
make_cssc3_example( order = c("cryosolic", "organic", "vertisolic", "podzolic", "gleysolic", "solonetzic", "chernozemic", "luvisolic", "brunisolic", "regosolic") )make_cssc3_example( order = c("cryosolic", "organic", "vertisolic", "podzolic", "gleysolic", "solonetzic", "chernozemic", "luvisolic", "brunisolic", "regosolic") )
order |
One of |
A PedonRecord.
p <- make_cssc3_example("chernozemic") p$horizons[, c("designation", "top_cm", "bottom_cm", "oc_pct")]p <- make_cssc3_example("chernozemic") p$horizons[, c("designation", "top_cm", "bottom_cm", "oc_pct")]
Synthetic semi-arid Durisol with a Si-cemented subsurface horizon
(35% duripan nodules over 45 cm). By construction
duric_horizon passes on Bdu.
make_durisol_canonical()make_durisol_canonical()
A PedonRecord.
Build an empty horizons data.table with the canonical schema
make_empty_horizons(n = 0L)make_empty_horizons(n = 0L)
n |
Number of rows (default 0). |
A data.table with all canonical horizon columns filled
with NAs of the correct type.
h <- make_empty_horizons(3) nrow(h)h <- make_empty_horizons(3) nrow(h)
Reusa fixture WRB Podzol – B espodico imediatamente abaixo de E.
make_espodossolo_canonical()make_espodossolo_canonical()
A PedonRecord populated with the canonical horizons and site metadata for this reference profile.
Synthetic but realistic Brazilian Latossolo Vermelho (Ferralsol per WRB 2022): deeply weathered, kaolinitic / oxidic, with the canonical "low-activity clay" signature. Diagnostic outcomes are deterministic by construction:
ferralic: PASSES on horizons Bw1 and Bw2
(CEC/clay = 8.3 cmol_c/kg clay; ECEC/clay = 3.6 cmol_c/kg
clay; texture sandy clay / clay; thickness >= 30 cm).
argic: FAILS (gradual clay increase, all
pairwise ratios < 1.2; absolute increment too small for the
>= 40% rule).
mollic: FAILS (chroma > 3, BS < 50%, A
horizon < 20 cm thick).
make_ferralsol_canonical()make_ferralsol_canonical()
A PedonRecord.
Synthetic floodplain Fluvisol: stratified textures across
consecutive C horizons, OC pattern non-monotone with depth
(because C2 is more recently deposited, OC-richer than C1).
By construction fluvic_material passes.
make_fluvisol_canonical()make_fluvisol_canonical()
v0.9.310: the strata are numbered as deposits of their own (C, 2C, 3C; FAO 2006 Guidelines), the lithic discontinuities that their particle-size distributions show (WRB 2022 Ch 3.2.7, criterion 2.a.iv), and the first two are massive, as unaltered alluvium is. Written C1, C2, C3, the clay-richer second stratum met the argic horizon (WRB 2022 Ch 3.1.3), and the profile keyed out as a Luvisol once the Luvisols asked only for an argic horizon starting <= 100 cm (Ch 4, p. 122); with the weak subangular blocky structure they had, the C below the Ah (chroma 1 unit higher) was a cambic horizon (Ch 3.1.5, criterion 3.b.iii) and the profile a Fluvic Cambisol.
A PedonRecord.
Reusa fixture WRB Gleysol – horizonte glei dentro de 50 cm.
make_gleissolo_canonical()make_gleissolo_canonical()
A PedonRecord populated with the canonical horizons and site metadata for this reference profile.
Synthetic Gleysol from a high-water-table floodplain: A with low chroma but no explicit redox features (so gleyic test is anchored on Bg); Bg with diagnostic redoximorphic features (35% by volume) within the upper 50 cm. By construction:
gleyic_properties: PASSES on Bg.
argic, ferralic,
mollic, cambic,
plinthic, spodic,
calcic, gypsic,
salic: FAIL.
make_gleysol_canonical()make_gleysol_canonical()
A PedonRecord.
Synthetic Gypsisol on gypsiferous parent material: shallow A; gypsum accumulation rising sharply in the By1 horizon (35% gypsum over 50 cm) – the diagnostic gypsic horizon. By construction:
make_gypsisol_canonical()make_gypsisol_canonical()
A PedonRecord.
Synthetic boreal-mire Histosol: thick (50 cm) surface organic horizon with OC ~ 35%, low chroma, no exchangeable-base data reported (typical of histic profiles where laboratory chemistry on organic material is reported separately). By construction:
histic_horizon: PASSES on Oa.
Mineral horizons below; mollic / umbric NA (no BS reported).
make_histosol_canonical()make_histosol_canonical()
A PedonRecord.
Small, plausible profiles written for the tests and examples, one per
type of the Hungarian diagnostic soil classification (Micheli et al.
2024), with designations in the FAO (2006) notation the text adopts and
the properties the key reads, including a total water-soluble salt
content (soluble_salts_pct) and exchangeable cations, so that the
types before each one are decided. They are not real profiles.
make_hscs2024_example( type = c("peat", "anthropogenic", "rocky_skeletal", "rock_influenced", "solonetz", "solonchak", "swelling_clay", "meadow", "carbonate", "steppe", "clay_illuvial", "sandy", "brown_earth", "deposit", "weakly_developed") )make_hscs2024_example( type = c("peat", "anthropogenic", "rocky_skeletal", "rock_influenced", "solonetz", "solonchak", "swelling_clay", "meadow", "carbonate", "steppe", "clay_illuvial", "sandy", "brown_earth", "deposit", "weakly_developed") )
type |
One of |
A PedonRecord.
p <- make_hscs2024_example("meadow") p$horizons[, c("designation", "top_cm", "bottom_cm")]p <- make_hscs2024_example("meadow") p$horizons[, c("designation", "top_cm", "bottom_cm")]
Synthetic continental-semiarid Kastanozem on loess-like substrate: mollic surface (chroma 3, value 3) – dark enough for mollic but not dark enough for Chernozem (chroma 3 > 2 in the upper 20 cm); secondary carbonates accumulating in the Bk. By construction:
mollic: PASSES.
kastanozem: PASSES.
chernozem: FAILS.
phaeozem: PASSES too (WRB 2022 Phaeozems allow
carbonates); the key reaches the Kastanozems first.
make_kastanozem_canonical()make_kastanozem_canonical()
A PedonRecord.
Reusa fixture WRB Ferralsol – B latossolico imediatamente abaixo de A, sem horizonte argilico acima.
make_latossolo_canonical()make_latossolo_canonical()
A PedonRecord populated with the canonical horizons and site metadata for this reference profile.
Synthetic mountain-slope Leptosol on metamorphic rock: a thin A (10 cm) directly over continuous rock. By construction:
leptic_features: PASSES (R at 10 cm <= 25).
Other diagnostics fail on thickness, missing data, or absent diagnostic features.
make_leptosol_canonical()make_leptosol_canonical()
A PedonRecord.
Synthetic Mediterranean / sub-tropical Lixisol on weathered calcareous parent material: argic horizon at Bt1 with low-activity clay (CEC/clay ~ 20) but high base saturation (BS ~ 70%) thanks to carbonate-buffered weathering. By construction:
make_lixisol_canonical()make_lixisol_canonical()
A PedonRecord.
Synthetic temperate-zone Luvisol on loess: clear textural differentiation, Bt with clay coatings, high base saturation, high- activity clay. By construction:
argic: PASSES on horizon Bt1 (clay increase
from E (18%) to Bt1 (35%) gives ratio 1.94 in the 15-40%
band; thickness 25 cm; texture clay loam; no glossic
features).
ferralic: FAILS (CEC/clay ~ 45 cmol_c/kg clay
in the Bt – well above the 16 cmol_c/kg threshold).
mollic: FAILS (A horizon: moist value 4 > 3,
thickness 10 cm < 20 cm).
make_luvisol_canonical()make_luvisol_canonical()
A PedonRecord.
Solo com B textural argila Ta + V alta. Tipico do semiarido com rocha basica.
make_luvissolo_canonical()make_luvissolo_canonical()
A PedonRecord populated with the canonical horizons and site metadata for this reference profile.
Solo raso sobre rocha continua dura. Sem horizonte B diagnostico.
make_neossolo_canonical()make_neossolo_canonical()
A PedonRecord populated with the canonical horizons and site metadata for this reference profile.
Synthetic East-African Nitisol on weathered basalt: clay-rich
(>= 50%), Fe-rich (DCB ~ 6%), polyhedral structure with shiny
ped surfaces. By construction nitic_horizon passes.
make_nitisol_canonical()make_nitisol_canonical()
A PedonRecord.
Solo argiloso (>= 35% argila desde superficie) com B nitico (estrutura forte em blocos + cerosidade), gradiente textural baixo (B/A <= 1.5).
make_nitossolo_canonical()make_nitossolo_canonical()
A PedonRecord populated with the canonical horizons and site metadata for this reference profile.
Small, plausible profiles written for the tests and examples, one per order of the New Zealand Soil Classification, with designations in the New Zealand notation and the properties the order key reads. Most key to the last (Orthic or default) group of their order. Their subgroup may be provisional where a measure the subgroups read is missing (sulfidic S, exchangeable Ca and Mg, the origin of the layers). They are not real profiles.
make_nzsc4_example( order = c("organic", "gley", "ultic", "podzol", "allophanic", "pumice", "melanic", "semiarid", "oxidic", "granular", "pallic", "brown", "anthropic", "recent", "raw") )make_nzsc4_example( order = c("organic", "gley", "ultic", "podzol", "allophanic", "pumice", "melanic", "semiarid", "oxidic", "granular", "pallic", "brown", "anthropic", "recent", "raw") )
order |
One of |
A PedonRecord.
p <- make_nzsc4_example("pallic") p$horizons[, c("designation", "top_cm", "bottom_cm")]p <- make_nzsc4_example("pallic") p$horizons[, c("designation", "top_cm", "bottom_cm")]
Solo organico saturado, com horizonte H histico >= 60 cm e SOC alto. Tipico de varzea / brejo.
make_organossolo_canonical()make_organossolo_canonical()
A PedonRecord populated with the canonical horizons and site metadata for this reference profile.
Synthetic humid-temperate Phaeozem on non-calcareous loess: mollic (chroma 2, value 2-3) and high BS, but no secondary carbonates anywhere – typical of more leached / less-arid steppe-forest transition. By construction:
mollic: PASSES.
phaeozem: PASSES.
chernozem, kastanozem: FAIL
(no carbonates).
make_phaeozem_canonical()make_phaeozem_canonical()
A PedonRecord.
Synthetic temperate Planosol with abrupt textural change: sandy E
(clay 12%) overlies a clay-rich Bt (35%) at 25 cm with an
abrupt boundary. By construction planic_features
passes.
make_planosol_canonical()make_planosol_canonical()
A PedonRecord.
Solo com horizonte E sobrejacente a B planico (mudanca textural abrupta + cores neutras + cromas baixos).
make_planossolo_canonical()make_planossolo_canonical()
A PedonRecord populated with the canonical horizons and site metadata for this reference profile.
Synthetic seasonally-saturated tropical Plinthosol: A horizon with typical Cerrado SOC; Btv with diagnostic plinthite (25% by volume over 60 cm); persistent plinthite at depth. By construction:
make_plinthosol_canonical()make_plinthosol_canonical()
A PedonRecord.
Reusa fixture WRB Plinthosol – horizonte plintico iniciando dentro de 40 cm. The WRB fixture writes its plinthic horizons "Btv" and "Cv", as KST and FAO do. In the Brazilian notation "v" marks vertic features and plinthite is "f", which for KST and FAO is frozen soil: a suffix read one way by one key is read another way by the next. This profile is classified by the three keys (it is one of the demonstration profiles of the app), so its horizons carry neither letter ("Bt", "C") and its plinthite is the measured one.
make_plintossolo_canonical()make_plintossolo_canonical()
A PedonRecord populated with the canonical horizons and site metadata for this reference profile.
Synthetic boreal / temperate-coniferous Podzol: bleached E (low clay, low CEC), illuvial Bs with diagnostic Al/Fe oxalate accumulation, weathered C. By construction:
spodic: PASSES on Bs (Al_ox + 0.5*Fe_ox = 0.6,
pH 4.5, 40 cm thick).
argic, ferralic,
mollic, cambic,
plinthic, calcic,
gypsic, salic: FAIL.
make_podzol_canonical()make_podzol_canonical()
E horizon Munsell is set to chroma 3 (rather than canonical 1-2 of a
true albic) to keep gleyic_properties clearly negative under
the conservative v0.2 criterion.
A PedonRecord.
Synthetic temperate Retisol on loess over clay-rich substrate:
bleached E with glossic tongues penetrating the underlying argic
Bt. By construction retic_properties passes via
the "glossic" designation pattern; argic also
passes (this is correct – Retisols are argic + retic features,
and the WRB key tests RT before AC/LX/AL/LV). The Bt is below
1.5 kg/dm3, so that the claric E has no stagnic properties (WRB 2022
3.2.14 criterion 4) and the profile does not key as a Stagnosol.
make_retisol_canonical()make_retisol_canonical()
A PedonRecord.
Synthetic Solonchak from a coastal-arid setting: surface salt accumulation gives the diagnostic salic horizon (EC 25 dS/m over 25 cm); EC declines but stays elevated in the Bz; non-saline C below. By construction:
make_solonchak_canonical()make_solonchak_canonical()
A PedonRecord.
Synthetic Solonetz on saline-sodic substrate: argic Btn with
columnar structure and high exchangeable Na (ESP ~ 28%). By
construction natric_horizon passes.
make_solonetz_canonical()make_solonetz_canonical()
A PedonRecord.
Synthetic Stagnosol: redoximorphic features in a perched layer
(Bg, 15-50 cm; redox 25%) but the deeper subsoil is well-drained
(BC redox 2%, C redox 0). Since v0.9.312 what tells stagnic from
gleyic is the recorded perched water table and the Bg's matrix, which
has no reductimorphic colour (WRB 2022 3.2.6 and 3.2.14, as Hugo reads
them): stagnic_properties passes,
gleyic_properties does not, and the grey Bg covers more
than one third of 0-60 cm (the Stagnosols key, Ch 4, p. 108).
make_stagnosol_canonical()make_stagnosol_canonical()
A PedonRecord.
Generates a small, deterministic PedonRecord with
n_horizons horizons and a Vis-NIR spectral matrix
(350:2500 nm). Useful for exercising
fill_from_spectra in tests and vignettes.
make_synthetic_pedon_with_spectra( n_horizons = 5L, wavelengths = 350:2500, seed = 1L )make_synthetic_pedon_with_spectra( n_horizons = 5L, wavelengths = 350:2500, seed = 1L )
n_horizons |
Integer number of horizons (default 5). |
wavelengths |
Integer vector of wavelengths (default
|
seed |
Integer seed for the RNG used to generate the spectra. |
A PedonRecord with a $spectra$vnir
matrix attached.
Synthetic urban / industrial Technosol: surface horizon with 30%
anthropogenic artefacts (brick, glass, slag, plastic). By
construction technic_features passes.
make_technosol_canonical()make_technosol_canonical()
A PedonRecord.
Synthetic humid-temperate Umbrisol on weathered acidic schist: deep
organic-rich dark surface with low base saturation – the acid
analogue of a Phaeozem. By construction umbric_horizon
passes; mollic fails on BS < 50.
make_umbrisol_canonical()make_umbrisol_canonical()
A PedonRecord.
Synthetic Vertisol from a smectite-rich plain: deep clay (50-55%) with strong slickensides in the Bss horizon. Surface chroma 4 (above the mollic cap) so that vertic_properties is the only v0.2 diagnostic that passes. By construction:
vertic_properties: PASSES on Bss and BC.
argic, ferralic,
mollic, cambic,
plinthic, spodic,
calcic, gypsic,
salic: FAIL.
make_vertisol_canonical()make_vertisol_canonical()
A PedonRecord.
Solo argiloso (>= 30% argila desde superficie) com horizonte vertico (slickensides + fendas + clay alto) iniciando dentro de 100 cm. Reusa structure / fixture do WRB Vertisol.
make_vertissolo_canonical()make_vertissolo_canonical()
A PedonRecord populated with the canonical horizons and site metadata for this reference profile.
Mineral material (WRB 2022 Ch 3.3.11): < 20% SOC AND < 35% volume artefacts containing >= 20% organic carbon. The complement of organic_material / organotechnic_material.
mineral_material(pedon, max_oc = 20, max_organotechnic = 35)mineral_material(pedon, max_oc = 20, max_organotechnic = 35)
pedon |
A |
max_oc |
Numeric threshold or option (see Details). |
max_organotechnic |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Tests whether any near-surface horizon meets the mollic horizon criteria. The mollic horizon is the diagnostic surface horizon of Chernozems, Phaeozems, Kastanozems, and several other RSGs; it indicates a thick, dark, base-rich, organic-matter-enriched topsoil formed under steppe or comparable vegetation.
mollic( pedon, min_thickness = 20, min_oc = 0.6, min_bs = 50, surface_top_cm = 5 )mollic( pedon, min_thickness = 20, min_oc = 0.6, min_bs = 50, surface_top_cm = 5 )
pedon |
A |
min_thickness |
Minimum thickness in cm (default 20). |
min_oc |
Minimum SOC % (default 0.6). |
min_bs |
Minimum base saturation % (default 50). |
surface_top_cm |
Maximum top depth (cm) for a horizon to be considered "surface-related" (default 5). v0.1 uses this as a proxy for the WRB rule that mollic must form continuously from the soil surface (after mixing of upper 20 cm if required). |
Sub-tests called:
test_mollic_color – moist value <= 3, moist
chroma <= 3, dry value <= 5.
test_mollic_organic_carbon – SOC >= 0.6%.
test_mollic_base_saturation – BS (NH4OAc, pH 7)
>= 50%.
test_mollic_thickness – horizon thickness >= 20 cm.
test_mollic_structure – not simultaneously
massive AND very hard when dry.
v0.1 limitations: cumulative thickness across contiguous mollic- qualifying horizons is not yet supported – this matters for profiles where mollic criteria are met by an A1+A2 sequence but no single horizon is >= 20 cm thick. Mixing of upper 20 cm before the test (per WRB) is also deferred to v0.2.
IUSS Working Group WRB (2022). World Reference Base for Soil Resources, 4th edition. International Union of Soil Sciences, Vienna. Chapter 3 – Mollic horizon.
"Consiste em um consideravel aumento no teor de argila em pequena distancia na zona de transicao entre o horizonte A ou E e o horizonte subjacente B":
A or E with less than 200 g/kg of clay: the B has at least twice as much;
A or E with 200 g/kg or more: the B has 200 g/kg more or above ("de 300 para no minimo 500, ou de 220 para no minimo 420"),
"em uma distancia vertical <= 7,5 cm".
mudanca_textural_abrupta(pedon)mudanca_textural_abrupta(pedon)
pedon |
A |
Since v0.9.244 the test is that of the book: the first B horizon is
compared with the horizon immediately above it, which has to be an A or
an E; and the distance is read from the distinctness of the transition
(boundary_distinctness of the horizon above: abrupt, under 2.5 cm,
or clear, 2.5 to 7.5 cm). Where it is recorded as gradual or diffuse there
is no abrupt change; where it is not recorded the two horizons are
compared. The layer returned is the first B horizon. A BA is a B horizon
here and a BC is not, as in item (h) of the B textural.
Until v0.9.243 the function was the WRB
abrupt_textural_difference, which compares every pair of
adjoining layers, in the order of the rows: a jump of clay between two B
horizons, or from a B to a C, was an abrupt change. A profile with no
horizon designation at all is still tested that way.
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Mulmic material (WRB 2022 Ch 3.3.12): mineral material developed from organic material; \>= 8% SOC, with low BD, structural / chroma criteria.
mulmic_material(pedon, min_oc = 8, max_chroma = 2)mulmic_material(pedon, min_oc = 8, max_chroma = 2)
pedon |
A |
min_oc |
Numeric threshold or option (see Details). |
max_chroma |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Tests for the natric horizon: an argic horizon with diagnostic sodium accumulation. Diagnostic of Solonetz.
natric_horizon(pedon, min_esp = 15, min_pH_h2o = 7)natric_horizon(pedon, min_esp = 15, min_pH_h2o = 7)
pedon |
A |
min_esp |
Minimum ESP % (default 15). |
min_pH_h2o |
Minimum pH(H2O) for the ESP-only path (default 7.0; alkaline gate to exclude false-positive acidic Bt horizons). |
v0.9.310: WRB 2022 Ch 3.1.21 (p. 53-54) criterion 3 (columnar or
prismatic structure, or blocky with tongues of the overlying layer) and
criterion 4 (ESP 15 throughout the upper 40 cm, or Mg + Na >
Ca + exchange acidity there with ESP 15 within 50 cm). Until
then an ESP 15 in any argic layer sufficed; the USDA natric
helpers keep that reading.
Field-described Solonetz profiles in NCSS / KSSL data routinely
reach the natric ESP threshold (computed from
na_cmol / cec_cmol) without satisfying the strict
argic() clay-increase test, because surveyors record
Btk-suffix designations (carbonates dominate the horizon
designation choice) rather than Btn/Bn or
clay_pct is missing.
With options(soilKey.natric_designation_inference = TRUE) the
function accepts a layer as natric when the canonical argic test
returns NA or FALSE AND either:
the designation matches [A-Z][a-z0-9]*n (an n
master-letter modifier in the horizon name – e.g.\
Btn, Btnz, Bn, the curator's direct
assertion that natric features are present), OR
ESP >= min_esp on a B-prefixed subsoil layer
(top_cm > 20) AND the layer's pH(H2O) >= 7
(alkaline – typical of true natric, excludes acidic Bt
horizons that happen to read high Na from sea-spray).
Default is FALSE (canonical behaviour preserved).
IUSS Working Group WRB (2022), Chapter 3, Natric horizon.
Tests for a nitic horizon, WRB 2022 Chapter 3.1.22, criterion by criterion on each layer:
30% clay (min_clay);
moderate to strong angular or subangular blocky structure
breaking into polyhedral or flat-edged second-level structure, or
polyhedral structure, with pressure faces (shiny surfaces) on
25% of the aggregate surfaces. Read from
structure_type, structure_grade,
structure_type_secondary and pressure_faces,
"common" or more (since v0.9.317; until then from clay films,
which WRB 2022 keeps apart from pressure faces);
4% Fe-dith (fe_dcb_pct), 0.2%
Fe-ox (fe_ox_pct) and Fe-ox / Fe-dith 0.05;
not part of a plinthic horizon (plinthic);
the layers that meet 1-4 are 30 cm thick together, as
one horizon (min_thickness).
A criterion is FALSE when the data contradict it and NA
when the data it needs are missing: a profile without Fe-ox or structure
records gets NA, not a nitic horizon. With
options(soilKey.morphological_inference = TRUE) missing structure
and Fe data are read from a Bt designation with a CEC of 8-36 cmolc/kg
clay and no albic E above (the v0.9.18 reading of legacy profiles),
recorded in the evidence.
nitic_horizon( pedon, min_clay = 30, min_fe_dcb = 4, min_thickness = 30, min_fe_ox = 0.2, min_feox_fedith = 0.05, max_clay_drop_pct = NULL, max_decrease_depth = NULL )nitic_horizon( pedon, min_clay = 30, min_fe_dcb = 4, min_thickness = 30, min_fe_ox = 0.2, min_feox_fedith = 0.05, max_clay_drop_pct = NULL, max_decrease_depth = NULL )
pedon |
A |
min_clay |
Minimum clay % (default 30). |
min_fe_dcb |
Minimum dithionite Fe % (default 4). |
min_thickness |
Minimum thickness in cm (default 30). |
min_fe_ox |
Minimum oxalate Fe % (default 0.2). |
min_feox_fedith |
Minimum Fe-ox / Fe-dith ratio (default 0.05). |
max_clay_drop_pct, max_decrease_depth
|
Unused since v0.9.220, kept so that existing calls still run. |
Until v0.9.219 the structure and shiny-surface tests never vetoed,
Fe-ox was not read, a plinthic horizon was not excluded, any ferralic
horizon in the profile excluded a nitic one (WRB 2022 does not:
Nitisols key out before Ferralsols), the Fe inference above ran by
default, and a clay drop of more than 8 percentage points within 50 cm
vetoed it. The clay rule of the Nitisol key is in nitisol.
IUSS Working Group WRB (2022), Chapter 3.1.22, Nitic horizon.
The Nitisol entry of the WRB 2022 key (Chapter 4): "1. a nitic horizon
starting 100 cm from the mineral soil surface; and 2. from the
mineral soil surface to the nitic horizon, a clay content that is at least
half of the weighted average clay content of the nitic horizon; and 3. no
vertic horizon starting above or at the upper limit of the nitic horizon."
Criterion 2 is read layer by layer; a vertic horizon soilKey cannot
establish does not exclude.
nitisol(pedon)nitisol(pedon)
pedon |
A |
IUSS Working Group WRB (2022), Chapter 4, Nitisols.
FEBR ships SiBCS labels in mixed legacy/modern form
("Podzolicos" for old name of Argissolos, singular vs plural,
Portuguese accents). This helper folds them to the form produced by
run_sibcs_key() so that benchmark accuracies can be computed
without false negatives.
normalise_febr_sibcs(x, level = c("order", "subordem"))normalise_febr_sibcs(x, level = c("order", "subordem"))
x |
Character vector of FEBR SiBCS names. |
level |
One of |
A label is read by its first word, with any punctuation around it dropped
("ESPODOSSOLO." is Espodossolos). Since v0.9.225 the result must be
one of the 13 orders of SiBCS 5 after the legacy map; otherwise it is
NA. Until then the first word came out whatever it was, so
"CLASSIFICACAO ? CAMBISSOLO ..." became the class "Classificacaos",
"ALISSOLO CROMICO" "Alissolos" and "LATOSOL AMARELO"
"Latosois": labels no prediction can equal, which the benchmarks counted
as scored profiles and as errors (631 of the 7,694 labels of the national
BDsolos export, in 79 forms).
Since v0.9.226, when the first word gives no order the label is read once
more as an old name: a leading "Solo" or "Solos" is set aside ("SOLO
LITOLICO" is Neossolos, "SOLOS ORGANICOS" Organossolos), a hyphen separates
words as a space does ("LATOSSOLO-VERMELHO", "SOLONETZ-SOLODIZADO"), and the
names of .SIBCS_LEGACY_TWO_WORD_MAP ("TERRA ROXA ESTRUTURADA",
"BRUNO NAO CALCICO") are looked up before those of
.SIBCS_LEGACY_ORDER_MAP. A label the first word already places is
read as before. At level = "subordem" an old name gives its order
followed by the next word of the label, which is not a suborder of SiBCS 5
in general: the old names are for comparisons at the order level.
Since v0.9.229 the order of the name is not the last word when the label
states attributes that SiBCS 5 places elsewhere: a Podzolico
Vermelho-Amarelo or Vermelho-Escuro, or a label that begins with
"Argissolo", that states "Eutrofico" and high-activity clay is Luvissolos,
and a Cambissolo in the old form that states "Eutrofico", high-activity
clay and "A chernozemico" is Chernossolos. See
.sibcs_stated_order().
Character vector of normalised SiBCS names; NA for
labels that are out-of-scope for the comparison: any label that is not
an order of SiBCS 5 after the legacy maps (old names without an entry
there, "Solos ..." followed by none of them, names of other systems,
text that is not a class).
normalise_febr_wrb, normalise_febr_usda
FEBR ships USDA Soil Taxonomy labels at the subgroup or great-group
granularity (e.g. "TYPIC HAPLUDULT", "ACRUSTOX"). The suffix of the
final word encodes the Order: ...OX -> Oxisols, ...ULT
-> Ultisols, ...EPT -> Inceptisols, etc. This helper extracts
the Order from the suffix so the benchmark can compare against
classify_usda()$rsg_or_order at level = "order".
normalise_febr_usda(x)normalise_febr_usda(x)
x |
Character vector of FEBR USDA names. |
Character vector of normalised Order names ("Oxisols", "Ultisols", "Inceptisols", ...).
FEBR ships WRB names with full qualifier strings, e.g.
"HUMIC FERRALSOL", "HAPLIC ACRISOL (ALUMIC, HYPERDYSTRIC, ...)".
The trailing word (before any qualifier parens) is the RSG.
This helper extracts and normalises it to soilKey's plural Title
Case form ("Ferralsols", "Acrisols"), matching
ClassificationResult$rsg_or_order.
normalise_febr_wrb(x)normalise_febr_wrb(x)
x |
Character vector of FEBR WRB names. |
Character vector of normalised RSG names.
KSSL stores 'samp_taxsubgrp' in lower-case, space-separated form ("typic hapludalfs", "aquic argiudolls"). soilKey's 'classify_usda()' returns Title Case names ("Typic Hapludalfs"). The benchmark runner at 'level = "subgroup"' lowercases both sides and trims whitespace, but this helper makes the normalisation explicit when users want to compare KSSL labels against arbitrary classifier output. Idempotent.
normalise_kssl_subgroup(x)normalise_kssl_subgroup(x)
x |
Character vector of KSSL subgroup names. |
Lowercase, single-space-separated vector.
Fits, on the A horizons of a set of pedons that record both colours, a
linear model of the dry Munsell value on the moist value and of the dry
chroma on the moist chroma, and estimates its error by cross-validation
grouped by pedon (the horizons of a pedon stay in one fold): the range of
the out-of-fold errors that holds
level of them (from its lower to its upper tail). The pedons are
dealt to the folds in turn, in the order given, so the result does not
depend on the random number generator. On the NPDB the
error is close to one value unit, so the estimate decides the dry value of
5.5 of the chernozemic A for most dark A horizons but seldom the limits of
3.5 and 4.5 between the Black, Dark Brown and Brown Chernozems.
npdb_dry_colour_model(pedons, level = 0.8, folds = 10L)npdb_dry_colour_model(pedons, level = 0.8, folds = 10L)
pedons |
A list of |
level |
Share of the cross-validated errors the range holds. |
folds |
Number of folds. |
A list of class npdb_dry_colour_model: value and
chroma (each with coef, band = the error range,
rmse out of fold, n horizons), level.
Adds to NPDB pedons what the records lack and the Canadian key reads for
the Chernozems (and the Gray Brown Luvisols and some subgroups), each as a
range, for benchmark_npdb:
the dry value and chroma of the A horizons that record a moist
colour and no dry one, from dry_colour (a
npdb_dry_colour_model), with the range of its error;
the mean annual soil temperature, as the range of
npdb_soil_climate (from the air temperature to 4 degrees
above it; kept as a range only where it crosses 0 or 8 degrees, the
limits the key reads), and the moisture subclass by Thornthwaite, with
the subclass by Hargreaves and every subclass in between where they
differ.
The pedons hold the central estimate (the middle of the soil temperature
range) in the usual fields (munsell_value_dry,
munsell_chroma_dry, site$mean_annual_soil_temp_C,
site$soil_moisture_subclass), and the Thornthwaite moisture index
in site$npdb_cmi; recorded values are never replaced. The ranges
are kept in site$npdb_scenario (a second call adds to them); a
pedon with no site$id, or one not in climate, gets no
climate. benchmark_npdb
classifies such a pedon at every combination of the ends of its ranges
and counts a class as decided only where they all give it; otherwise the
result is provisional.
npdb_scenario(pedons, climate = NULL, dry_colour = NULL)npdb_scenario(pedons, climate = NULL, dry_colour = NULL)
pedons |
A list of |
climate |
A data frame from |
dry_colour |
A |
The pedons (copies), with the estimates.
## Not run: peds <- load_npdb_pedons("path/to/npdb_v3_csv") nm <- fetch_aafc_normals(vapply(peds, function(p) p$site$lat, 0), vapply(peds, function(p) p$site$lon, 0), id = names(peds)) sc <- npdb_scenario(peds, climate = npdb_soil_climate(nm), dry_colour = npdb_dry_colour_model(peds)) benchmark_npdb(sc, level = "order", set_aside = character(0)) ## End(Not run)## Not run: peds <- load_npdb_pedons("path/to/npdb_v3_csv") nm <- fetch_aafc_normals(vapply(peds, function(p) p$site$lat, 0), vapply(peds, function(p) p$site$lon, 0), id = names(peds)) sc <- npdb_scenario(peds, climate = npdb_soil_climate(nm), dry_colour = npdb_dry_colour_model(peds)) benchmark_npdb(sc, level = "order", set_aside = character(0)) ## End(Not run)
Estimates, from monthly climate normals (as returned by
fetch_aafc_normals), what the Canadian System of Soil
Classification reads as the soil climate (Ch 2, p. 16, criterion 7 of the
chernozemic A; the soil temperature classes and moisture subclasses of its
Tables 3 and 4, after the map Soil Climates of Canada, Clayton et al.
1977):
the mean annual air temperature (MAAT, the mean of the twelve
monthly means) and, for the mean annual soil temperature (MAST), the
range from the MAAT to the MAAT plus mast_offset degrees: in
Canada the soil under snow is warmer than the air;
the climatic moisture index (CMI) of Table 4, the growing-season precipitation as a percentage of the water crops would use: here the precipitation over the potential evapotranspiration (PET) of the months of the growing season (April to October) whose mean temperature is above 5 degrees. The PET is computed in two ways: by Thornthwaite (monthly mean temperatures and day length), the central estimate, which matches the zones the book gives the Chernozem great groups on the NPDB (Brown subarid to semiarid, Dark Brown semiarid, Black and Dark Gray subhumid); and by Hargreaves and Samani (monthly minimum and maximum temperatures and extraterrestrial radiation), the other end of the range (on the NPDB mostly drier, sometimes wetter);
the moisture subclass from each index (Table 4): perhumid above 84, humid 74-84, subhumid 59-73, semiarid 46-58, subarid 25-45, arid below 25.
npdb_soil_climate(normals, mast_offset = c(0, 4))npdb_soil_climate(normals, mast_offset = c(0, 4))
normals |
A data frame with |
mast_offset |
The range added to the MAAT for the MAST, in degrees (two numbers, read from the lower to the higher). |
A data frame: id, maat, mast_lo,
mast_hi, p_gs (mm), gs_months, pet_gs and
cmi and moisture_subclass (Thornthwaite),
pet_gs_hargreaves, cmi_hargreaves and
moisture_subclass_hargreaves.
Soil Classification Working Group (1998). The Canadian System of Soil Classification, 3rd ed., Tables 3 and 4. Clayton, J.S. et al. (1977). Soils of Canada. Thornthwaite, C.W. (1948). Geographical Review 38: 55-94. Hargreaves, G.H., Samani, Z.A. (1985). Applied Engineering in Agriculture 1: 96-99. Allen, R.G. et al. (1998). FAO Irrigation and Drainage Paper 56.
Probes http://127.0.0.1:11434/api/tags (the standard Ollama
endpoint) with a short HTTP HEAD-style GET. Returns TRUE
only if the request returns HTTP 200 in under timeout_s
seconds. Used by vlm_pick_provider for the
provider = "auto" fallback chain. Override the URL via
options(soilKey.ollama_url = "http://host:port").
ollama_is_running(url = NULL, timeout_s = 1.5)ollama_is_running(url = NULL, timeout_s = 1.5)
url |
Override URL to probe (default reads
|
timeout_s |
Request timeout in seconds (default 1.5). |
Logical scalar.
Organic material (WRB 2022 Ch 3.3.13): \>= 20% SOC + recognisability criteria. v0.3.3: SOC threshold only.
organic_material(pedon, min_oc = 20)organic_material(pedon, min_oc = 20)
pedon |
A |
min_oc |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Organotechnic material (WRB 2022 Ch 3.3.14): \>= 35% volume of artefacts that themselves contain \>= 20% organic C. Soil itself has < 20% SOC.
organotechnic_material(pedon, min_artefacts = 35, max_oc = 20)organotechnic_material(pedon, min_artefacts = 35, max_oc = 20)
pedon |
A |
min_artefacts |
Numeric threshold or option (see Details). |
max_oc |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Aornit|Bornit.Ornithogenic material (WRB 2022 Ch 3.3.15): bird-influenced topsoil.
Mehlich-3 P >= 750 mg/kg + designation pattern Aornit|Bornit.
ornithogenic_material(pedon, min_p_mehlich3 = 750)ornithogenic_material(pedon, min_p_mehlich3 = 750)
pedon |
A |
min_p_mehlich3 |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
A small, deterministic, OSSL-shaped artefact for use in vignettes,
examples and tests when the real Open Soil Spectral Library data
is not available (no network, sensitive deployment, CI). The
object has the canonical list(Xr, Yr, metadata) shape
consumed by predict_ossl_mbl /
fill_from_spectra, so the in-package demo path is
identical to the real-data path.
ossl_demo_saossl_demo_sa
A list with three elements:
XrNumeric matrix, 80 rows (synthetic profiles) x 2151 columns (wavelengths 350-2500 nm). Reflectance values in [0.05, 0.85].
YrData frame, 80 rows x 9 columns
(clay_pct, sand_pct, silt_pct,
cec_cmol, bs_pct, ph_h2o,
oc_pct, fe_dcb_pct, caco3_pct). Property
ranges follow the OSSL global summary statistics.
metadataNamed list with provenance information
(region, n_profiles, snapshot,
seed, note, ...).
This is a synthetic placeholder: the spectra are generated from a tropical-soil baseline plus property-correlated absorption bands (1400 nm OH-water, 1900 nm clay-OH, 2200 nm Al-OH, 900 nm Fe-oxide) with deterministic noise. It is not a substitute for real OSSL measurements. For paper-grade work, populate a real OSSL artefact via:
ossl_lib <- download_ossl_subset(region = "south_america")
Re-build the demo with source("data-raw/build_ossl_demo.R").
Synthetic; built by data-raw/build_ossl_demo.R with seed
20260430. The OSSL property ranges that drove the simulation
come from Sanderman, J. et al. (2024), Open Soil
Spectral Library, https://soilspectroscopy.org/.
data(ossl_demo_sa) dim(ossl_demo_sa$Xr) #> [1] 80 2151 head(ossl_demo_sa$Yr) ## Not run: # Use it as the ossl_library argument to predict_ossl_mbl(): pedon <- make_synthetic_pedon_with_spectra() fill_from_spectra(pedon, library = "ossl", method = "mbl", ossl_library = ossl_demo_sa) ## End(Not run)data(ossl_demo_sa) dim(ossl_demo_sa$Xr) #> [1] 80 2151 head(ossl_demo_sa$Yr) ## Not run: # Use it as the ossl_library argument to predict_ossl_mbl(): pedon <- make_synthetic_pedon_with_spectra() fill_from_spectra(pedon, library = "ossl", method = "mbl", ossl_library = ossl_demo_sa) ## End(Not run)
predict_ossl_mbl and
predict_ossl_plsr_local take an ossl_library
argument that must be a list with two named elements:
ossl_library_template( wavelengths = 350:2500, properties = c("clay_pct", "sand_pct", "silt_pct", "cec_cmol", "bs_pct", "ph_h2o", "oc_pct", "fe_dcb_pct", "caco3_pct") )ossl_library_template( wavelengths = 350:2500, properties = c("clay_pct", "sand_pct", "silt_pct", "cec_cmol", "bs_pct", "ph_h2o", "oc_pct", "fe_dcb_pct", "caco3_pct") )
wavelengths |
Integer vector of wavelengths (default
|
properties |
Character vector of property column names to seed
the empty |
Xr: numeric matrix, rows = OSSL training spectra,
columns = wavelengths. Must align (after preprocessing)
with the column space used by the spectra you predict on.
Yr: data.frame keyed by property name (e.g.
clay_pct, cec_cmol), one row per training
spectrum.
This function returns an empty template you can populate from a
real OSSL extract (e.g. via the ossl-import Python package
or the public S3 mirror at
https://storage.googleapis.com/soilspec4gg-public/).
soilKey does not bundle OSSL data; until you populate this template with real values, all 'predict_ossl_*' calls fall back to the deterministic synthetic predictor (which prints a warning).
A list with Xr (a 0-row matrix of the right column
dimension) and Yr (an empty data.frame with the
requested columns).
The USDA oxic horizon is the diagnostic of Oxisols. Its central criteria match the WRB 2022 ferralic horizon closely enough that v0.2 simply delegates: every fixture that classifies as Oxisol via USDA also classifies as Ferralsol via WRB and vice-versa. The fine-grained differences (USDA's water-dispersible-clay test, the sand-fraction weatherable-mineral cut-offs) are tracked in the diagnostics.yaml for v0.8 refinement.
oxic_usda(pedon, ...)oxic_usda(pedon, ...)
pedon |
A |
... |
Passed to |
The CEC limit is inclusive here: KST 13 (Ch. 3, oxic horizon, criterion
6) asks for "an apparent CEC of 16 cmol(+) or less per kg clay", where WRB
2022's ferralic horizon asks for "< 16". Since v0.9.212 ferralic()
follows WRB and this function passes cec_inclusive = TRUE, so a
horizon at exactly 16 is oxic but not ferralic.
A DiagnosticResult (with name = "oxic_usda").
Soil Survey Staff (2014). Keys to Soil Taxonomy, 12th edition. USDA-NRCS, Washington DC. Chapter 3 – Diagnostic Horizons; oxic.
From Quechua p'anpay = "to bury". A buried diagnostic horizon (any horizon whose original surface was subsequently overlain by younger material). Used by the Panpaic qualifier and by the Cambisols / Anthrosols branches.
panpaic(pedon)panpaic(pedon)
pedon |
A |
Since v0.9.220 the four criteria of WRB 2022 Ch 3.1.23 on a buried
surface horizon (an A designation with a b suffix, or below a
lithic discontinuity, 2A): 0.2% SOC; SOC
25% (relative) and 0.2% (absolute) higher
than in the overlying layer; a lithic discontinuity at its upper limit;
5 cm thick. Until v0.9.219 any designation containing a
b passed, AB included.
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Returns a Draft-2020-12 JSON Schema describing the canonical
PedonRecord structure: a site object with site-level
metadata plus a horizons array where each element matches
the canonical horizon schema documented by
horizon_column_spec.
pedon_json_schema(as = c("list", "json"), pretty = TRUE)pedon_json_schema(as = c("list", "json"), pretty = TRUE)
as |
One of |
pretty |
Logical, only used for |
A list (default) or a JSON string.
## Not run: schema <- pedon_json_schema() names(schema) #> [1] "$schema" "$id" "title" "type" "required" "properties" # Validate a JSON profile against the schema: if (requireNamespace("jsonvalidate", quietly = TRUE)) { schema_json <- pedon_json_schema(as = "json") jsonvalidate::json_validate('{"site":{...},"horizons":[...]}', schema_json, engine = "ajv") } ## End(Not run)## Not run: schema <- pedon_json_schema() names(schema) #> [1] "$schema" "$id" "title" "type" "required" "properties" # Validate a JSON profile against the schema: if (requireNamespace("jsonvalidate", quietly = TRUE)) { schema_json <- pedon_json_schema(as = "json") jsonvalidate::json_validate('{"site":{...},"horizons":[...]}', schema_json, engine = "ajv") } ## End(Not run)
The mapping respects aqp's expected column conventions and sets
the metadata required by getArgillicBounds(),
getCambicBounds(), and mollicEpipedon():
pedon_to_spc(pedon)pedon_to_spc(pedon)
pedon |
A |
id from pedon$site$id
top / bottom from top_cm / bottom_cm
name (designation) from designation
texcl (texture class) derived via
texture_class_from_pct
clay, silt, sand from
clay_pct / silt_pct / sand_pct
m_hue, m_value, m_chroma,
d_value, d_chroma from
munsell_*_moist and munsell_*_dry
Internal use; the soilKey diagnostics call this on the fly when
engine = "aqp". Direct use is supported for users who want
to plug additional aqp algorithms (slab, slice,
glom) into a soilKey workflow.
A aqp::SoilProfileCollection with one site (the
pedon) and one row per horizon.
PedonRecord: structured representation of a single pedon
PedonRecord: structured representation of a single pedon
The central data carrier in soilKey. A PedonRecord bundles everything we
know about one soil profile: site metadata, the horizons table (with a
fixed canonical schema — see horizon_column_spec),
optional Vis-NIR/MIR spectra, profile photographs, source documents, and
a provenance log that records, per (horizon, attribute) pair, where each
value came from (measured, extracted_vlm,
predicted_spectra, inferred_prior, user_assumed).
All diagnostic functions (argic, ferralic,
mollic, ...) consume a PedonRecord directly. The
provenance log is what allows the final
ClassificationResult to assign a meaningful evidence
grade.
Horizon columns and site properties that soilKey does not recognise are
kept but read by no key. PedonRecord$new() warns about them (with
the closest recognised names) when it is called from outside the package;
see unrecognised_attributes,
horizon_attribute_spec and site_attribute_spec.
options(soilKey.warn_unrecognised = FALSE) turns the warning off.
An R6 object of class PedonRecord.
siteList. Site-level metadata: lat, lon,
crs (default 4326), date,
country, elevation_m, slope_pct,
aspect_deg, landform,
parent_material, land_use,
vegetation, drainage_class,
plus an arbitrary id.
horizonsdata.table with the canonical horizon schema.
spectraList with optional vnir matrix (rows =
horizons, cols = wavelengths in nm), mir
matrix, and metadata list.
imagesList of named lists describing profile photographs.
documentsList of named lists describing source documents.
provenancedata.table with columns horizon_idx,
attribute, source, confidence,
notes.
new()
Construct a PedonRecord.
PedonRecord$new( site = NULL, horizons = NULL, spectra = NULL, images = NULL, documents = NULL, provenance = NULL )
siteList of site-level metadata.
horizonsdata.frame/data.table of horizons.
spectraOptional list with vnir, mir,
metadata.
imagesOptional list of image descriptors.
documentsOptional list of document descriptors.
provenanceOptional provenance data.table; if NULL, an empty one is created.
validate()
Validate the record against soil-physical sanity rules.
Checks: top < bottom for every horizon; no overlapping depths;
clay+silt+sand sum to 100 ± 2 where all three are reported; pH
values plausible (1..12); CEC >= sum of exchangeable bases (Ca, Mg,
K, Na); Munsell value/chroma in plausible ranges; coarse fragments
percent in [0, 100]; OC
geographic ranges. Returns a list with valid, errors,
warnings, n_horizons.
PedonRecord$validate(strict = FALSE, verbose = TRUE)
strictIf TRUE, throws on errors instead of returning.
verboseIf TRUE, prints messages via cli.
Invisibly, a list summarising the validation outcome.
to_aqp()
Coerce to an aqp SoilProfileCollection.
PedonRecord$to_aqp()
A SoilProfileCollection. Requires the aqp
package.
from_aqp()
Populate this record from an aqp
SoilProfileCollection.
PedonRecord$from_aqp(spc, top_col = "top_cm", bottom_col = "bottom_cm")
spcA SoilProfileCollection.
top_colName of the top-depth column in spc (mapped to
top_cm).
bottom_colName of the bottom-depth column (mapped to
bottom_cm).
Invisibly self (mutated in place).
add_measurement()
Add a measurement (or extracted/predicted value) and record its provenance.
PedonRecord$add_measurement( horizon_idx, attribute, value, source = "measured", confidence = 1, notes = NA_character_, overwrite = FALSE )
horizon_idxInteger horizon index (1-based).
attributeName of the horizon column to set.
valueNew value for that cell.
sourceOne of "measured", "extracted_vlm", "predicted_spectra", "inferred_prior", "user_assumed".
confidenceNumeric in [0, 1].
notesOptional free-text note.
overwriteIf FALSE (default) and the cell already has
a value from a more authoritative source, leave it
alone. If TRUE, overwrite.
Invisibly self.
summary()
Compact summary list (for serialization or testing).
PedonRecord$summary(...)
...Ignored (S3 summary signature compatibility).
print()
Pretty-print the record.
PedonRecord$print(...)
...Ignored (S3 print signature compatibility).
clone()
The objects of this class are cloneable with this method.
PedonRecord$clone(deep = FALSE)
deepWhether to make a deep clone.
# The canonical fixtures return ready-built PedonRecords: pedon <- make_ferralsol_canonical() pedon$site$id nrow(pedon$horizons)# The canonical fixtures return ready-built PedonRecords: pedon <- make_ferralsol_canonical() pedon$site$id nrow(pedon$horizons)
Groups a reflectance + metadata table by profile and returns one
PedonRecord per profile, with each profile's sample rows stacked
into $spectra$vnir (rows = horizons, cols = wavelengths) and the lab
attributes / depths written to the horizons. Taxonomic labels are stored in
$site (reference_wrb / reference_sibcs /
reference_st). These pedons are the query objects for
classify_*(gapfill = list(method = "spectra", ossl_library = <lib>)).
pedons_from_spectral_table( reflectance, metadata, id_col = "id", profile_col = NULL, wavelengths = NULL, resample_to = NULL, property_map = NULL, label_map = NULL, normalize = c("auto", "none", "percent"), keep_properties = FALSE, verbose = TRUE )pedons_from_spectral_table( reflectance, metadata, id_col = "id", profile_col = NULL, wavelengths = NULL, resample_to = NULL, property_map = NULL, label_map = NULL, normalize = c("auto", "none", "percent"), keep_properties = FALSE, verbose = TRUE )
reflectance |
Reflectance data: a matrix / data.frame with rows =
samples and columns named by wavelength (nm); OR a long data.frame with
|
metadata |
A data.frame with one row per sample carrying |
id_col |
Sample identifier column shared by both tables (default
|
profile_col |
Column grouping samples into profiles (default
|
wavelengths |
Optional explicit wavelength vector (nm) when the reflectance columns are not wavelength-named. |
resample_to |
Optional target wavelength grid (nm) to linearly resample
every spectrum onto (e.g. |
property_map, label_map
|
Optional named lists overriding the alias
auto-detection, e.g. |
normalize |
One of |
keep_properties |
If |
verbose |
Print a one-line summary (default |
A list of PedonRecord objects.
read_spectral_library, benchmark_spectral_fill
A continuously cemented variant of the calcic horizon. Same chemistry (CaCO3 \>= 15%) plus moderate-or-greater cementation in at least 50% of the layer.
petrocalcic(pedon, min_thickness = 10, min_caco3_pct = 15)petrocalcic(pedon, min_thickness = 10, min_caco3_pct = 15)
pedon |
A |
min_thickness |
Numeric threshold or option (see Details). |
min_caco3_pct |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Petroduric horizon (WRB 2022): cemented duric.
petroduric(pedon, min_thickness = 10, min_duripan_pct = 10)petroduric(pedon, min_thickness = 10, min_duripan_pct = 10)
pedon |
A |
min_thickness |
Numeric threshold or option (see Details). |
min_duripan_pct |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Petrogypsic horizon (WRB 2022): cemented gypsic.
petrogypsic(pedon, min_thickness = 10, min_gypsum_pct = 5)petrogypsic(pedon, min_thickness = 10, min_gypsum_pct = 5)
pedon |
A |
min_thickness |
Numeric threshold or option (see Details). |
min_gypsum_pct |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Continuous or fractured layer cemented by Fe (WRB 2022 Ch 3.1.27, p. 59).
Since v0.9.312 a layer qualifies when its Fe cement is recorded (an iron
pan, pan_type ferricrete or ironpan, or plinthite \>=
min_plinthite_pct) and its cementation class is at least strongly
cemented (criterion 4; until v0.9.311 moderately was enough), over
min_thickness cm of adjoining layers (criterion 7). A layer whose
Fe cement or cementation is not recorded is undecided.
petroplinthic(pedon, min_thickness = 10, min_plinthite_pct = 15)petroplinthic(pedon, min_thickness = 10, min_plinthite_pct = 15)
pedon |
A |
min_thickness |
Numeric threshold or option (see Details). |
min_plinthite_pct |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Tests whether a profile satisfies the Phaeozem RSG criteria (WRB 2022 Ch 4, p. 113): a mollic horizon AND a base saturation (1 M NH4OAc, pH 7) \>= 50% throughout to 100 cm from the mineral soil surface or to a limiting layer, whichever is shallower. Carbonates are allowed: the Chernozems and Kastanozems are keyed out before. Where BS is not recorded, pH is read as in WRB 2022 Annex 2, Table 9.2. A profile not described down to that depth is undecided.
phaeozem(pedon)phaeozem(pedon)
pedon |
A |
IUSS Working Group WRB (2022), Chapter 4, Phaeozems (p. 113).
Tightens confidence as the prediction interval narrows relative to
the predicted value: confidence = 1 - (PI95_width / |value|) / 4,
floored at 0 and capped at 1. When value is near zero we
fall back to an absolute-width heuristic so we never blow up.
pi_to_confidence(pi95_low, pi95_high, value = NULL)pi_to_confidence(pi95_low, pi95_high, value = NULL)
pi95_low |
Lower 2.5% quantile of the prediction. |
pi95_high |
Upper 97.5% quantile of the prediction. |
value |
Optional point prediction. When supplied, normalisation
is by |
Properties of the mapping:
Zero-width interval -> confidence = 1.
Interval whose width equals |value| * 4 -> confidence = 0.
NA value or NA bounds -> confidence = 0.5 (neutral).
Numeric in [0, 1].
Per-pedon heuristic: returns "aqp" if the pedon's horizon
table has the morphological richness that makes aqp's canonical
NRCS dispatch reliable, otherwise returns "soilkey" (the
more permissive hand-coded path).
pick_engine(pedon, min_score = 3L)pick_engine(pedon, min_score = 3L)
pedon |
A |
min_score |
Integer (1-5). Minimum completeness score for
|
Character: "aqp" or "soilkey".
We score each pedon on a 0-5 morphology-completeness scale; aqp
fires when score \>= min_score (default 3). The five
axes:
Designation present (any layer has a non-blank
designation, e.g. "A1", "Bt2", "Bw").
Texture quantitative (any layer has both
clay_pct and sand_pct populated).
Munsell complete (any layer has all three of
munsell_hue_moist, munsell_value_moist,
munsell_chroma_moist populated).
Structure recorded (any layer has a non-blank
structure_grade).
Clay films / argic evidence (any layer has
a non-blank clay_films_amount or designation
pattern matching Bt).
On BDsolos RJ (data-rich), the heuristic recommends aqp for
~99
canonical thresholds). On LUCAS topsoil-only (data-sparse), it
recommends aqp for ~0
clay-films / designation axes are unfilled. Calling
classify_*(pedon) routed through the heuristic gives the
correct engine per pedon, recovering both the BDsolos RJ lift
AND the LUCAS robustness.
Vectorised version of pick_engine returning the
recommended engine for each pedon in a list.
pick_engine_batch(pedons, min_score = 3L)pick_engine_batch(pedons, min_score = 3L)
pedons |
A list of |
min_score |
Integer; forwarded to |
Character vector of length(pedons) with values "aqp" or "soilkey".
WRB 2022 Ch 3.1.28 (p. 60): \>= 40% of the volume (whole soil)
yellowish, reddish or blackish concretions or nodules over 2 mm, at least
moderately cemented, not part of a petroplinthic horizon, \>= 15 cm
thick. Since v0.9.312 the concretions are read from
ferric_nodules_pct (Fe/Mn nodules or concretions; the ISIS reader
stores the hard ones over 2 mm), adjoining sublayers counting together; a
layer where they are not recorded is undecided. Until v0.9.311 the test
was plinthite \>= 15% with a "pisolitic" structure, which is not the
WRB 2022 definition.
pisoplinthic( pedon, min_thickness = 15, min_plinthite_pct = 15, min_nodules_pct = 40 )pisoplinthic( pedon, min_thickness = 15, min_plinthite_pct = 15, min_nodules_pct = 40 )
pedon |
A |
min_thickness |
Numeric threshold or option (see Details). |
min_plinthite_pct |
Not used since v0.9.312; kept so that existing calls still work. |
min_nodules_pct |
Minimum volume % of concretions and nodules (default 40). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
v0.9.2.C tightening: the v0.3.3 implementation accepted ANY thick, low-BD, OC-rich A horizon, which over-fired across natural mollic / umbric / chernic surfaces. The diagnostic now requires, in addition to the OC + BD + thickness baseline, at least one independent anthropogenic-input marker:
p_mehlich3_mg_kg >= 50 (sustained sod / manure
additions concentrate Mehlich-3 P in the topsoil), OR
artefacts_pct > 0 (any human artefact volume fraction
is sufficient as a presence signal), OR
designation pattern Apl / Aplg / Apk
/ explicit "plagg".
Without one of those markers the diagnostic returns FALSE even when
OC + BD + thickness pass. This mirrors the v0.9.1 qual_plaggic
gate but enforces the rule at the diagnostic level so any caller
(SiBCS, USDA, future modules) inherits the protection.
plaggic( pedon, min_thickness = 20, max_bd = 1.5, min_oc = 0.6, min_p_mehlich3 = 100 )plaggic( pedon, min_thickness = 20, max_bd = 1.5, min_oc = 0.6, min_p_mehlich3 = 100 )
pedon |
A |
min_thickness |
Numeric threshold or option (see Details). |
max_bd |
Numeric threshold or option (see Details). |
min_oc |
Numeric threshold or option (see Details). |
min_p_mehlich3 |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Tests whether the profile shows an abrupt textural change between adjacent horizons (clay-doubling within 7.5 cm vertical distance, typically at the E/Bt boundary). Diagnostic of Planosols.
planic_features(pedon, min_ratio = 2, require_abrupt_boundary = TRUE)planic_features(pedon, min_ratio = 2, require_abrupt_boundary = TRUE)
pedon |
A |
min_ratio |
Minimum clay ratio (default 2.0). |
require_abrupt_boundary |
If TRUE (default), the upper horizon
must have |
IUSS Working Group WRB (2022), Chapter 5, Planosols.
WRB 2022: an abrupt textural difference \<= 75 cm from the mineral soil surface and, within 5 cm directly above or below it, (1) stagnic properties in which the area of reductimorphic plus oximorphic features is \>= 50% and (2) reducing conditions in some parts of the volume with the reductimorphic features.
planosol(pedon, strict = NULL)planosol(pedon, strict = NULL)
pedon |
A |
strict |
Logical or |
The two layers that meet at the abrupt textural difference stand for the
5 cm above and below it. Stagnic properties are those of
stagnic_properties; a claric layer directly above the
abrupt textural difference is stagnic (Ch 3.2.14, criterion 4) and its
whole area counts as reductimorphic. Since v0.9.312 the abrupt textural
difference has its transition criterion (boundary_distinctness),
the depth limit of 75 cm is applied, and the v0.2 planic_features
fallback (clay doubling at an abrupt boundary, with no redox evidence),
which is not in WRB 2022, is gone.
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Tests whether any horizon meets the plinthic horizon criteria (WRB 2022
Ch 3.1.30, p. 62), the diagnostic of Plinthosols with the pisoplinthic
and petroplinthic horizons. The depth limit belongs to the Plinthosols
key (plinthosol()), not to the horizon.
plinthic(pedon, min_thickness = 15, min_plinthite_pct = 15)plinthic(pedon, min_thickness = 15, min_plinthite_pct = 15)
pedon |
A |
min_thickness |
Minimum thickness in cm (default 15). |
min_plinthite_pct |
Minimum volume % plinthite (default 15). |
Criteria read (v0.9.312):
1: plinthite_pct \>= 15 (the oximorphic features inside
former aggregates of criterion 1, as plinthite_pct records
them); a layer where it is not recorded is undecided;
2: Fe-dithionite \>= 2.5% (2.a) when fe_dcb_pct is
measured; below it the layer is undecided, since 2.b (10% Fe in
the oximorphic features) and 2.c (hardening after drying and
wetting) are not recorded; not measured, the recorded plinthite
is taken for 2.c;
3: Feox/Fedith < 0.1 when both are measured;
4: not part of a petroplinthic or pisoplinthic horizon;
5: \>= 15 cm thick; adjoining sublayers (Btv1 over Btv2) count together.
The result is NA when undecided layers could make the horizon.
Field-described Brazilian Plintossolos profiles (e.g.\ the Embrapa
Redape curated dataset) routinely encode plinthite via the
designation suffix f in the master letter sequence (e.g.\
Btf, 2Btf, Cf) – the curator's direct
assertion that plinthite is present – without recording
plinthite_pct as a numeric volume percent.
With options(soilKey.plinthic_designation_inference = TRUE) the
function accepts a layer as plinthic when:
the canonical plinthite_pct test is NA for
that layer, AND
the designation matches [A-Z]+[A-Za-z]*f[0-9]?
(a f master-letter modifier in any sub-position).
Default is FALSE (canonical behaviour preserved).
IUSS Working Group WRB (2022), Chapter 3.1.30, Plinthic horizon.
Combines a deterministic ClassificationResult with a
spatial prior. The deterministic key remains authoritative – this
function reports only an alternative probabilistic view useful for
downstream uncertainty quantification.
posterior_classify(result, prior, epsilon = 0.001)posterior_classify(result, prior, epsilon = 0.001)
result |
A |
prior |
A spatial-prior data.table (as returned by
|
epsilon |
Small smoothing constant added to all prior entries before normalising, so RSGs unseen by the prior do not receive zero posterior. |
Posterior is computed under the simple model:
where the likelihood L is concentrated on the deterministic
assignment (delta-1 at that code) by default, optionally smoothed
if key_passed_others is supplied.
A data.table with columns rsg_code,
prior, likelihood, posterior.
Ergonomic, named entry point for the OSSL-backed predictive
pipeline. Accepts either a PedonRecord or a numeric
spectra matrix, applies the same preprocessing used at training
time (recorded on each model), and returns predictions in the
canonical long-form schema.
predict_from_spectra( pedon_or_spectra, models = NULL, properties = NULL, overwrite = FALSE, verbose = TRUE, ... )predict_from_spectra( pedon_or_spectra, models = NULL, properties = NULL, overwrite = FALSE, verbose = TRUE, ... )
pedon_or_spectra |
A |
models |
A named list of |
properties |
Character vector of property names to predict.
Defaults to all properties in |
overwrite |
Passed to |
verbose |
Verbosity passed downstream. |
... |
Ignored (reserved for future backends). |
When pedon_or_spectra is a PedonRecord, this
function delegates to fill_from_spectra with
method = "pretrained" and the predictions are written back
to the pedon (with source = "predicted_spectra" provenance).
When pedon_or_spectra is a numeric matrix or vector, this
function returns the prediction data.table directly without
touching any pedon.
Either the mutated PedonRecord (invisibly) or a
data.table with columns horizon_idx, property,
value, pi95_low, pi95_high,
n_neighbors.
## Not run: lib <- download_ossl_subset(region = "south_america") models <- train_pls_from_ossl(lib, properties = c("clay_pct", "ph_h2o")) predict_from_spectra(my_pedon, models = models) ## End(Not run)## Not run: lib <- download_ossl_subset(region = "south_america") models <- train_pls_from_ossl(lib, properties = c("clay_pct", "ph_h2o")) predict_from_spectra(my_pedon, models = models) ## End(Not run)
Convenience wrapper: predict_xyz_from_spectra
followed by the standard CIE Lab transform under D65 / 2-degree
observer.
predict_lab_from_spectra(spectra, wavelengths)predict_lab_from_spectra(spectra, wavelengths)
spectra |
Reflectance values, in 0..1 or 0..100. A numeric vector (one sample), a numeric matrix (rows = samples, cols = wavelengths) or a data.frame. |
wavelengths |
Numeric vector of the wavelengths (in nm)
corresponding to the columns of |
A data.frame with columns L, a, b.
Combines predict_xyz_from_spectra with the Munsell
renotation interpolation in munsellinterpol (CRAN, GPL).
Returns hue (e.g. "7.5YR"), value (0..10) and chroma
(0..20) per sample, plus the soilKey fields
predict_munsell_from_spectra(spectra, wavelengths, round_chip = TRUE)predict_munsell_from_spectra(spectra, wavelengths, round_chip = TRUE)
spectra |
Reflectance values, in 0..1 or 0..100. A numeric vector (one sample), a numeric matrix (rows = samples, cols = wavelengths) or a data.frame. |
wavelengths |
Numeric vector of the wavelengths (in nm)
corresponding to the columns of |
round_chip |
If |
The Munsell renotation is defined under Illuminant C, while
the colorimetry here is computed under D65, so the conversion adapts
D65 -> C. It calls munsellinterpol::XYZtoMunsell(XYZ, white =)
(munsellinterpol >= 3.4-0), which performs that chromatic adaptation
internally, and falls back to the numerically identical
XYZ -> CIELAB(D65) -> LabToMunsell() route on older versions.
Feeding D65 chromaticities straight to xyYtoMunsell() (with no
white) would bias every colour toward green-yellow (a perfect
neutral would return Chroma ~ 0.65 rather than 0); this routine avoids
that. The D65 reference white is derived from the same bundled CIE
table the colorimetry integrates against (so a constant-reflectance
spectrum maps to an exact neutral, and a perfect reflecting diffuser
to Munsell value 10), and the conversion is vectorised over all rows
of spectra at once. At zero Chroma the Munsell hue is undefined,
so a neutral is reported with hue "N" in both the rounded and the
continuous (round_chip = FALSE) notation.
munsell_hue_moist, munsell_value_moist,
munsell_chroma_moist ready to write into a
PedonRecord via the pedon's add_measurement
method (see also fill_munsell_from_spectra).
This is the v0.9.47 unblock for the v0.9.35 Argissolo Vermelho / Amarelo / Vermelho-Amarelo color-confusion case: when a user has Vis-NIR spectra (which Embrapa's BDsolos / FEBR do not include but the OSSL does), the Munsell hue can be recovered physically without waiting for the surveyor's morphological description.
A data.frame with columns munsell_hue_moist,
munsell_value_moist, munsell_chroma_moist,
munsell_string (e.g. "7.5YR 4/6"),
X, Y, Z, one row per sample.
## Not run: # White reflector across the visible: should map to a near-neutral # high-value Munsell color. wl <- seq(380, 780, by = 5) R <- rep(0.9, length(wl)) predict_munsell_from_spectra(R, wavelengths = wl) ## End(Not run)## Not run: # White reflector across the visible: should map to a near-neutral # high-value Munsell color. wl <- seq(380, 780, by = 5) R <- rep(0.9, length(wl)) predict_munsell_from_spectra(R, wavelengths = wl) ## End(Not run)
Predicts a set of soil properties from pre-processed Vis-NIR or MIR
spectra using memory-based learning (MBL) – the recommended
OSSL workflow for heterogeneous libraries. Defaults follow the
literature (Ramirez-Lopez et al., 2013): k = 100 neighbours,
PLS-score dissimilarity, local PLS regression with 5 components,
internal leave-one-out validation.
predict_ossl_mbl( X, properties, region = "global", k = 100L, ossl_library = NULL, ... )predict_ossl_mbl( X, properties, region = "global", k = 100L, ossl_library = NULL, ... )
X |
A pre-processed numeric matrix (rows = horizons, columns = wavelengths). |
properties |
Character vector of OSSL-supported property names. |
region |
One of |
k |
Integer number of neighbours. |
ossl_library |
Optional list with the OSSL training spectra
( |
... |
Additional arguments forwarded to |
If resemble::mbl is installed and an ossl_library
artefact is supplied (a list with elements Xr, Yr)
the function delegates to resemble::mbl(); otherwise it
returns a deterministic synthetic prediction conditioned on the
input spectra so that downstream code, tests and vignettes run
without external dependencies. The fallback is annotated via the
notes attribute on the returned data.table.
A data.table with columns horizon_idx, property,
value, pi95_low, pi95_high, n_neighbors. The
"backend" attribute records which path was taken
("resemble" or "synthetic").
Ramirez-Lopez, L., Behrens, T., Schmidt, K., Stevens, A., Demattê, J. A. M., & Scholten, T. (2013). The spectrum-based learner: A new local approach for modeling soil Vis-NIR spectra of complex datasets. Geoderma, 195–196, 268–279.
Selects the k nearest neighbours to each test spectrum in
the OSSL training set and fits a local PLS regression. Like
predict_ossl_mbl, this function dispatches to
resemble::mbl (with a local_algorithm = "pls" setting)
when the dependency is available; otherwise it falls back to the
synthetic predictor.
predict_ossl_plsr_local( X, properties, region = "global", k = 100L, ossl_library = NULL, ... )predict_ossl_plsr_local( X, properties, region = "global", k = 100L, ossl_library = NULL, ... )
X |
A pre-processed numeric matrix (rows = horizons, columns = wavelengths). |
properties |
Character vector of OSSL-supported property names. |
region |
One of |
k |
Integer number of neighbours. |
ossl_library |
Optional list with the OSSL training spectra
( |
... |
Additional arguments forwarded to |
A data.table with the same schema as
predict_ossl_mbl.
Applies the OSSL-distributed pre-trained PLSR / Cubist models for a
set of soil properties to pre-processed spectra. Pre-trained models
are loaded from ossl_models, a named list of property models
that each must implement a predict(model, X) interface
returning a data.frame with columns value, pi95_low,
pi95_high. When ossl_models is NULL, the
synthetic predictor is used.
predict_ossl_pretrained( X, properties, region = "global", ossl_models = NULL, ... )predict_ossl_pretrained( X, properties, region = "global", ossl_models = NULL, ... )
X |
A pre-processed numeric matrix (rows = horizons, columns = wavelengths). |
properties |
Character vector of OSSL-supported property names. |
region |
One of |
ossl_models |
Optional named list of pre-trained models, keyed by property name. |
... |
Reserved. |
A data.table with columns horizon_idx, property,
value, pi95_low, pi95_high, n_neighbors. n_neighbors
is NA_integer_ for pre-trained models. The
"backend" attribute records which path was taken.
Numerically integrates user reflectance against the CIE 1931 2-degree
Standard Observer color-matching functions, weighted by the D65
illuminant. Returns the tristimulus values on the
standard scale where for a perfect diffuse white.
predict_xyz_from_spectra(spectra, wavelengths)predict_xyz_from_spectra(spectra, wavelengths)
spectra |
Reflectance values, in 0..1 or 0..100. A numeric vector (one sample), a numeric matrix (rows = samples, cols = wavelengths) or a data.frame. |
wavelengths |
Numeric vector of the wavelengths (in nm)
corresponding to the columns of |
A data.frame with columns X, Y, Z,
one row per sample.
predict_lab_from_spectra,
predict_munsell_from_spectra.
S3 method that applies a trained PLSR model from
train_pls_from_ossl to a (pre-processed) numeric
matrix and returns predictions plus a 95
built from the cross-validated training RMSE.
## S3 method for class 'soilKey_pls_model' predict(object, X, ...)## S3 method for class 'soilKey_pls_model' predict(object, X, ...)
object |
A |
X |
A pre-processed numeric matrix (rows = samples, columns = wavelengths). Must have the same column count used at training time. |
... |
Reserved. |
A data.frame with columns value, pi95_low,
pi95_high, one row per sample.
Applies a chosen pre-processing pipeline to a numeric matrix of
soil spectra. Rows are samples (typically horizons) and columns are
wavelengths. Returns a numeric matrix; SG-based methods shorten the
spectrum by w - 1 columns at the edges (default w = 5
so two columns are dropped from each side).
preprocess_spectra(X, method = c("snv+sg1", "snv", "sg1"), w = 5L, p = 2L)preprocess_spectra(X, method = c("snv+sg1", "snv", "sg1"), w = 5L, p = 2L)
X |
Numeric matrix or data.frame of spectra (rows = samples, columns = wavelengths). Wavelengths should be evenly spaced. |
method |
One of |
w |
Window size for the SG filter. Must be odd; default 5. |
p |
Polynomial order for the SG filter. Default 2. |
Supported method values:
"snv"Standard Normal Variate. Each row is centered on its own mean and divided by its own standard deviation.
"sg1"Savitzky-Golay 1st derivative with a window of five wavelengths and a quadratic polynomial.
"snv+sg1"SNV followed by SG1 (default; the standard pipeline used by OSSL pretrained models for Vis-NIR).
If prospectr is available, we use
prospectr::standardNormalVariate and
prospectr::savitzkyGolay (Rcpp implementation, faster and
supports arbitrary window/polynomial). The native fallback uses the
classical 5-point first-derivative coefficients
(-2, -1, 0, 1, 2) / 10, which is the closed-form
Savitzky-Golay solution for window 5 / polynomial 2 / derivative 1.
A numeric matrix. Column names (wavelengths) are preserved
where possible; SG trimming drops (w - 1) / 2
columns from each edge.
Savitzky, A., & Golay, M. J. E. (1964). Smoothing and differentiation of data by simplified least squares procedures. Analytical Chemistry, 36(8), 1627–1639.
Barnes, R. J., Dhanoa, M. S., & Lister, S. J. (1989). Standard Normal Variate transformation and de-trending of near-infrared diffuse reflectance spectra. Applied Spectroscopy, 43(5), 772–777.
Stevens, A., & Ramirez-Lopez, L. (2024). prospectr: Misc. functions for processing and sample selection of spectroscopic data. R package version 0.2.7.
set.seed(1) X <- matrix(runif(5 * 2151, 0, 1), nrow = 5) colnames(X) <- 350:2500 Xp <- preprocess_spectra(X, method = "snv+sg1") dim(Xp) # 5 x 2147 (4 columns dropped by SG window 5)set.seed(1) X <- matrix(runif(5 * 2151, 0, 1), nrow = 5) colnames(X) <- 350:2500 Xp <- preprocess_spectra(X, method = "snv+sg1") dim(Xp) # 5 x 2147 (4 columns dropped by SG window 5)
Pretic horizon (WRB 2022): "Amazonian Dark Earth" (terra preta de indio) horizon – thick anthropogenic surface with high P, SOC, and incorporated charcoal / pottery.
pretic(pedon, min_thickness = 20, min_oc = 1.5, min_p_mehlich3 = 30)pretic(pedon, min_thickness = 20, min_oc = 1.5, min_p_mehlich3 = 30)
pedon |
A |
min_thickness |
Numeric threshold or option (see Details). |
min_oc |
Numeric threshold or option (see Details). |
min_p_mehlich3 |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Print method for soilKey_pls_model
## S3 method for class 'soilKey_pls_model' print(x, ...)## S3 method for class 'soilKey_pls_model' print(x, ...)
x |
A |
... |
Reserved. |
The object, invisibly.
Returns a list describing whether the assigned RSG is plausible under the given prior. The deterministic classification is never overridden – this is purely a sanity-check signal.
prior_consistency_check(rsg_code, prior, threshold = 0.01)prior_consistency_check(rsg_code, prior, threshold = 0.01)
rsg_code |
Two-letter RSG code (e.g. |
prior |
A spatial-prior data.table from
|
threshold |
Probability below which an assignment is flagged inconsistent (default 0.01). |
A list with elements:
consistent: TRUE / FALSE / NA.
p: probability of the assigned RSG in the prior
(or NA_real_ if not found).
threshold: the threshold used.
status: a short status string – "consistent",
"inconsistent", or "no_data".
note: human-readable explanation.
top_prior: data.table with the top three
classes from the prior (for messages).
Accumulations of secondary carbonates, visible when moist, that occupy
\>= 5% of the exposed area with masses, nodules, concretions or
filaments, or cover \>= 10% of the surfaces of aggregates, biopore
walls or the undersides of coarse fragments (WRB 2022 3.2.8, p. 78).
The test reads the recorded abundance of visible secondary carbonates,
secondary_carbonates_pct (or the visual carbonate_soft_pct
plus carbonate_hard_pct). Laboratory CaCO3 is not evidence of
secondary carbonates: with no abundance recorded, a layer with no CaCO3
(caco3_pct 0, or no effervescence) has no protocalcic properties
and any other layer is undecided. A k suffix with no abundance is
undecided too, unless options(soilKey.morphological_inference =
TRUE), where it is accepted as morphological evidence.
protocalcic_properties(pedon, min_secondary_pct = 5)protocalcic_properties(pedon, min_secondary_pct = 5)
pedon |
A |
min_secondary_pct |
Minimum visible secondary carbonates, % of the exposed area (default 5). |
A DiagnosticResult recording whether the diagnostic
is present, the qualifying layers, and the supporting evidence; the
per-layer status (TRUE / FALSE / NA) is in evidence$layer_status.
Protogypsic properties (WRB 2022 Ch 3.2.9): visible secondary gypsum \>= 1% but below the gypsic gate.
protogypsic_properties(pedon, min_caso4_pct = 1, max_caso4_pct = 5)protogypsic_properties(pedon, min_caso4_pct = 1, max_caso4_pct = 5)
pedon |
A |
min_caso4_pct |
Numeric threshold or option (see Details). |
max_caso4_pct |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
A weakly developed vertic horizon – the swelling/shrinking machinery is present but does not reach the full vertic intensity (cracks too narrow, or slickensides only "few", or thickness too small). Used by the Protovertic qualifier; relevant for soils that would be Vertisols if the cracks/slickensides were a notch stronger.
protovertic(pedon, min_clay = 30, min_thickness = 15)protovertic(pedon, min_clay = 30, min_thickness = 15)
pedon |
A |
min_clay |
Numeric threshold or option (see Details). |
min_thickness |
Numeric threshold or option (see Details). |
v0.3.5 detection: clay \>= 30% AND any positive vertic evidence
(slickensides at \>= "few" OR cracks_width_cm \>= 0.2 OR a
wedge/lenticular structure_type) AND thickness \>= 15 cm. The
positive cases that pass the strict vertic_horizon
test are explicitly excluded so the two diagnostics partition the
vertic-spectrum cleanly.
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Wraps febr::readFEBR() (CRAN package, FEBR v1.9.9+ recommended)
and adapts the returned camada (layer) +
observacao tables to the soilKey schema. Auto-detects
Munsell columns across the ~6 distinct conventions found in the
200 FEBR datasets that carry color data, parses PT-BR Munsell
strings ("2,5YR 3/6") and converts FEBR's standard units
to soilKey conventions.
read_febr_pedons( dataset_codes = c("ctb0039"), febr_repo = NULL, min_munsell_coverage = 0, verbose = TRUE )read_febr_pedons( dataset_codes = c("ctb0039"), febr_repo = NULL, min_munsell_coverage = 0, verbose = TRUE )
dataset_codes |
Character vector of FEBR dataset IDs
(e.g. |
febr_repo |
Optional override for the FEBR repository
location, forwarded to |
min_munsell_coverage |
Drop pedons whose horizons are all missing Munsell. Default 0 (keep all); set to 0.5 to keep only pedons with at least 50 horizons having a Munsell hue. |
verbose |
If |
Iron (v0.9.221), from the FEBR dictionary codes (g/kg): dithionite Fe
(ferro_ditionito_*, or fe2o3_ditionito_* converted to
the element) goes to fe_dcb_pct; oxalate Fe
(ferro_oxalato_* / fe2o3_oxalato_*) to
fe_ox_pct; total Fe of the sulfuric attack, as the oxide
(fe2o3_sulfurico_*, or ferro_sulfurico_* converted), to
fe2o3_sulfuric_pct; all in %. Until v0.9.220 the first
fe2o3_* column of any method filled fe_dcb_pct,
unconverted.
Per the May 2026 scan, ~80
febr_index_munsell to get the curated list of
Munsell-bearing dataset IDs.
A list of PedonRecord objects with
site$id = FEBR observacao_id,
site$reference_sibcs = the surveyor's classification
when available, and one horizon per FEBR camada
row.
febr_index_munsell,
load_bdsolos_csv.
## Not run: # Single dataset (35 perfis, 100% Munsell coverage) pedons <- read_febr_pedons("ctb0039") # Multiple datasets pedons <- read_febr_pedons(c("ctb0032", "ctb0562", "ctb0568")) # All Munsell-bearing datasets (slow; 200 datasets, ~36k horizons) all_pedons <- read_febr_pedons("all") ## End(Not run)## Not run: # Single dataset (35 perfis, 100% Munsell coverage) pedons <- read_febr_pedons("ctb0039") # Multiple datasets pedons <- read_febr_pedons(c("ctb0032", "ctb0562", "ctb0568")) # All Munsell-bearing datasets (slow; 200 datasets, ~36k horizons) all_pedons <- read_febr_pedons("all") ## End(Not run)
Reads profiles live from ISRIC's ISIS GraphQL service and returns them as
PedonRecords, ready for classify_all or
benchmark_isis. Nothing is written to disk. Each pedon carries
the names ISRIC gives it, the licence and the citation
(isis_citation); see isis_profile_to_pedon for
what the translation reads.
read_isis( profile_codes = NULL, country = NULL, max_profiles = 100L, absent_unless_recorded = TRUE, timeout = 60, progress = NULL )read_isis( profile_codes = NULL, country = NULL, max_profiles = 100L, absent_unless_recorded = TRUE, timeout = 60, progress = NULL )
profile_codes |
Profile codes, e.g. |
country |
ISO 3166 two-letter country code, e.g. |
max_profiles |
The most profiles to read (default 100). |
absent_unless_recorded |
Passed to |
timeout |
Seconds to wait for each request (default 60). |
progress |
Optional |
A named list of PedonRecords, one per profile read.
On a failed request the profiles read until then are returned with a
warning.
## Not run: p <- read_isis(c("KE009", "ZW005")) classify_all(p$KE009) p$KE009$site$reference_wrb_full ## End(Not run)## Not run: p <- read_isis(c("KE009", "ZW005")) classify_all(p$KE009) p$KE009$site$reference_wrb_full ## End(Not run)
The everyday entry point for anyone who has a soil profile in a spreadsheet:
one row per horizon, one column per attribute, using soilKey's canonical
column names (top_cm, bottom_cm, designation,
clay_pct, ph_h2o, munsell_hue_moist, ...). The full list
is names(horizon_column_spec()); the quickest start is the bundled
template
system.file("extdata", "perfil_exemplo.csv", package = "soilKey").
read_pedon_csv(file, site = NULL, sep = "auto")read_pedon_csv(file, site = NULL, sep = "auto")
file |
Path to a |
site |
Optional named list of site metadata (see |
sep |
Field separator. |
Only recognised columns are used (any extras are carried through untouched),
so a messy export still works: soilKey uses the columns it understands, and
recognises names that differ only in capitalisation or separators and common
aliases (Clay, SOC, CEC, ...). Columns and site
properties that it does not recognise are named in a warning, with the
closest recognised names (see unrecognised_attributes). Site
metadata (id, lat/lon, soil moisture / temperature regime)
is optional and passed via site; without it the profile still
classifies, just with less specificity where site data would have refined the
name.
A PedonRecord.
classify_csv to go straight from a file to the three
classifications; classify_all; PedonRecord.
f <- system.file("extdata", "perfil_exemplo.csv", package = "soilKey") pedon <- read_pedon_csv(f) classify_all(pedon)$summaryf <- system.file("extdata", "perfil_exemplo.csv", package = "soilKey") pedon <- read_pedon_csv(f) classify_all(pedon)$summary
Turns an arbitrary spectral dataset (e.g. a Brazilian Vis-NIR/MIR library)
into the canonical list(Xr, Yr, metadata) object consumed by
fill_from_spectra and
classify_by_spectral_neighbours. Column names are mapped to the
package's canonical attributes (clay_pct, sand_pct, ..., and the taxonomic
label columns wrb_rsg / sibcs_ordem / usda_order) via a
built-in alias table (including Portuguese headers such as
argila / silte / carbono) or an explicit
property_map / label_map.
read_spectral_library( reflectance, metadata, id_col = "id", wavelengths = NULL, resample_to = NULL, property_map = NULL, label_map = NULL, normalize = c("auto", "none", "percent"), verbose = TRUE )read_spectral_library( reflectance, metadata, id_col = "id", wavelengths = NULL, resample_to = NULL, property_map = NULL, label_map = NULL, normalize = c("auto", "none", "percent"), verbose = TRUE )
reflectance |
Reflectance data: a matrix / data.frame with rows =
samples and columns named by wavelength (nm); OR a long data.frame with
|
metadata |
A data.frame with one row per sample carrying |
id_col |
Sample identifier column shared by both tables (default
|
wavelengths |
Optional explicit wavelength vector (nm) when the reflectance columns are not wavelength-named. |
resample_to |
Optional target wavelength grid (nm) to linearly resample
every spectrum onto (e.g. |
property_map, label_map
|
Optional named lists overriding the alias
auto-detection, e.g. |
normalize |
One of |
verbose |
Print a one-line summary (default |
A list with Xr (numeric reflectance matrix), Yr (data
frame of mapped properties + labels + lat/lon), and
metadata (provenance). Ready to pass as ossl_library=.
pedons_from_spectral_table,
benchmark_spectral_fill, fill_from_spectra
Fetches the layers of a single profile from ISRIC's WoSIS GraphQL endpoint and returns them in the soilKey horizon schema. Nothing is written to disk.
read_wosis_layers_graphql( profile_id, timeout = 30, max_layers = 40L, page_size = 10L, progress = NULL )read_wosis_layers_graphql( profile_id, timeout = 30, max_layers = 40L, page_size = 10L, progress = NULL )
profile_id |
A WoSIS |
timeout |
Seconds to wait for each request (default 30). |
max_layers |
Largest profile, in layers, that is read (default 40). |
page_size |
Layers per request (default 10). |
progress |
Optional |
Units are converted from ISRIC's own catalogue (organic carbon, total nitrogen and carbonate equivalent arrive in g/kg and become %), and only properties whose method matches the soilKey column are mapped: volumetric coarse fragments, saturated-paste EC, gravimetric water retention and CEC at pH 7. WoSIS serves no exchangeable bases, base saturation or Fe/Al oxides, so those columns stay empty and the classifier reports them as missing.
A data.frame of horizons in the soilKey schema, top to bottom, with
attributes "provenance" (one row per value: horizon, column, WoSIS
code, unit and method), "licence" (the most restrictive licence
among the layers), "dataset", "n_layers" and
"depth_shift_cm" (non-zero when depths were shifted so an organic
surface layer starts at 0 cm). Zero rows, with a "wosis_error"
attribute, when ISRIC cannot be reached, the profile has no layers, or it
has more than max_layers.
The endpoint is a free public service whose database cancels any statement
that runs longer than about 30 seconds, and the cost of a query grows with the
number of layers times the number of properties. The layers are therefore
counted first with a cheap query, then read in pages of page_size in a
stable order. Profiles recorded as many fine depth increments (some have 90
one-centimetre layers) exceed max_layers and are not read unless you
raise it deliberately.
wosis_profile_to_pedon, wosis_citation.
# Requires network access to ISRIC. p <- read_wosis_profiles_graphql(country = "Argentina", n_max = 1) if (nrow(p)) { h <- read_wosis_layers_graphql(p$profile_id[1]) h[, c("top_cm", "bottom_cm", "designation", "clay_pct", "oc_pct")] }# Requires network access to ISRIC. p <- read_wosis_profiles_graphql(country = "Argentina", n_max = 1) if (nrow(p)) { h <- read_wosis_layers_graphql(p$profile_id[1]) h[, c("top_cm", "bottom_cm", "designation", "clay_pct", "oc_pct")] }
Reads soil profiles straight from ISRIC's WoSIS GraphQL endpoint. Nothing is cached to disk: soilKey distributes no soil observations, and each call is made by you, to ISRIC, under ISRIC's terms.
read_wosis_profiles_graphql( country = NULL, wrb_rsg = NULL, n_max = 25L, licence_filter = c("permissive", "any"), timeout = 30, max_scan = 300L )read_wosis_profiles_graphql( country = NULL, wrb_rsg = NULL, n_max = 25L, licence_filter = c("permissive", "any"), timeout = 30, max_scan = 300L )
country |
Optional country name, e.g. |
wrb_rsg |
Optional WRB Reference Soil Group, e.g. |
n_max |
Maximum profiles to return (default 25, at most 100). |
licence_filter |
|
timeout |
Seconds to wait for each request (default 30). |
max_scan |
Most profiles examined per call (default 300). |
A data.frame, one row per profile, with profile_id,
profile_code, country, lat, lon,
wrb_rsg, usda_order, dataset, licence,
licence_short, n_layers and depth_cm. Zero rows if
nothing matched. Never throws on a network failure: it returns zero rows
with a "wosis_error" attribute, since an unreachable server is an
expected condition. Attributes "wosis_excluded" and
"wosis_excluded_licences" report what the licence filter withheld,
and "wosis_no_layers" how many profiles had no layers at all.
WoSIS is licensed per profile as each data provider specified, and
about half of it carries a NonCommercial restriction. licence_filter =
"permissive" (the default) returns only profiles free of that restriction
(CC BY, or public domain); "any" returns everything. Either way the
licence and the source dataset travel with every profile, because CC BY
requires attribution when you reuse the data. Cite the data with
wosis_citation.
The endpoint accepts at most 100 profiles per request, so profiles are read
in pages of 100, in a stable order, and at most max_scan are examined
per call. The number of layers and the depth of each listed profile come
from one light query on the layers table, which lets a caller tell a full
profile from a single topsoil sample before loading it.
wosis_profile_to_pedon to turn a row into a
PedonRecord with its horizons.
# Requires network access to ISRIC. p <- read_wosis_profiles_graphql(country = "Argentina", n_max = 5) if (nrow(p)) p[, c("profile_code", "wrb_rsg", "n_layers", "licence_short")]# Requires network access to ISRIC. p <- read_wosis_profiles_graphql(country = "Argentina", n_max = 5) if (nrow(p)) p[, c("profile_code", "wrb_rsg", "n_layers", "licence_short")]
test_reducing_conditions.Reducing conditions (WRB 2022 Ch 3.2.10) – per-pedon test wrapping
test_reducing_conditions.
reducing_conditions(pedon, min_redox_pct = 5)reducing_conditions(pedon, min_redox_pct = 5)
pedon |
A |
min_redox_pct |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Produces a pedologist-facing report from one or more
ClassificationResult objects, optionally including the
source PedonRecord. The HTML output is fully
self-contained (single file, inline CSS); the PDF output goes through
rmarkdown::render() and therefore requires a working LaTeX
install (or one of the alternative engines accepted by
rmarkdown).
report( x, file, format = c("auto", "html", "pdf"), pedon = NULL, title = NULL, include_family = FALSE, specifiers = FALSE, lang = c("en", "pt"), ... )report( x, file, format = c("auto", "html", "pdf"), pedon = NULL, title = NULL, include_family = FALSE, specifiers = FALSE, lang = c("en", "pt"), ... )
x |
A |
file |
Output path. The format is inferred from the extension
( |
format |
One of |
pedon |
Optional |
title |
Optional report title. |
include_family |
When |
specifiers |
When |
lang |
Report language; |
... |
Passed to method-specific renderers. |
This is an S3 generic with methods for ClassificationResult,
list, and PedonRecord. Most users call report()
directly with a list of three results
(list(classify_wrb2022(p), classify_sibcs(p), classify_usda(p)))
to get a cross-system one-pager.
The output path, invisibly.
pedon <- make_ferralsol_canonical() out <- file.path(tempdir(), "soilkey_report.html") report(pedon, file = out, pedon = pedon) file.exists(out)pedon <- make_ferralsol_canonical() out <- file.path(tempdir(), "soilkey_report.html") report(pedon, file = out, pedon = pedon) file.exists(out)
See report for the generic. This function writes a
single-file HTML report with inline CSS (no external network
requests, no 'htmltools' dependency) so it can be emailed or
archived as-is.
report_html( x, file, pedon = NULL, title = NULL, include_family = FALSE, specifiers = FALSE, lang = c("en", "pt"), ... )report_html( x, file, pedon = NULL, title = NULL, include_family = FALSE, specifiers = FALSE, lang = c("en", "pt"), ... )
x |
A |
file |
Output |
pedon |
Optional |
title |
Report title. |
include_family, specifiers
|
Passed through to the keys when
|
lang |
Report language; |
... |
Currently unused. |
The output path, invisibly.
See report for the generic dispatcher. This function
assembles a temporary '.Rmd' file with the same content as
report_html (site, cross-system summary, classification
cards, horizons, provenance) and renders it via
rmarkdown::render().
report_pdf( x, file, pedon = NULL, title = NULL, include_family = FALSE, specifiers = FALSE, lang = c("en", "pt"), ... )report_pdf( x, file, pedon = NULL, title = NULL, include_family = FALSE, specifiers = FALSE, lang = c("en", "pt"), ... )
x |
A |
file |
Output |
pedon |
Optional |
title |
Report title. |
include_family, specifiers
|
Passed through to the keys when
|
lang |
Report language, |
... |
Passed to |
The output path, invisibly.
Writes a single GeoPackage (.gpkg) that QGIS reads
natively, containing one POINT layer (the profile location with
all classification metadata as attributes) plus two attribute-only
tables (the horizons schema and the provenance log). Lets a
pedologist overlay the soilKey result on a soil-survey base map
or join it with field-campaign vector data without writing R or
SQL.
report_to_qgis( pedon, classifications, file, report_html = NULL, overwrite = TRUE )report_to_qgis( pedon, classifications, file, report_html = NULL, overwrite = TRUE )
pedon |
A |
classifications |
A list of one to three
|
file |
Output path ( |
report_html |
Optional path to a sibling HTML report
(rendered via |
overwrite |
If |
The output file path, invisibly. Side-effect:
writes a multi-layer GeoPackage.
The point geometry uses the pedon's site CRS
(pedon$site$crs, default EPSG:4326). When the site has no
coordinates, the function still writes the two attribute tables
but skips the point layer and emits a warning.
pedon_pointsite_id, country, year, lat, lon, crs, wrb_name, wrb_rsg, wrb_grade, wrb_principal, wrb_supplementary, sibcs_name, sibcs_ordem, sibcs_grade, usda_name, usda_order, usda_grade, n_horizons, report_html (relative path), generated_at.
horizons_tablesite_id, horizon_idx, top_cm,
bottom_cm, designation, plus the canonical
horizon_column_spec() attributes when present.
provenance_logsite_id, horizon_idx, attribute, source, confidence, notes.
report for HTML / PDF reports;
classify_from_documents for the high-level
one-liner that produces compatible classifications.
## Not run: pedon <- make_ferralsol_canonical() results <- list( wrb = classify_wrb2022(pedon, on_missing = "silent"), sibcs = classify_sibcs(pedon, include_familia = TRUE), usda = classify_usda(pedon) ) report_to_qgis(pedon, results, file = "perfil_042.gpkg", report_html = "perfil_042.html") # In QGIS: Layer -> Add Layer -> Add Vector Layer -> perfil_042.gpkg ## End(Not run)## Not run: pedon <- make_ferralsol_canonical() results <- list( wrb = classify_wrb2022(pedon, on_missing = "silent"), sibcs = classify_sibcs(pedon, include_familia = TRUE), usda = classify_usda(pedon) ) report_to_qgis(pedon, results, file = "perfil_042.gpkg", report_html = "perfil_042.html") # In QGIS: Layer -> Add Layer -> Add Vector Layer -> perfil_042.gpkg ## End(Not run)
Walks the RSG's lists of principal and supplementary qualifiers (WRB 2022
Chapter 4, in inst/rules/wrb2022/qualifiers.yaml) and tests each
qualifier against the pedon, following the rules for naming soils of
Chapter 2.2: in a slash group ("Rhodic/Xanthic") only the first
qualifier that applies is used; a qualifier made redundant by another is
left out (Eutric when Calcaric or Dolomitic applies); Haplic applies only
where the RSG lists it and no other principal qualifier does.
resolve_wrb_qualifiers(pedon, rsg_code, rules = NULL, specifiers = FALSE)resolve_wrb_qualifiers(pedon, rsg_code, rules = NULL, specifiers = FALSE)
pedon |
A |
rsg_code |
Two-letter RSG code (e.g. |
rules |
Optional pre-loaded rules list (saves I/O when many RSGs are tested). |
specifiers |
If |
Both vectors come back in the order of the name. Principal qualifiers are
written right to left, "the uppermost qualifier in the list is placed
closest to the name of the RSG", so principal reads the matched list
backwards. Supplementary qualifiers open with the texture qualifiers (top to
bottom of the profile when specifiers make several apply), then follow the
alphabetical order of the qualifier, not of the subqualifier. Until
v0.9.217 both kept the order of the old lists.
A list with principal and supplementary (character
vectors, in the order they are written in the name), trace
and trace_supplementary.
WRB 2022 Chapter 3.2.11: claric material interfingering into an argic or
natric horizon from its upper limit. soilKey reads criteria 1 and 6 from
the data, the finer-textured parts belonging to an argic or natric horizon
(argic, natric_horizon) and the interfingering
recorded at its upper limit, and stands in for criteria 2-5, 7 and 8
(claric coarser parts, colour and clay contrasts, width, 10-90% of the
sections, not in a plough layer), which no column holds, by what the
describer recorded on the uppermost argic or natric layer or the layer
directly above it: a designation matching pattern; an FAO
designation of a layer with distinct parts of an E and a B horizon
(E/B, 2E/Bt, B/E, since v0.9.312); or (since v0.9.312)
an E or claric layer whose lower boundary on the argic or natric horizon
is irregular or broken (boundary_topography), the uneven limit that
3.2.1 names as an example of retic properties.
retic_properties(pedon, pattern = "glossic|retic|albeluvic")retic_properties(pedon, pattern = "glossic|retic|albeluvic")
pedon |
A |
pattern |
Regex (default |
FALSE without an argic or natric horizon, or when designations or
boundaries are recorded and none shows the interfingering; NA when
the argic or natric horizon cannot be established or there are neither
designations nor boundary topographies. Until v0.9.219 the designation
alone decided, anywhere in the profile.
IUSS Working Group WRB (2022), Chapter 3.2.11, Retic properties.
Auto-detects which reference datasets are available locally, runs each via
benchmark_unified, adds the offline canonical sanity row and
the AfSP sample when present, and returns a tidy accuracy summary. When
report_path is given, a consolidated Markdown report is written.
run_all_benchmarks( datasets = "auto", paths = NULL, max_n = 300L, level = "order", report_path = NULL, verbose = TRUE )run_all_benchmarks( datasets = "auto", paths = NULL, max_n = 300L, level = "order", report_path = NULL, verbose = TRUE )
datasets |
|
paths |
Named list of dataset paths (see
|
max_n |
Cap on pedons per dataset (keeps the run fast). Default 300. |
level |
Comparison level forwarded where supported (currently the
suite reports at |
report_path |
File to write the Markdown report to, |
verbose |
Print progress. |
Invisibly, a list with summary (data.frame: dataset, system,
n_compared, accuracy), per_system (pooled), raw
(full benchmark_unified output), weak (zero-recall
classes) and config.
benchmark_unified, benchmark_redape.
## Not run: res <- run_all_benchmarks(max_n = 250, report_path = TRUE) res$summary ## End(Not run)## Not run: res <- run_all_benchmarks(max_n = 250, report_path = TRUE) res$summary ## End(Not run)
Opens a local Shiny app ("Pro") that drives the soilKey pipeline from a
browser – no R code required: build a pedon from a canonical fixture, a CSV
upload, or an interactive horizon editor; classify under WRB 2022 / SiBCS 5 /
USDA ST 13 with the full key trace; run VLM photo extraction, OSSL spectral
gap-fill, the SoilGrids spatial prior, an interactive leaflet map that
queries the class prior at a clicked point, and a Monte-Carlo robustness
analysis; and download a cross-system HTML or PDF report. The interface is
bilingual (English / Portuguese; see lang).
run_classify_app( ui = c("pro", "classic"), lang = c("en", "pt"), port = NULL, launch.browser = TRUE, ... )run_classify_app( ui = c("pro", "classic"), lang = c("en", "pt"), port = NULL, launch.browser = TRUE, ... )
ui |
Kept for back-compatibility. |
lang |
Initial interface language: |
port |
Port for the local server. Default lets Shiny choose. |
launch.browser |
Whether to open the app in the default
browser (default |
... |
Additional arguments passed to |
Needs the optional packages bslib, shinyWidgets, plotly
and leaflet (all in Suggests); the function raises a clear,
copy-pasteable error if any are missing.
Invisibly the value returned by shiny::runApp().
## Not run: run_classify_app() # professional multi-tab app (English) run_classify_app(lang = "pt") # interface em portugues ## End(Not run)## Not run: run_classify_app() # professional multi-tab app (English) run_classify_app(lang = "pt") # interface em portugues ## End(Not run)
Opens a Shiny app that lets a non-coder pick one of the 31 canonical profiles or upload a small horizons CSV, click Classify, and read the WRB / SiBCS / USDA names plus the deterministic key trace and the evidence grade. Useful for live demos, classroom teaching, and for pedologists who want to verify the package on a profile they already know without writing R code.
run_demo(...)run_demo(...)
... |
Forwarded to |
Requires the shiny package. The taxonomic key is still
deterministic: no VLM is invoked from the GUI.
Invisibly, the value returned by
shiny::runApp().
## Not run: soilKey::run_demo() ## End(Not run)## Not run: soilKey::run_demo() ## End(Not run)
v0.7.3: itera os Grandes Grupos da subordem em ordem canonica via o
engine generico run_taxa_list; a primeira test-block
que passa captura o perfil. Os Grandes Grupos sao carregados de
inst/rules/sibcs5/grandes-grupos/<ordem>.yaml (split por
ordem) e mergeados pelo load_rules.
run_sibcs_grande_grupo(pedon, subordem_code, rules = NULL)run_sibcs_grande_grupo(pedon, subordem_code, rules = NULL)
pedon |
A |
subordem_code |
Codigo da subordem (e.g. "OJ" para Organossolos Tiomorficos). |
rules |
Lista de regras carregada via |
Quando a subordem nao tem bloco de Grandes Grupos definido (ainda
nao wirado para todas as ordens), retorna
list(assigned = NULL, trace = list()) – comportamento
nao-fatal que permite classify_sibcs parar no 2o
nivel sem erro.
Lista com assigned (entrada YAML do Grande Grupo ou
NULL) e trace.
Roda a chave SiBCS 5a edicao sobre um pedon
run_sibcs_key(pedon, rules = NULL)run_sibcs_key(pedon, rules = NULL)
pedon |
A |
rules |
Conjunto de regras pre-carregado; se NULL, le
|
Lista com assigned (entrada YAML da ordem atribuida)
e trace.
v0.7.3.B: itera os Subgrupos do Grande Grupo em ordem canonica via o
engine generico run_taxa_list; a primeira test-block
que passa captura o perfil. Os Subgrupos sao carregados de
inst/rules/sibcs5/subgrupos/<ordem>.yaml (split por ordem) e
mergeados pelo load_rules.
run_sibcs_subgrupo(pedon, gg_code, rules = NULL)run_sibcs_subgrupo(pedon, gg_code, rules = NULL)
pedon |
A |
gg_code |
Codigo do Grande Grupo (e.g. "OJF" para Organossolos Tiomorficos Fibricos). |
rules |
Lista de regras carregada via |
Em contraste com o 3o nivel (Grandes Grupos de Organossolos),
Subgrupos de Cap 14 SEMPRE tem catch-all tests:{default:true}
como ultima entrada de cada lista (subgrupo "tipico"), entao a
classificacao sempre desce ao 4o nivel quando o GG foi resolvido.
Lista com assigned (entrada YAML do Subgrupo ou
NULL) e trace.
Itera as subordens da ordem em ordem canonica via o engine generico
run_taxa_list; a primeira cuja test-block passa captura
o perfil. Se nenhuma passar, retorna a ultima subordem (catch-all
tests:{default:true}).
run_sibcs_subordem(pedon, ordem_code, rules = NULL)run_sibcs_subordem(pedon, ordem_code, rules = NULL)
pedon |
A |
ordem_code |
Codigo de uma letra da ordem (e.g. "L" para Latossolos). |
rules |
Lista de regras carregada via |
Lista com assigned (entrada YAML da subordem ou
NULL se a ordem nao tiver bloco) e trace.
Internal iterator extracted from run_taxonomic_key so
nested categorical levels (subordens, grandes grupos, subgrupos,
familias) can be iterated directly, without going through the
rules[[level_key]] indirection that only makes sense at the
top level.
run_taxa_list(pedon, taxa)run_taxa_list(pedon, taxa)
pedon |
A |
taxa |
A list of taxon entries; each entry must have
|
Behavioural note: when taxa is empty or NULL, returns
list(assigned = NULL, trace = list()) – a sub-level lookup
with no canonical entries is non-fatal. The top-level
run_taxonomic_key keeps the stricter "missing list is
an error" semantics by guarding before calling this helper.
A list with assigned (the entry of the assigned taxon,
or NULL when taxa was empty) and trace.
Iterates over the taxa list at rules[[level_key]] in
canonical order; the first taxon whose tests pass is assigned.
evaluate_rsg_tests is reused as the per-taxon evaluator
regardless of system – the test combinator semantics
(all_of / any_of / default /
not_implemented_v01) are the same in all three systems.
run_taxonomic_key(pedon, rules, level_key)run_taxonomic_key(pedon, rules, level_key)
pedon |
A |
rules |
A parsed rule set (output of |
level_key |
Name of the taxa list inside |
Used at the TOP level (RSG / Order / Ordem). For nested categorical
levels (subordens, grandes grupos, subgrupos, familias) iterate the
flat taxa list directly via run_taxa_list.
A list with assigned (the YAML entry of the assigned
taxon) and trace (one entry per taxon tested).
Run the USDA Great Group key for a given Suborder
run_usda_great_group(pedon, suborder_code, rules = NULL)run_usda_great_group(pedon, suborder_code, rules = NULL)
pedon |
A |
suborder_code |
The Suborder code (e.g. "AA" for Histels). |
rules |
Optional pre-loaded rule set. |
A list with assigned and trace; assigned is
NULL if the Suborder has no great-groups YAML.
Run the USDA Soil Taxonomy Order key over a pedon
run_usda_key(pedon, rules = NULL)run_usda_key(pedon, rules = NULL)
pedon |
A |
rules |
Optional pre-loaded rule set; if NULL, reads
|
A list with assigned (the YAML entry of the assigned
Order) and trace.
Run the USDA Subgroup key for a given Great Group
run_usda_subgroup(pedon, great_group_code, rules = NULL)run_usda_subgroup(pedon, great_group_code, rules = NULL)
pedon |
A |
great_group_code |
The Great Group code (e.g. "AAA" for Folistels). |
rules |
Optional pre-loaded rule set. |
A list with assigned and trace; assigned is
NULL if the Great Group has no subgroups YAML.
Run the USDA Suborder key for a given Order
run_usda_suborder(pedon, order_code, rules = NULL)run_usda_suborder(pedon, order_code, rules = NULL)
pedon |
A |
order_code |
The Order code (e.g. "GE" for Gelisols). |
rules |
Optional pre-loaded rule set. |
A list with assigned and trace; assigned is
NULL if the Order has no suborders YAML.
Iterates over the RSGs in canonical key order; the first RSG whose tests pass is assigned. RSGs whose tests return NA (stubbed diagnostics or insufficient data) are skipped and recorded in the trace.
run_wrb_key(pedon, rules = NULL)run_wrb_key(pedon, rules = NULL)
pedon |
A |
rules |
Optional pre-loaded rule set; if NULL, reads
|
A list with assigned (the YAML entry for the assigned
RSG) and trace (one entry per RSG tested, in order).
Tests whether any horizon meets the salic horizon criteria. The salic horizon is a horizon of soluble-salt accumulation, diagnostic for Solonchaks.
salic( pedon, min_thickness = 15, min_ec_dS_m = 15, alkaline_min_ec_dS_m = 8, alkaline_min_pH = 8.5, min_product = 450, alkaline_min_product = 240 )salic( pedon, min_thickness = 15, min_ec_dS_m = 15, alkaline_min_ec_dS_m = 8, alkaline_min_pH = 8.5, min_product = 450, alkaline_min_product = 240 )
pedon |
A |
min_thickness |
Minimum thickness in cm (default 15). |
min_ec_dS_m |
Primary EC threshold (default 15 dS/m at 25C). |
alkaline_min_ec_dS_m |
Alkaline-path EC threshold (default 8
dS/m, used when pH(H2O) \>= |
alkaline_min_pH |
Required pH(H2O) for alkaline path (default 8.5). |
min_product |
Primary path product (EC * thickness in dS/m * cm) threshold (default 450 per WRB 2022). |
alkaline_min_product |
Alkaline-path product threshold (default 240). |
Sub-tests called:
test_ec_concentration – EC \>= 15 dS/m
(primary) OR (EC \>= 8 dS/m AND pH(H2O) \>= 8.5)
(alkaline).
test_minimum_thickness – thickness \>= 15 cm.
test_salic_product – EC * thickness product
\>= 450 (primary) or \>= 240 (alkaline) per qualifying
layer.
v0.3.1: alkaline-path and product test added (WRB 2022 Ch 3.1.20, p. 49). Earlier versions only enforced the primary EC + thickness gate.
IUSS Working Group WRB (2022). World Reference Base for Soil Resources, 4th edition. International Union of Soil Sciences, Vienna. Chapter 3.1.20 – Salic horizon (p. 49).
Material organico altamente decomposto: < 17% de fibras esfregadas OU indice de von Post H7-H10. Discrimina Organossolos Sapricos no 3o nivel categorico.
saprico(pedon)saprico(pedon)
pedon |
A |
Embrapa (2018), SiBCS 5a ed., Cap 14 (Organossolos), pp 224-226.
Thin wrappers around saveRDS / readRDS that also
verify the deserialised object's shape. The on-disk file carries
the soilKey version, training time and preprocess label as
attributes; load_ossl_models preserves them.
save_ossl_models(models, path) load_ossl_models(path)save_ossl_models(models, path) load_ossl_models(path)
models |
Output of |
path |
File path. Use |
save_ossl_models() returns path invisibly.
load_ossl_models() returns the model list.
test_shrink_swell_cracks.Shrink-swell cracks (WRB 2022 Ch 3.2.12) – per-pedon test wrapping
test_shrink_swell_cracks.
shrink_swell_cracks(pedon, min_width_cm = 0.5)shrink_swell_cracks(pedon, min_width_cm = 0.5)
pedon |
A |
min_width_cm |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Mineral material with a relatively low CEC. WRB 2022 (3.2.13) requires BOTH:
one or both of: clay >= 8% AND CEC/clay < 24 cmol_c/kg clay; OR bulk CEC < 2 cmol_c/kg soil;
evidence of soil formation as defined in criterion 3 of the cambic
horizon (test_cambic_soil_formation).
Both must be met by the SAME layer. Criterion 2 was added in v0.9.127
(previously only criterion 1 was enforced); where the soil-formation
evidence cannot be assessed (no Munsell/clay/Fe/carbonate adjacency data)
the result is NA rather than a false positive.
sideralic_properties(pedon, max_cec_per_clay = 24, max_bulk_cec = 2)sideralic_properties(pedon, max_cec_per_clay = 24, max_bulk_cec = 2)
pedon |
A |
max_cec_per_clay |
Numeric threshold or option (see Details). |
max_bulk_cec |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
One row per site property that soilKey recognises (the named elements of
PedonRecord$site), with the section it belongs to, its type, unit
and description, the values a categorical property takes where the keys
compare it with a fixed set, and the classification keys that read it. The
properties of the last section, reference classes and provenance,
are stored by the loaders and reports and read by no key. The metadata
come from inst/schemas/site-attributes.yaml; the attribute reference
inst/ATTRIBUTES.md lists them after the horizon attributes.
site_attribute_spec()site_attribute_spec()
A data.frame with the columns name, type,
section, unit, description, and allowed and
systems (comma-separated, empty when none).
horizon_attribute_spec,
unrecognised_attributes.
s <- site_attribute_spec() s[s$name %in% c("drainage_class", "soil_moisture_regime"), c("name", "type", "description")]s <- site_attribute_spec() s[s$name %in% c("drainage_class", "soil_moisture_regime"), c("name", "type", "description")]
Returns a ranked list of the soil Reference Soil Groups (or SiBCS ordens, or USDA orders) most likely to occur at the given point, based on a global or regional dominant-soil raster (SoilGrids 2.0 by default). This is the **before-you-have-a-pedon helper**: a pedologist arriving in the field can call it with the GPS coordinates of the planned profile pit and see which classes are expected, plus what attributes typically distinguish them.
soil_classes_at_location( lat, lon, system = c("wrb2022", "sibcs", "usda"), buffer_m = 1000, source_url = NULL, top_n = 5, verbose = TRUE )soil_classes_at_location( lat, lon, system = c("wrb2022", "sibcs", "usda"), buffer_m = 1000, source_url = NULL, top_n = 5, verbose = TRUE )
lat, lon
|
Numeric WGS-84 coordinates. |
system |
Classification system. One of |
buffer_m |
Radius in metres around the point used to gather raster pixels (default 1000 m, i.e. roughly 4 SoilGrids pixels). |
source_url |
Path / URL of the dominant-soil raster. |
top_n |
Keep the top N classes by probability (default 5). |
verbose |
Emit a |
This function does not classify a profile. The
deterministic key in classify_wrb2022 /
classify_sibcs / classify_usda remains
the only thing that assigns a class from horizon data. The output
here is purely informational – a "shopping list" of what to
confirm.
A list as described under Output.
For real use, point source_url at a regional SoilGrids
"MostProbable WRB" GeoTIFF / COG (one of the cuts at
https://files.isric.org/soilgrids/latest/data/wrb/). For
tests, options(soilKey.test_raster = "/tmp/syn.tif") is
honoured. When no source is given, the function emits a
cli_alert_warning() and returns an empty result – it does
not pretend to know.
A list with three elements:
distributionA data.table with columns
rsg_code, rsg_name, probability,
sorted by descending probability.
typical_attributesA data.table keyed by
rsg_code with the canonical attribute ranges that
distinguish each class (clay range, CEC range, BS range,
etc.). The values come from the WRB 2022 / SiBCS 5 /
KST 13ed canonical thresholds, NOT from the raster.
siteThe site list passed in, plus the buffer radius and the source URL.
spatial_prior_soilgrids for the
post-classification consistency check.
## Not run: # Mata Atlântica, Rio de Janeiro state. res <- soil_classes_at_location( lat = -22.7, lon = -43.7, system = "wrb2022", source_url = "https://files.isric.org/soilgrids/latest/data/wrb/MostProbable.vrt" ) res$distribution # ranked list of likely RSGs res$typical_attributes # canonical thresholds per RSG to confirm ## End(Not run)## Not run: # Mata Atlântica, Rio de Janeiro state. res <- soil_classes_at_location( lat = -22.7, lon = -43.7, system = "wrb2022", source_url = "https://files.isric.org/soilgrids/latest/data/wrb/MostProbable.vrt" ) res$distribution # ranked list of likely RSGs res$typical_attributes # canonical thresholds per RSG to confirm ## End(Not run)
Soil organic carbon (WRB 2022 Ch 3.3.16): organic C that does NOT belong to artefacts. v0.3.3: any layer with oc_pct >= 0.1 and artefacts_industrial_pct < 35.
soil_organic_carbon(pedon, min_oc = 0.1, max_artefacts = 35)soil_organic_carbon(pedon, min_oc = 0.1, max_artefacts = 35)
pedon |
A |
min_oc |
Numeric threshold or option (see Details). |
max_artefacts |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Reserved for the future SoilGrids USDA layer. Currently returns the 12 USDA Order codes mapped to integers 1..12.
soilgrids_usda_lut()soilgrids_usda_lut()
Named character vector.
Maps the integer raster values used by the SoilGrids 2.0
"MostProbable WRB" layer to soilKey's two-letter RSG codes (the
codes used in inst/rules/wrb2022/key.yaml).
soilgrids_wrb_lut()soilgrids_wrb_lut()
The numeric values follow the order used by ISRIC; users with a
different convention can override this via the lut argument
to spatial_prior_soilgrids.
Named character vector: names are integer-as-character
("1", "2", ...), values are RSG codes.
Lists the classification systems registered in the package, one row per
system, in the order classify_all runs them. Each system is a
folder inst/rules/<id>/ holding its key and a system.yaml
entry. The id is what load_rules and
classify_all accept; the aliases are accepted too.
soilkey_systems()soilkey_systems()
A data.frame with one row per system and the columns
id, name (English display name), edition,
status, classifier (the function that classifies a
PedonRecord in that system), levels and
aliases (both comma-separated), and default (whether
classify_all(systems = "all") runs the system).
soilkey_systems()soilkey_systems()
rock_origin == "colluvial" OR layer_origin ==
"solimovic".Solimovic material (WRB 2022 Ch 3.3.17): hetero genous mass-movement
material on slopes / footslopes (formerly "colluvic"). v0.3.3: detects
via rock_origin == "colluvial" OR layer_origin ==
"solimovic".
solimovic_material(pedon)solimovic_material(pedon)
pedon |
A |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Sombric horizon (WRB 2022): subsurface accumulation of humus that qualified neither as spodic nor as a true mollic-like horizon (low-base-saturation cool tropical highlands). v0.3.3 detects via designation pattern + OC criteria (BS < 50, OC > 0.6, depth > 25 cm).
sombric( pedon, min_thickness = 15, min_oc = 0.6, max_bs = 50, min_top_cm = 25, min_oc_increase = 0.1 )sombric( pedon, min_thickness = 15, min_oc = 0.6, max_bs = 50, min_top_cm = 25, min_oc_increase = 0.1 )
pedon |
A |
min_thickness |
Numeric threshold or option (see Details). |
min_oc |
Numeric threshold or option (see Details). |
max_bs |
Numeric threshold or option (see Details). |
min_top_cm |
Numeric threshold or option (see Details). |
min_oc_increase |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Top-level dispatcher. Reads a categorical raster of soil classes (SoilGrids globally, Embrapa for Brazil), buffers the pedon's coordinates, tallies pixel classes within the buffer, and returns the empirical class frequency as a probability distribution.
spatial_prior( pedon, source = c("soilgrids", "embrapa"), system = c("wrb2022", "usda"), ... )spatial_prior( pedon, source = c("soilgrids", "embrapa"), system = c("wrb2022", "usda"), ... )
pedon |
A |
source |
Backend to query: |
system |
Classification system: |
... |
Passed through to the backend
( |
The prior is intentionally separate from the deterministic key.
Pass the returned data.table to classify_wrb2022 via
the prior argument; the result will then carry a
prior_check entry (consistent / inconsistent / not_run).
A data.table with columns rsg_code (character)
and probability (numeric, summing to 1). Empty if the
buffer extracts no valid pixels – callers should check
nrow().
v0.5 stub. Reads a user-provided categorical raster of SiBCS orders / suborders, buffers the pedon's site, tallies pixel classes, and returns a probability distribution over SiBCS codes (or, with a user-provided LUT, over WRB equivalents).
spatial_prior_embrapa( pedon, raster_path = NULL, buffer_m = 3750, lut = NULL, n_classes_top = 10, ... )spatial_prior_embrapa( pedon, raster_path = NULL, buffer_m = 3750, lut = NULL, n_classes_top = 10, ... )
pedon |
A |
raster_path |
Required. Path to a local categorical raster
(GeoTIFF) of Embrapa SiBCS classes. There is no built-in
file in v0.5 – download the polygon map from
|
buffer_m |
Buffer radius in metres (default 3750, i.e. ~15-cell neighbourhood at 250 m resolution). |
lut |
Optional named character vector mapping raster integer values to soil-class codes. If NULL, raster categories are used as-is (terra::levels). |
n_classes_top |
Keep only the top N classes (default 10). |
... |
Reserved. |
Unlike SoilGrids, Embrapa does not publish per-pixel probabilities, so the empirical frequency over a neighbourhood window (default 15 x 15 cells = ~3.75 km radius at 250 m resolution) is used as an approximation.
A data.table with columns rsg_code,
probability.
Reads a categorical raster of dominant Reference Soil Groups around the pedon's site, buffers the point in metric coordinates, extracts all pixel values within the buffer, and returns the empirical class frequency as a probability distribution over RSG codes.
spatial_prior_soilgrids( pedon, system = c("wrb2022", "usda"), buffer_m = 250, source_url = NULL, n_classes_top = 10, lut = NULL, ... )spatial_prior_soilgrids( pedon, system = c("wrb2022", "usda"), buffer_m = 250, source_url = NULL, n_classes_top = 10, lut = NULL, ... )
pedon |
A |
system |
Classification system; |
buffer_m |
Buffer radius in metres around the point (default 250 m, i.e. one SoilGrids pixel). |
source_url |
Optional. A path or URL accepted by
|
n_classes_top |
Keep only the top N classes by frequency
(default 10). Set to |
lut |
Optional named integer vector mapping raster values to
RSG codes. Default is |
... |
Reserved for future use. |
A data.table with columns rsg_code,
probability.
For real use, pass source_url pointing at a SoilGrids
"MostProbable WRB" GeoTIFF / COG, e.g. one of the regional cuts
published at https://files.isric.org/soilgrids/latest/data/wrb/.
For tests, set options(soilKey.test_raster = "/path/to/syn.tif")
to point at a local synthetic raster – this avoids network access
in CI.
We use sf::st_transform when sf is available; otherwise we
fall back to terra::project on a single-point SpatVector.
The buffer is constructed in metric (UTM) coordinates so
buffer_m is in metres regardless of the pedon CRS. The
raster itself is queried in its native CRS via terra's automatic
reprojection.
spatial_prior, soilgrids_wrb_lut.
Tests whether any horizon meets the spodic horizon criteria. The spodic horizon is an illuvial horizon with active Al + Fe oxalate- extractable material plus organic matter; diagnostic of Podzols.
spodic( pedon, min_thickness = 2.5, min_alfe = 0.5, max_ph = 5.9, min_oc_in_b = 0.5, engine = NULL )spodic( pedon, min_thickness = 2.5, min_alfe = 0.5, max_ph = 5.9, min_oc_in_b = 0.5, engine = NULL )
pedon |
A |
min_thickness |
Minimum thickness in cm (default 2.5). |
min_alfe |
Minimum (Al_ox + 0.5 * Fe_ox) percent (default 0.5). |
max_ph |
Maximum ph_h2o (default 5.9). |
min_oc_in_b |
Minimum OC % in the candidate Bh / Bs layer for the v0.9.19 morphological inference path when Al / Fe oxalate are missing (default 0.5). |
engine |
One of |
Sub-tests:
test_spodic_aluminum_iron – (Al_ox +
0.5*Fe_ox) >= 0.5%
test_ph_below – ph_h2o <= 5.9
test_minimum_thickness – thickness >= 2.5 cm
v0.2 limitations: the WRB color criterion (hue 5YR or yellower with chroma <= 5, or specific dark colors) is not enforced. The (Al_ox + Fe_ox)/clay >= 0.05 alternative ratio test is not yet wired. Both deferred to v0.3.
KSSL+NASIS Spodosols routinely use generic "B1" / "B2" / "Bw" designations rather than the specific Bh / Bs / Bhs that the v0.9.19 morphological-inference path requires. Of 14 KSSL+NASIS Podzol references, only 1 / 14 passes spodic via the v0.9.19 path; 7 / 14 have BOTH an E-designated albic-eligible horizon above AND an OC peak in a B horizon below (the canonical Podzol illuviation signature) but use generic B / Bw designations and so fail strict morph.
When engine = "aqp" (read from
getOption("soilKey.diagnostic_engine", "soilkey") when
engine is NULL) AND Al / Fe oxalate is unmeasured
AND the v0.9.19 strict path did not fire, accept any
B* designation below an E*-designated horizon when:
ph_h2o <= max_ph in the B horizon, AND
oc_pct >= min_oc_in_b in the B horizon, AND
OC in the B is greater than the maximum OC in any horizon above (the translocation signature).
Default engine is "soilkey" – canonical behaviour
bit-for-bit preserved.
IUSS Working Group WRB (2022), Chapter 3, Spodic horizon.
Convenience wrapper for canonical_reference("ST_features").
Returns an 84-row data.frame with one row per diagnostic feature
(epipedon / subsurface horizon / property / material) and columns:
group, name, chapter, page, description, criteria. The
criteria column is a list-column; each element holds the
parsed criteria text per feature.
st_features_canonical(prefer_pkg = TRUE)st_features_canonical(prefer_pkg = TRUE)
prefer_pkg |
Retained for compatibility and no longer used. Until
v0.9.203 |
The canonical Soil Taxonomy diagnostic-features reference (a list / data.frame).
Tests for stagnic properties (WRB 2022 Ch 3.2.14, p. 81) in a layer
starting within the upper max_top_cm (default 100).
stagnic_properties( pedon, max_top_cm = 100, min_redox_pct = 5, decay_factor = 3 )stagnic_properties( pedon, max_top_cm = 100, min_redox_pct = 5, decay_factor = 3 )
pedon |
A |
max_top_cm |
Maximum top depth (cm) of candidate layers (default 100). |
min_redox_pct |
The oximorphic features are more than this % of the layer (default 5). |
decay_factor |
Not used since v0.9.312 (the decay test was removed); kept so that existing calls still work. |
Since v0.9.312 the layer reading is that of gleyic_properties
(Hugo's reading for descriptions that do not say where the mottles sit):
a layer with more than 5% oximorphic features that are not gleyic
(criteria 1-3: the matrix has no reductimorphic colour, the layer does
not lie directly on a layer with such a matrix, and the site records no
groundwater within 150 cm that is not perched, or a claric layer lies
directly above it); a layer with claric colours in 95% or more of
its area above an abrupt textural difference or a layer of 1.5 kg/dm3 or
more (criterion 4), or above a layer with stagnic oximorphic features
(criterion 5). Mottles with neither colour nor water evidence leave the
layer NA. Until v0.9.311 a layer with 5% redox features passed when
the features decayed with depth, which is not in WRB 2022.
IUSS Working Group WRB (2022), Chapter 3.2.14, Stagnic properties.
Discrimina os Subgrupos espessos de Planossolos (Cap 15:
SNs Espessos, SNo Espessos, SXs Espessos, SXal Espessos,
SXd Espessos, SXe Espessos): B planico cujo topo ocorre entre
min_top_cm (exclusivo) e max_top_cm (inclusivo).
subgrupo_planossolo_espessos(pedon, min_top_cm = 100, max_top_cm = 200)subgrupo_planossolo_espessos(pedon, min_top_cm = 100, max_top_cm = 200)
pedon |
A |
min_top_cm |
Profundidade minima exclusiva do topo do B planico (default 100; passa se top > 100). |
max_top_cm |
Profundidade maxima inclusiva (default 200). |
Implementacao: identifica B planico via
B_planico, captura o topo (mais raso) das camadas
que passam, e testa se cai em (min_top_cm, max_top_cm].
Embrapa (2018), SiBCS 5a ed., Cap 15 (Planossolos), pp 251-260.
Discrimina os Subgrupos mesicos de Planossolos (Cap 15:
SNs Mesicos, SNo Mesicos, SXs Mesicos, SXal Mesicos, SXd Mesicos,
SXe Mesicos): B planico cujo topo ocorre entre min_top_cm
(inclusivo) e max_top_cm (inclusivo).
subgrupo_planossolo_mesicos(pedon, min_top_cm = 50, max_top_cm = 100)subgrupo_planossolo_mesicos(pedon, min_top_cm = 50, max_top_cm = 100)
pedon |
A |
min_top_cm |
Profundidade minima inclusiva (default 50). |
max_top_cm |
Profundidade maxima inclusiva (default 100). |
Embrapa (2018), SiBCS 5a ed., Cap 15 (Planossolos).
Discrimina o Subgrupo FFcoEn (Plintossolos Petricos Concrecionarios
endicos): horizonte concrecionario cujo topo ocorre a >=
min_top_cm cm.
subgrupo_plintossolo_endico_concrecionario(pedon, min_top_cm = 40)subgrupo_plintossolo_endico_concrecionario(pedon, min_top_cm = 40)
pedon |
A |
min_top_cm |
Profundidade minima inclusiva (default 40). |
Embrapa (2018), SiBCS 5a ed., Cap 16, p 264.
Discrimina o Subgrupo FFlpEn (Plintossolos Petricos Litoplinticos
endicos): horizonte litoplintico cujo topo ocorre a >=
min_top_cm cm.
subgrupo_plintossolo_endico_litoplintico(pedon, min_top_cm = 40)subgrupo_plintossolo_endico_litoplintico(pedon, min_top_cm = 40)
pedon |
A |
min_top_cm |
Profundidade minima inclusiva (default 40). |
Embrapa (2018), SiBCS 5a ed., Cap 16, p 264.
Discrimina os Subgrupos espessos de Plintossolos Argiluvicos
(FT*Es) e Haplicos (FXacEs, FXdEs, FXeEs): horizonte plintico cujo
topo ocorre entre min_top_cm (exclusivo) e
max_top_cm (inclusivo).
subgrupo_plintossolo_espessos(pedon, min_top_cm = 100, max_top_cm = 200)subgrupo_plintossolo_espessos(pedon, min_top_cm = 100, max_top_cm = 200)
pedon |
A |
min_top_cm |
Profundidade minima exclusiva (default 100). |
max_top_cm |
Profundidade maxima inclusiva (default 200). |
Embrapa (2018), SiBCS 5a ed., Cap 16 (Plintossolos), pp 261-272.
test_takyric_surface.Takyric properties (WRB 2022 Ch 3.2.15) – per-pedon test wrapping
test_takyric_surface.
takyric_properties(pedon)takyric_properties(pedon)
pedon |
A |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Tests for any of three WRB 2022 alternative qualifying conditions for Technosols:
Artefacts >= artefacts_min_pct (default 20%) by
volume within the upper max_top_cm (default 100 cm).
A continuous geomembrane (geomembrane_present == TRUE)
within the upper 100 cm.
Technic hard material (concrete, asphalt, mine spoil) with
technic_hardmaterial_pct >= hardmaterial_min_pct
(default 95%) at the surface (top_cm <=
hardmaterial_max_top_cm, default 5).
Either path qualifies.
technic_features( pedon, artefacts_min_pct = 20, max_top_cm = 100, hardmaterial_min_pct = 95, hardmaterial_max_top_cm = 5 )technic_features( pedon, artefacts_min_pct = 20, max_top_cm = 100, hardmaterial_min_pct = 95, hardmaterial_max_top_cm = 5 )
pedon |
A |
artefacts_min_pct |
Minimum artefact percent (default 20). |
max_top_cm |
Maximum top depth (cm) for the artefact and geomembrane paths (default 100). |
hardmaterial_min_pct |
Minimum hard-material coverage (%) for the technic-hard-material path (default 95). |
hardmaterial_max_top_cm |
Surface depth window (cm) for the technic-hard-material path (default 5). |
IUSS Working Group WRB (2022), Chapter 5, Technosols.
Technic hard material (WRB 2022 Ch 3.3.18): consolidated human-made material (asphalt, concrete, worked stones).
technic_hard_material(pedon)technic_hard_material(pedon)
pedon |
A |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Tephric material (WRB 2022 Ch 3.3.19): \>= 30% volcanic glass in 0.02-2 mm fraction AND no andic / vitric properties.
tephric_material(pedon, min_glass = 30)tephric_material(pedon, min_glass = 30)
pedon |
A |
min_glass |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Terric horizon (WRB 2022): topsoil thickened by long-term application of mineral material (sediment / sand additions). v0.3.3: thickness >= 20 cm + designation Au / Apc.
terric(pedon, min_thickness = 20)terric(pedon, min_thickness = 20)
pedon |
A |
min_thickness |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
aqp's getArgillicBounds() requires an NRCS texture class
column (e.g. "SCL", "C", "CL", "FS"). soilKey horizons only carry
the percent fractions; this helper derives the class from the
standard USDA texture triangle.
texture_class_from_pct(clay, silt, sand)texture_class_from_pct(clay, silt, sand)
clay |
Numeric vector of clay percent (0-100). |
silt |
Numeric vector of silt percent. |
sand |
Numeric vector of sand percent. (clay + silt + sand should sum to ~100; mild deviations are tolerated.) |
Returns the standard NRCS abbreviation:
| COS | Coarse sand |
| S | Sand |
| FS | Fine sand |
| VFS | Very fine sand |
| LS | Loamy sand |
| LFS | Loamy fine sand |
| SL | Sandy loam |
| FSL | Fine sandy loam |
| L | Loam |
| SIL | Silt loam |
| SI | Silt |
| SCL | Sandy clay loam |
| CL | Clay loam |
| SICL | Silty clay loam |
| SC | Sandy clay |
| SIC | Silty clay |
| C | Clay |
Implementation follows the canonical USDA texture triangle; vector- ised over the input. NA in / NA out.
Character vector of NRCS texture class abbreviations.
Thionic horizon (WRB 2022): post-oxidation acid sulfate horizon. Requires sulfidic_s_pct >= 0.01 AND pH(H2O) <= 4.
thionic( pedon, min_thickness = 15, max_pH = 4, min_sulfidic_s = 0.01, adjoining = FALSE )thionic( pedon, min_thickness = 15, max_pH = 4, min_sulfidic_s = 0.01, adjoining = FALSE )
pedon |
A |
min_thickness |
Numeric threshold or option (see Details). |
max_pH |
Numeric threshold or option (see Details). |
min_sulfidic_s |
Numeric threshold or option (see Details). |
adjoining |
|
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Iterates over properties and fits one PLSR model per target
against the OSSL spectra in ossl_library$Xr, with internal
cross-validation to pick the optimal number of components per
property. The returned list is a drop-in replacement for the
ossl_models argument of predict_ossl_pretrained
and fill_from_spectra.
train_pls_from_ossl( ossl_library, properties = c("clay_pct", "sand_pct", "silt_pct", "cec_cmol", "ph_h2o", "oc_pct"), ncomp_max = 20L, validation = c("CV", "LOO", "none"), segments = 10L, preprocess = "snv+sg1", min_n = 50L, verbose = TRUE )train_pls_from_ossl( ossl_library, properties = c("clay_pct", "sand_pct", "silt_pct", "cec_cmol", "ph_h2o", "oc_pct"), ncomp_max = 20L, validation = c("CV", "LOO", "none"), segments = 10L, preprocess = "snv+sg1", min_n = 50L, verbose = TRUE )
ossl_library |
A list with two named elements: |
properties |
Character vector of column names in
|
ncomp_max |
Integer. Upper bound on the number of PLS components to consider during cross-validation. Defaults to 20. |
validation |
One of |
segments |
Number of CV segments when
|
preprocess |
Pre-processing label passed to
|
min_n |
Minimum number of valid training samples (after dropping rows with non-finite y or X). Properties below this threshold are skipped with a warning. Default 50. |
verbose |
If |
Spectra are pre-processed inside the function (default
"snv+sg1"); the same preprocessing is used downstream by
predict_from_spectra so the user does not have to
remember which transform was applied at training time.
A named list of soilKey_pls_model objects, one per
successfully trained property. Carries
trained_at, soilKey_version and
preprocess attributes for provenance.
## Not run: lib <- download_ossl_subset(region = "south_america") models <- train_pls_from_ossl(lib, properties = c("clay_pct", "ph_h2o")) result <- predict_from_spectra(my_pedon, models = models) ## End(Not run)## Not run: lib <- download_ossl_subset(region = "south_america") models <- train_pls_from_ossl(lib, properties = c("clay_pct", "ph_h2o")) result <- predict_from_spectra(my_pedon, models = models) ## End(Not run)
From Georgian tsiteli = red. A red colour-defined horizon formed on weathered basalt or similar Fe-rich parent material in Caucasian / Mediterranean settings. Used by the Cambisols key (Ch 4 p 123, criterion 4) and by the Tsitelic qualifier.
tsitelic(pedon, min_thickness = 10)tsitelic(pedon, min_thickness = 10)
pedon |
A |
min_thickness |
Numeric threshold or option (see Details). |
Diagnostic criteria (v0.3.5 simplification):
Munsell hue \<= 2.5YR (i.e. 2.5YR, 10R, 7.5R, 5R, 2.5R) AND value \<= 4 (moist) AND chroma \>= 4 (moist);
evidence of soil formation (cambic-style criterion 3)
proxied by clay \>= 8% AND structure_grade not
"single grain" / "massive";
thickness \>= 10 cm.
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Tests for the umbric horizon – a thick, dark, organic-rich surface horizon like mollic, but with low base saturation (< 50%). Diagnostic of Umbrisols.
umbric_horizon( pedon, min_thickness = 20, min_oc = 0.6, max_bs = 50, surface_top_cm = 5 )umbric_horizon( pedon, min_thickness = 20, min_oc = 0.6, max_bs = 50, surface_top_cm = 5 )
pedon |
A |
min_thickness |
Minimum thickness (cm; default 20). |
min_oc |
Minimum SOC % (default 0.6). |
max_bs |
Maximum base saturation % (default 50; profile must be BELOW this). |
surface_top_cm |
Maximum depth (cm) below the mineral soil surface at which the stack may start (default 5). |
Implementation reuses the mollic sub-tests on the contiguous stack of
dark layers from the mineral soil surface (organic layers on top are
not part of it), and tests the weighted average base saturation of the
stack against max_bs (WRB 2022 3.1.39, pp. 69-70).
IUSS Working Group WRB (2022), Chapter 3.1.39, Umbric horizon (pp. 69-70).
Lists the horizon columns and site properties that no classification key
reads: a horizon column that is neither a canonical name of
horizon_column_spec nor one that
ensure_horizon_schema renames onto it (a difference of
capitalisation or separators, or a common alias such as SOC), and a
site property that is not in site_attribute_spec. Such
attributes are kept in a PedonRecord but have no effect on a
classification. PedonRecord$new() warns about them when it is called
from outside the package, and so does read_pedon_csv;
options(soilKey.warn_unrecognised = FALSE) turns the warning off.
unrecognised_attributes(x, site = NULL)unrecognised_attributes(x, site = NULL)
x |
A |
site |
A list of site properties, when |
A data.frame with one row per attribute that is not
recognised and the columns where ("horizons" or
"site"), name, suggestion (the closest recognised
names, comma-separated, empty when none) and note: empty, or
"site property" for a horizon column that is a site property,
"horizon attribute" for a site property that is a horizon column,
or "already given" when the column it would be renamed to is also
present. No rows when everything is recognised.
horizon_attribute_spec,
site_attribute_spec, inst/ATTRIBUTES.md.
h <- data.frame(top_cm = c(0, 20), bottom_cm = c(20, 60), clay = c(30, 45), organic_carbon_gkg = c(11, 4), soil_moisture_regime = "ustic") unrecognised_attributes(h, site = list(id = "p1", drainge_class = "well"))h <- data.frame(top_cm = c(0, 20), bottom_cm = c(20, 60), clay = c(30, 45), organic_carbon_gkg = c(11, 4), soil_moisture_regime = "ustic") unrecognised_attributes(h, site = list(id = "p1", drainge_class = "well"))
Returns the single most-common WRB RSG for a given USDA Order + optional Suborder. Based on IUSS WRB (2022) Annex 6.
usda_to_wrb_rsg(usda_order, usda_suborder = NULL)usda_to_wrb_rsg(usda_order, usda_suborder = NULL)
usda_order |
Character vector of USDA Order names. Case- insensitive; trailing 's' stripped (e.g.\ both "Mollisols" and "Mollisol" accepted). |
usda_suborder |
Optional character vector of USDA Suborder
names (case-insensitive) used to refine the mapping.
Same length as |
Character vector of WRB Reference Soil Group names
(singular, no plural 's'). NA for unrecognised inputs.
This is a "best-guess" cross-walk for benchmark validation only.
Real-world correlation requires per-pedon evaluation of WRB
diagnostic horizons. Use this function to derive a reasonable
expected WRB classification from a USDA-classified pedon
(e.g.\ from KSSL/NASIS) so that classify_wrb2022() can be
validated against an external taxonomy on the same profiles.
IUSS Working Group WRB (2022). World Reference Base for Soil Resources, 4th edition, Annex 6. International Union of Soil Sciences, Vienna.
usda_to_wrb_rsg("Mollisols") #> "Phaeozem" usda_to_wrb_rsg("Aridisols", "Salids") #> "Solonchak" usda_to_wrb_rsg(c("Spodosols", "Oxisols", "Vertisols")) #> c("Podzol", "Ferralsol", "Vertisol")usda_to_wrb_rsg("Mollisols") #> "Phaeozem" usda_to_wrb_rsg("Aridisols", "Salids") #> "Solonchak" usda_to_wrb_rsg(c("Spodosols", "Oxisols", "Vertisols")) #> c("Podzol", "Ferralsol", "Vertisol")
A pure, side-effect-free check of a horizon table's depth geometry,
independent of any PedonRecord. The Pro app's Pedon builder
calls it to give immediate feedback while horizons are edited, and it is a
handy guard before constructing a profile from an untrusted CSV.
validate_horizon_geometry(horizons)validate_horizon_geometry(horizons)
horizons |
A data frame with at least numeric |
It reports two severities:
a missing or
non-numeric top_cm/bottom_cm; a negative depth; a horizon
whose top_cm >= bottom_cm (inverted or zero thickness); two
horizons whose depths overlap.
the shallowest horizon not starting at the surface (0 cm); a gap between consecutive horizons; horizons entered out of increasing-depth order; a duplicated horizon designation.
This complements PedonRecord$validate(), which additionally checks
chemistry (texture sums, pH, CEC vs bases, Munsell ranges); use that for a
built record and this for a raw table.
A list with valid (logical; TRUE when there are no
errors), errors and warnings (character vectors of
human-readable English messages), and details – a named list of
the offending row indices (or values) per check, so a caller can compose
its own (e.g. localised) messages.
h <- data.frame(top_cm = c(0, 20, 55), bottom_cm = c(20, 55, 90), designation = c("A", "AB", "Bt")) validate_horizon_geometry(h)$valid # TRUE bad <- data.frame(top_cm = c(0, 40), bottom_cm = c(50, 30)) # overlap+inverted validate_horizon_geometry(bad)$errorsh <- data.frame(top_cm = c(0, 20, 55), bottom_cm = c(20, 55, 90), designation = c("A", "AB", "Bt")) validate_horizon_geometry(h)$valid # TRUE bad <- data.frame(top_cm = c(0, 40), bottom_cm = c(50, 30)) # overlap+inverted validate_horizon_geometry(bad)$errors
Convenience wrapper that converts a PedonRecord (or a
compatible list) to JSON and validates it via
jsonvalidate::json_validate against the canonical schema
returned by pedon_json_schema.
validate_pedon_json(x)validate_pedon_json(x)
x |
A |
Use this BEFORE calling classify_* when ingesting data from
external systems (web APIs, ETL pipelines, multimodal extraction)
to catch schema violations early.
A logical scalar (TRUE when valid). Validation errors
appear as the errors attribute when FALSE.
## Not run: p <- make_ferralsol_canonical() validate_pedon_json(p) #> [1] TRUE ## End(Not run)## Not run: p <- make_ferralsol_canonical() validate_pedon_json(p) #> [1] TRUE ## End(Not run)
A clay-rich subsurface horizon with slickensides or wedge-shaped aggregates, formed by shrinking and swelling. Used by Vertisols.
vertic_horizon( pedon, min_clay = 30, min_thickness = 25, min_le_cm = 6, le_max_depth_cm = 100, min_crack_width_cm = 0.5, reading = c("wrb2022", "usda") )vertic_horizon( pedon, min_clay = 30, min_thickness = 25, min_le_cm = 6, le_max_depth_cm = 100, min_crack_width_cm = 0.5, reading = c("wrb2022", "usda") )
pedon |
A |
min_clay |
Numeric threshold or option (see Details). |
min_thickness |
Numeric threshold or option (see Details). |
min_le_cm |
Minimum LE sum (cm) for the COLE-based path of
|
le_max_depth_cm |
Depth window (cm) for the COLE-based path of
|
min_crack_width_cm |
Minimum shrink-swell crack width (cm).
Defaults to 0.5 (WRB/USDA); the SiBCS
|
reading |
|
Since v0.9.311 the default reading (reading = "wrb2022") follows
the diagnostic criteria of WRB 2022 Ch 3.1.40 (p. 70). Mineral material
with:
\>= 30% clay;
wedge-shaped aggregates (a structure_type that names them)
or slickensides on \>= 10% of the aggregate surfaces
(slickensides "common" or more);
shrink-swell cracks: cracks_width_cm \>= 0.5, or, where
the width is not recorded, slickensides "common" or more or an
ss designation as evidence of them;
a thickness of \>= 25 cm, of adjoining layers that meet 1 to 3 taken together.
Each criterion is read per layer as met, not met or unrecorded. The
horizon is NA only when layers that might meet them (a criterion
unrecorded) could make up the thickness. Organic layers and continuous
rock are not part of it. WRB gives the COLE (\>= 0.06) as additional
information only, so this reading does not use cole_value.
reading = "usda" keeps the reading that the USDA Vertisols and the
SiBCS horizonte vertico are built on, as it was before v0.9.311:
slickensides "common" or more and cracks \>= min_crack_width_cm
in one layer of min_thickness, OR the KST 13 linear-extensibility
alternative: summed cole_value * thickness over the upper
le_max_depth_cm \>= min_le_cm (KST 13ed Ch 16, p. 343).
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Field-described Brazilian Vertissolos profiles (e.g.\ the Embrapa
Redape curated dataset) encode vertic morphology via a v
master-letter modifier in the horizon designation (Bv,
Bvk1, Cv, Cvz) without recording
slickensides class or shrink_swell_cracks_cm as
numeric inputs. With
options(soilKey.vertic_designation_inference = TRUE) the
function accepts a layer as vertic when the criteria of the reading
fail or are NA AND the layer has clay_pct >=
min_clay AND its designation matches a v master-letter
modifier. Default is FALSE.
Tests whether any horizon shows vertic properties – shrink-swell clay behaviour evidenced by slickensides, wedge-shaped peds, and deep cracks. Diagnostic for Vertisols.
vertic_properties( pedon, min_clay = 30, min_thickness = 25, slickenside_levels = c("common", "many", "continuous") )vertic_properties( pedon, min_clay = 30, min_thickness = 25, slickenside_levels = c("common", "many", "continuous") )
pedon |
A |
min_clay |
Minimum clay percent (default 30, per WRB 2022). |
min_thickness |
Minimum thickness (cm) of the vertic layer (default 25 per WRB 2022 Ch 3.2.x). |
slickenside_levels |
Vector of |
Sub-tests:
test_clay_above – clay >= 30%
test_slickensides_present – slickensides at
or above the "common" level
test_minimum_thickness – combined vertic layer
thickness >= 25 cm (v0.3.1 added per WRB 2022)
v0.3.1: thickness gate added. Limitations remaining: WRB also accepts deep cracks (>= 1 cm wide extending from the surface to >= 50 cm depth, when soil is dry) and wedge-shaped peds as alternative evidence; this implementation requires clay + slickensides. The "after mixing of upper 18 cm" clause from WRB is still deferred.
IUSS Working Group WRB (2022), Chapter 3.2 – Vertic properties.
WRB 2022 Ch 4 (p. 101), Vertisols: other soils having
a vertic horizon starting \<= 100 cm from the mineral soil surface;
\>= 30% clay between the mineral soil surface and the vertic horizon throughout;
shrink-swell cracks that start (a) at the mineral soil surface, (b) at the base of a plough layer, (c) directly below a self-mulching surface (a layer with strong granular, or strong angular or subangular blocky, structure of aggregates \<= 1 cm) or (d) directly below a surface crust, and extend to the vertic horizon.
Since v0.9.311 each item is TRUE, FALSE or NA (not recorded), and the gate
is NA when an item is undecided and none fails. Only a vertic horizon that
can start within 100 cm decides item 1, so unrecorded layers below it do
not leave the gate undecided. Item 3 reads the cracks of each layer as
vertic_horizon does (cracks_width_cm, or slickensides
or an ss designation as evidence of them): every layer between the
start and the vertic horizon must have them, and a layer whose cracks are
not recorded leaves the item undecided. Until v0.9.310 item 3 asked for a
layer with cracks starting within 20 cm and read missing cracks as absent.
vertisol(pedon, strict = NULL)vertisol(pedon, strict = NULL)
pedon |
A |
strict |
Logical or |
With strict = TRUE the overlying-clay threshold is raised from
30% to 35%, tightening the gate against marginally clayey profiles
that satisfy the vertic horizon but sit close to the Vertisol cut-off.
Volcanic glass \>= 5% in 0.02-2 mm fraction, Al_ox + 1/2 Fe_ox \>= 0.4%, phosphate retention \>= 25%.
vitric_properties( pedon, min_glass_pct = 5, min_alfe = 0.4, min_p_retention = 25 )vitric_properties( pedon, min_glass_pct = 5, min_alfe = 0.4, min_p_retention = 25 )
pedon |
A |
min_glass_pct |
Numeric threshold or option (see Details). |
min_alfe |
Numeric threshold or option (see Details). |
min_p_retention |
Numeric threshold or option (see Details). |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.
Selects a provider based on what is reachable in the user's
environment, in this preference order: local Ollama (if
ollama_is_running()), then Anthropic, OpenAI, and Google
(each requires the relevant *_API_KEY environment variable).
Errors with an actionable installation / API-key hint when no
provider is reachable.
vlm_pick_provider(verbose = TRUE)vlm_pick_provider(verbose = TRUE)
verbose |
If |
Character scalar: one of "ollama", "anthropic",
"openai", "google".
Returns an ellmer chat object configured for the given
provider, ready to be passed to the extraction functions
(extract_horizons_from_pdf, etc.). The chat object
wraps API credentials and model selection; it does not itself send
any request.
vlm_provider( name = c("auto", "anthropic", "openai", "google", "ollama"), model = NULL, ... )vlm_provider( name = c("auto", "anthropic", "openai", "google", "ollama"), model = NULL, ... )
name |
Provider name. One of |
model |
Optional model identifier; defaults to
|
... |
Additional arguments forwarded to the corresponding
|
This is purely a convenience wrapper: it picks a default model per
provider and forwards remaining arguments (e.g.
system_prompt, api_key) to the underlying ellmer
constructor. ellmer must be installed.
An ellmer Chat object exposing a $chat()
method for sending prompts.
Passing name = "ollama" runs every extraction locally via
an Ollama server (default gemma4:e4b, Gemma 4 edge with
multimodal text+image+audio support). No data leaves the
machine, which is the recommended setting for sensitive field
descriptions (e.g. governmental surveys, indigenous land studies)
where institutional independence and data sovereignty matter.
Pull the model first:
ollama pull gemma4:e4b # ~3 GB edge variant (default) ollama pull gemma4:31b # frontier dense variant ollama pull gemma3:27b # earlier generation, still solid
Then start an Ollama server (ollama serve) and the chat
object returned here will dispatch over HTTP locally.
## Not run: # Cloud provider (needs ANTHROPIC_API_KEY) provider <- vlm_provider("anthropic") # Local Gemma 4 edge model -- default, ~3 GB, runs anywhere provider <- vlm_provider("ollama") # Local Gemma 4 frontier dense model -- best quality provider <- vlm_provider("ollama", model = "gemma4:31b") # Any other multimodal model the user has pulled provider <- vlm_provider("ollama", model = "qwen2.5vl:32b") ## End(Not run)## Not run: # Cloud provider (needs ANTHROPIC_API_KEY) provider <- vlm_provider("anthropic") # Local Gemma 4 edge model -- default, ~3 GB, runs anywhere provider <- vlm_provider("ollama") # Local Gemma 4 frontier dense model -- best quality provider <- vlm_provider("ollama", model = "gemma4:31b") # Any other multimodal model the user has pulled provider <- vlm_provider("ollama", model = "qwen2.5vl:32b") ## End(Not run)
Returns the citation ISRIC asks users of WoSIS-latest to give, with the date the data were read. The ISRIC Data and Software Policy requires products, web services, papers and reports that use the data to reference the provider and acknowledge that the data were acquired through ISRIC.
wosis_citation(accessed = Sys.Date())wosis_citation(accessed = Sys.Date())
accessed |
Date the data were read (default today). |
A character string.
wosis_citation(as.Date("2026-10-06"))wosis_citation(as.Date("2026-10-06"))
Fetches the profile's layers live from ISRIC
(read_wosis_layers_graphql) and builds a
PedonRecord. Every value carries a provenance note naming its
WoSIS code, unit and method. The site metadata carries the licence, the source
dataset, the date the data were read and the citation ISRIC asks for
(wosis_citation), so attribution survives into anything the
user later exports. CC BY requires it, and an extract that drops it turns a
licensed use into an unattributed one.
wosis_profile_to_pedon(row, fetch_layers = TRUE, timeout = 30, progress = NULL)wosis_profile_to_pedon(row, fetch_layers = TRUE, timeout = 30, progress = NULL)
row |
One row of |
fetch_layers |
If |
timeout |
Seconds to wait for ISRIC (default 30). |
progress |
Optional |
When the layers carry a more restrictive licence than the profile listing reported, the more restrictive one is kept.
A PedonRecord. If the layers could not be read, it has
no horizons and site$wosis_error says why.
AfSP ships WRB 2006 RSG codes (2-letter, e.g.\ LV, AC, AR). The
2-letter codes are stable across WRB editions (2006 -> 2022); only
a handful of qualifier names changed. This helper maps the codes
to the WRB 2022 RSG names that classify_wrb2022 emits.
wrb06_code_to_rsg(code)wrb06_code_to_rsg(code)
code |
Character vector of WRB 2006 codes. |
Character vector of singular WRB 2022 RSG names; NA
for unrecognised codes.
Convenience wrapper for canonical_reference("WRB_4th_2022").
Returns a 3-element list:
$rsg (118 obs): Reference Soil Group + criteria text
$pq (661 obs): principal qualifiers per RSG
$sq (1167 obs): supplementary qualifiers per RSG
wrb2022_canonical(prefer_pkg = TRUE)wrb2022_canonical(prefer_pkg = TRUE)
prefer_pkg |
Retained for compatibility and no longer used. Until
v0.9.203 |
Source: NCSS-tech SoilTaxonomy R package. Original: IUSS
Working Group WRB (2022). World Reference Base for Soil
Resources, 4th edition.
The canonical WRB 2022 reference data (a list / data.frame of RSG and qualifier criteria), read from the SoilTaxonomy package.
test_yermic_surface.Yermic properties (WRB 2022 Ch 3.2.17) – per-pedon test wrapping
test_yermic_surface.
yermic_properties(pedon)yermic_properties(pedon)
pedon |
A |
A DiagnosticResult recording whether the diagnostic is present, the qualifying layers, and the supporting evidence.