#' Flexible Guessing and Mapping for Combining Data Types
#'
#' Maps data types into standard combiners that should be sensible.
#'
#' @param result A single result; flexibly accepts several object classes.
#'
#' @importFrom data.table rbindlist
#'
#' @return A function to combine a list of such results.
guess_combiner <- function(result) {
switch(class(result)[1],
data.table = data.table::rbindlist,
data.frame = combiner_rbind,
matrix = combiner_rbind,
numeric = combiner_c,
character = combiner_c,
integer = combiner_c,
logical = combiner_c,
factor = unlist,
array = combiner_array,
identity
)
}
################################################################################
#' Combine Results from Different Folds
#'
#' Applies \code{\link{combiners}}: functions that collapse across a list of
#' similarly structured results, to a list of such lists.
#'
#' @param results A \code{list} of \code{list}s, corresponding to each result,
#' with the inner \code{list}s corresponding to results from each fold.
#' @param combiners A \code{list} with the same names as results, containing
#' combiner function names or functions for each result.
#' @param smart_combiners A \code{logical} indicating whether combiners should
#' be guessed from the data type of the results if they are missing.
#'
#' @details In theory you should never call this function directly, because it
#' is called automatically by cross_validate. The defaults, combiners guessed
#' based on data type, should work in most cases.
#'
#' @return A list of combined results.
#'
#' @seealso \code{\link{combiners}}
#'
#' @export
combine_results <- function(results,
combiners = NULL,
smart_combiners = TRUE) {
result_names <- names(results)
if (is.null(combiners) && smart_combiners) {
# try to learn from data structure
first_fold <- lapply(results, function(result) result[[1]])
combiners <- sapply(first_fold, guess_combiner)
}
# combine results from different folds using the appropriate combiner
if (!is.null(combiners)) {
combined <- lapply(result_names, function(result_name) {
combiners[[result_name]](results[[result_name]])
})
names(combined) <- result_names
} else {
combined <- results
}
return(combined)
}
###############################################################################
#' Combiners
#'
#' Combiners are functions that collapse across a list of similarly structured
#' results. These are standard idioms for combining lists of certain data types.
#'
#' @param x A \code{list} of similar results to be combined.
#'
#' @return A combined results object.
#'
#' @rdname combiners
#'
#' @name combiners
NULL
#' @rdname combiners
#'
#' @export
combiner_rbind <- function(x) {
do.call(rbind, x)
}
#' @rdname combiners
#'
#' @export
combiner_c <- function(x) {
do.call(c, x)
}
#' @rdname combiners
#'
#' @export
combiner_factor <- function(x) {
unlist(x)
}
#' @rdname combiners
#'
#' @importFrom abind abind
#'
#' @export
combiner_array <- function(x) {
do.call(abind::abind, c(x, along = 1))
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.