Nothing
#' @title Perform summaries on groups (from \code{group_by}) and create new site or horizon level attributes
#'
#' @aliases summarizeSPC,SoilProfileCollection-method, summarize
#'
#' @description \code{summarize()} is a function used for summarizing a `SoilProfileCollection` object. Specify the groups using the group_by verb, and then (named) expressions to evaluate on each group. The result is a data.frame with one row per categorical level in the grouping variable and one column for each summary variable.
#'
#' @param object A `SoilProfileCollection`
#' @param ... A set of (named) comma-delimited R expressions that resolve to a summary value. e.g \code{groupmean = mean(clay, na.rm = TRUE)}
#'
#' @return A `data.frame` with one row per level in the grouping variable, and one column for each summary
#'
#' @author Andrew G. Brown
#' @export
#'
summarizeSPC <- function(object, ...) {
# TODO: safe setter and accessor methods for grouping variable
group.by.col <- object@metadata$aqp_group_by
if (length(group.by.col) == 0)
group.by.col <- idname(object)
groups <- levels(factor(as.character(object[[group.by.col]])))
# capture expression(s) at function
.dots <- substitute(list(...))
.dots <- .dots[2:length(.dots)]
.names <- names(.dots)
if (is.null(.names))
.names <- as.character(.dots)
dfout <- .as.data.frame.aqp(data.frame(matrix(nrow = 0, ncol = length(.names))), aqp_df_class(object))
# TODO: generalize split for n site or horizon level attributes
res <- lapply(aqp::split(object, f = group.by.col), function(obj) {
# TODO: what else would be needed to do similar splits on the horizon data?
# essentially, base::split of horizons(obj) + summary on groups within SPC? pretty simple in principle
# summarize could operate on groups at multiple levels -- just need another loop in here for horizons
# this depends on aqp::split() being able to make splits based on criteria at multiple levels, then
# parsing up of the profiles in resulting list elements based on unique levels of horizon-level groups
#
# new behavior of aqp::split would possibly result in a list with overlap of profiles across elements
# also, could use diagnostics and or restrictions -- future compositeSPC will include these
# apply expressions to each group, frameify results
.data <- compositeSPC(obj)
for(i in 1:length(.dots)) {
output <- .data_dots(.data, eval(.dots[[i]]))[[1]]
names(output) <- .names[i-1]
if(length(output) > 1) {
stop("summary value '%s' has length greater than one", call.=FALSE)
} else if(length(output) == 0) {
stop("summary value '%s' has length zero", call.=FALSE)
}
if(any(c(nrow(dfout), length(dfout)) == 0)) {
dfout <- output
} else {
dfout <- cbind(dfout, output)
}
}
return(dfout)
})
# recombine results for each group into a single data.frame
summaries <- do.call('rbind', res)
final <- data.frame(groups, summaries)
colnames(final) <- c(group.by.col, .names)
# return result in same class as SPC slots
return(.as.data.frame.aqp(final, aqp_df_class(object)))
}
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.