Nothing
#' Collapse a COM(P)ADRE database by averaging matrices over levels of one or
#' more grouping variables
#'
#' @description
#' Collapses a CompadreDB object by averaging matrices over levels of one or
#' more grouping variables (e.g. SpeciesAuthor, MatrixPopulation).
#'
#' For a given study and species, a COM(P)ADRE database may contain multiple
#' matrices, reflecting different combinations of population, year, and/or
#' treatment. Collapsing allows a user to obtain a single 'grand mean matrix'
#' for each group of interest (e.g. MatrixPopulation), and therefore limit
#' pseudoreplication.
#'
#' All members of a group \emph{must} have the same matrix dimension (consider
#' adding MatrixDimension as a grouping variable). All members of a group
#' \emph{should} have the same ProjectionInterval and matrix stage class
#' definitions (see \code{\link{cdb_id_stages}}). Note that Seasonal matrices
#' should not be collapsed using this method (they should be matrix-multiplied
#' rather than averaged).
#'
#' @param cdb A CompadreDB object
#' @param columns Vector of grouping variables to collapse over (corresponding
#' to columns within \code{cdb})
#'
#' @return A CompadreDB object
#'
#' @details
#' Will give a warning if members of any group do not all share the same
#' ProjectionInterval or stage class definitions, or if \code{cdb} contains any
#' rows with a MatrixComposite value of "Seasonal".
#'
#' Prior to collapsing, columns of class 'factor' will be coerced to
#' 'character', and any list-column apart from \code{mat} will be removed.
#'
#' Within a group, rows of a given column are collapsed as follows:
#'
#' \itemize{
#' \item \code{mat}: matrices are averaged using \link{mpm_mean}, and stage
#' class definitions are taken from the first group member
#' \item \code{MatrixComposite}: return original value if N = 1, else return
#' "Collapsed"
#' \item \code{Lat}: re-calculated by averaging Lat column (if available)
#' \item \code{Lon}: re-calculated by averaging Lon column (if available)
#' \item \code{SurvivalIssue}: re-calculated from the collapsed \code{mat}
#' (\code{max(colSums(matU))})
#' \item \code{others}: if all elements equal return that unique value, else
#' paste together all unique values separated by "; "
#' }
#'
#' @author Patrick M. Barks <patrick.barks@@gmail.com>
#' @author Owen R. Jones <jones@@biology.sdu.dk>
#'
#' @family data checking
#'
#' @seealso \link{cdb_id_stages}
#'
#' @examples
#' # filter out Seasonal matrices
#' CompSub <- subset(Compadre, MatrixComposite != "Seasonal")
#'
#' # add column identifying unique stage class definitions
#' CompSub$id_stage <- cdb_id_stages(CompSub, "MatrixClassOrganized")
#'
#' # collapse
#' CompCollapse <- cdb_collapse(CompSub, columns = c("id_stage"))
#'
#' @importFrom methods new
#' @importFrom tibble as_tibble add_column
#' @export cdb_collapse
cdb_collapse <- function(cdb, columns) {
if ("MatrixComposite" %in% names(cdb) &&
any(cdb$MatrixComposite == "Seasonal")) {
warning("cdb contains rows with MatrixComposite == 'Seasonal'. This ",
"method of collapsing is not suitable for seasonal matrices. ",
"Consider removing prior to collapsing.",
call. = FALSE
)
}
# leave other validation to cdb_id
# create a unique integer identifier for each group to be collapsed
id_collapse <- cdb_id(cdb, columns)
id_unique <- unique(id_collapse)
# extract data slot
dat <- cdb@data
# remove any list-columns except for 'mat'
col_mat <- names(dat) == "mat"
col_list <- vapply(dat, class, "", USE.NAMES = FALSE) == "list"
dat <- dat[, col_mat | !col_list]
# coerce factor columns to character
is_factor <- vapply(dat, is.factor, logical(1), USE.NAMES = FALSE)
if (any(is_factor)) {
j <- which(is_factor)
for (i in j) dat[[i]] <- as.character(dat[[i]])
}
# collapse to list of 1-row data frames for each group
coll_l <- lapply(id_unique,
FUN = CollapseWrapper,
dat = dat,
id_collapse = id_collapse
)
# bind data frames
coll_dat <- do.call(rbind, coll_l)
new("CompadreDB",
data = coll_dat,
version = cdb@version
)
}
CollapseWrapper <- function(id, dat, id_collapse) {
dat <- dat[id_collapse %in% id, ]
CollapseFn(dat)
}
CollapseFn <- function(x) {
mat <- mpm_mean(x$mat)
d <- as_tibble(lapply(x[, -1], CollapseCol))
d <- add_column(d, mat = list(mat), .before = 1)
if (nrow(x) > 1) {
d$MatrixComposite <- "Collapsed"
if ("Lat" %in% names(x)) d$Lat <- mean(x$Lat)
if ("Lon" %in% names(x)) d$Lon <- mean(x$Lon)
d$SurvivalIssue <- max(colSums(mat@matU))
}
return(d)
}
CollapseCol <- function(col) {
ifelse(length(unique(col)) == 1,
unique(col),
paste(unique(col), collapse = "; ")
)
}
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.