In this demo, we use the aqp functions glom()
and profileApply()
to analyze a depth-subset of horizons from each profile in a SoilProfileCollection.
glom()
returns the horizon(s) that intersect the specified depth [z1] or depth interval [z1, z2].
First, the script queries components by component name, then gets records populated in the Component Diagnostic Features (codiagfeatures
) table.
glom()
is used to get all horizons that are within the cambic depth range. A custom function has_sandy_cambic()
is defined to use glom()
on individual profiles (p
).
A regular expression pattern is used to check the glom()
-ed horizon textures field (p$texture
) for stratified and/or sandy texture classes that are not allowed in cambic horizons.
If either stratified or sandy textures are found, the function returns TRUE
for that profile. Otherwise, the function returns FALSE
.
This demonstration script loads some components from Yosemite National Park (CA790). In this simple example, we look at some components correlated to Glacierpoint.
The Glacierpoint series (Sandy-skeletal, isotic Xeric Dystrocryepts) is defined as having either an Umbric epipedon OR a cambic horizon. It appears that cambic horizons were populated even for some of the components whose RV textures do not meet cambic criteria.
library(aqp)
library(soilDB)
# get components from Yosemite National Park for a sandy-skeletal, cryic, inceptisol
my.spc <- fetchSDA(WHERE="compname = 'Glacierpoint'")
Now, access the SPC @diagnostics
slot to figure out which components have cambics, and then make a subset SPC my.spc.sub
with just those components.
# copy contents of diagnostics slot
diagz <- diagnostic_hz(my.spc)
# create a subset SPC with just profiles that have a cambic in their diagnostics
my.spc.sub <- my.spc[profile_id(my.spc) %in%
diagz[grepl(diagz$featkind, pattern="[Cc]ambic"), idname(my.spc)],]
A total of 3 components out of 8 have cambic horizons.
Let’s inspect those 3 components visually.
Use plotSPC()
to show sand fraction percentage by horizon – with cambic top and bottom depths shown with brackets using aqp::addDiagnosticBracket()
.
# set margins
par(mar=c(0,1,3,1))
# plot spc using total sand RV % as color
plotSPC(my.spc.sub,
color='sandtotal_r',
width=0.15,
cex.names = 1)
# add red brackets showing cambic horizon top and bottom depth
addDiagnosticBracket(my.spc.sub,
kind='Cambic horizon',
top='featdept_r',
bottom='featdepb_r',
col='red',
offset=0,
lwd=10)
Now that we have the data and have done some preliminary inspection, let’s define a regular expression pattern and a function to check our cambic criteria.
Define a custom function has_sandy_cambic()
to test horizons within the cambic depth range for each profile. The default argument sandy.texture.pattern
matches stratified or sandy textures.
# has_sandy_cambic() has one required argument p, which is a single profile SPC
has_sandy_cambic <- function(p, sandy.texture.pattern = "SR|-S$|^S$|COS$|L[^V]FS$|[^L]VFS$|LS$|LFS$") {
d <- diagnostic_hz(p)
# match the pattern cambic or Cambic
d.cambic.idx <- grep(d$featkind, pattern="[Cc]ambic")
cambic_top <- d[d.cambic.idx, 'featdept_r']
cambic_bot <- d[d.cambic.idx, 'featdepb_r']
# if top or bottom depth are NULL there is no cambic
if(!is.null(cambic_top) | !is.null(cambic_bot)) {
# glom horizons in p from cambic_top to cambic_bot
cambic_horizons <- glom(p, cambic_top, cambic_bot, as.data.frame = TRUE)
print(paste0("COKEY: ",unique(p$cokey)," has cambic (",
cambic_top," - ",cambic_bot," cm) with ", paste0(cambic_horizons$hzname, collapse=","),
" horizons of texture class: ", paste0(cambic_horizons$texture, collapse=", ")))
# use a regular expression to match the sandy textures
if(any(grepl(cambic_horizons$texture,
pattern = sandy.texture.pattern,
ignore.case = TRUE))) {
return(TRUE)
}
}
return(FALSE)
}
Apply the function to each profile.
# apply function has_sandy_cambic() to each profile
my.spc.sub$sandy_cambic <- profileApply(my.spc.sub, has_sandy_cambic)
## [1] "COKEY: 17639151 has cambic (14 - 45 cm) with Bw1,Bw2 horizons of texture class: cb-ls, cbv-lfs"
## [1] "COKEY: 17639343 has cambic (28 - 49 cm) with Bw horizons of texture class: byx-cosl"
## [1] "COKEY: 17639416 has cambic (41 - 69 cm) with Bw horizons of texture class: stv-ls"
Inspect results. Print out the offending unique profile IDs (cokey
).
# do any components have a sandy cambic?
if(any(my.spc.sub$sandy_cambic)) {
print(paste0("The following components have sandy cambics: ",
paste0(profile_id(my.spc.sub)[my.spc.sub$sandy_cambic], collapse=",")))
} else {
print("All components with cambics have appropriate textures.")
}
## [1] "The following components have sandy cambics: 17639151,17639416"
This document is based on aqp
version 1.19, soilDB
version 2.5, and sharpshootR
version 1.5.