Nothing
#' Generate Labels for Slabs
#'
#' This method is used by [slab()] for generating labels that assign IDs to layers in a SoilProfileCollection
#'
#' The new routine used in aqp 2.0 requires that, at a minimum, the `spc` and `slab.structure` arguments be specified.
#'
#' @param slab.structure A user-defined slab thickness (defined by an integer), or user-defined structure (numeric vector). See details for `slab()`.
#' @param max.d Maximum depth
#' @param n.profiles Number of profiles
#' @param spc Optional: A SoilProfileCollection
#' @param diced Optional: The `dice()`-ed horizon-level data.frame corresponding to `spc`
#' @return factor. slab IDs, labels are the segment top and bottom depth separated by `"-"`
#' @param ... Additional arguments passed to `dice()` when `spc` is specified.
#' @seealso [slab()]
#' @export
genSlabLabels <- function(slab.structure = 1, max.d = NULL, n.profiles = NULL, spc = NULL, diced = NULL, ...) {
# new method in aqp 2.x slab() requires SPC input
if (!is.null(spc)) {
if (is.null(diced)) {
diced <- dice(spc, ..., SPC = FALSE)
}
# call method now used internally in slab()
return(.genSlabLabels2(spc = spc, diced = diced, slab.structure = slab.structure))
}
if (is.null(max.d)) {
stop("Must specify `max.d` when `spc` is NULL")
}
if (is.null(n.profiles)) {
stop("Must specify `n.profiles` when `spc` is NULL")
}
# legacy method from aqp 1.x slab():
# fixed-size slabs
if (length(slab.structure) == 1) {
# generate sequence of segment labels
seg.label <- rep(1:ceiling(max.d / slab.structure), each = slab.structure, length = max.d)
# general segment labels
seg.label.levels <- tapply(1:max.d, seg.label,
function(i) {
r <- range(i, na.rm = TRUE)
paste(c(r[1] - 1, r[2]), collapse = '-')
})
}
# user-defined slabs
if (length(slab.structure) > 1) {
if (slab.structure[1] == 0 & length(slab.structure) > 2) {
# trivial case where segments start from 0
seg.label <- rep(slab.structure[-1], times = diff(slab.structure))[1:max.d]
} else {
# other case: user defines an arbitrary lower and upper limit
if (length(slab.structure) != 2)
stop('user-defined slab boundaries must either start from 0, or contain two values between 0 and the max soil depth')
# calculate thickness of slab
slab.thickness <- diff(slab.structure)
# make a new label for the slab
new.label <- paste(slab.structure, collapse = '-')
slab.idx <- rep(new.label, times = slab.thickness)
seg.label <- slab.idx
}
# generate segment labels
seg.label.levels <- sapply(1:(length(slab.structure) - 1), function(i) {
paste(c(slab.structure[i], slab.structure[i + 1]), collapse = '-')
})
}
# covert into a factor that can be used to split profiles into slabs
res <- factor(rep(seg.label, times = n.profiles), labels = seg.label.levels)
return(res)
}
# does not assume logical horizons (may overlap, resulting in different # of slices per profile)
.genSlabLabels2 <- function(spc, diced, slab.structure = 1) {
# handle various allowed slab.structure specifications
if (length(slab.structure) == 1) {
i <- seq(from = 0, length.out = (max(spc) / slab.structure) + 1) * slab.structure
} else if (length(slab.structure) > 1) {
i <- slab.structure
} else {
stop("empty slab.structure", call. = FALSE)
}
# calculate a sequence of cumulative depths and corresponding indices for each slab
j <- diff(i)
hzd <- horizonDepths(spc)
if (length(j) == 0) {
stop("Empty slab.structure", call. = FALSE)
} else if (length(j) == 1 && j == 0) {
stop("Invalid slab.structure", call. = FALSE)
} else {
idx1 <- cumsum(do.call('c', lapply(seq_along(j), function(x) rep(1, j[x])))) + i[1]
idx2 <- do.call('c', lapply(seq_along(j), function(x) rep(x, j[x])))
mt <- data.frame(idx1, slab_id = idx2, slab_label = paste0(i[idx2], "-", i[idx2 + 1]))
}
colnames(mt) <- c(hzd[2], "slab_id", "slab_label")
# merge the dice'd data.frame result with the slab ID and labels
res <- merge(diced, mt, by = hzd[2], all.x = TRUE, sort = FALSE)
# order by horizon ID and depth
res <- res[order(res[[idname(spc)]], res[[hzd[2]]]),]
# return the slab IDs as a factor, with labels denoting each segment top and bottom
factor(res$slab_id, labels = na.omit(unique(res$slab_label)))
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.