Nothing
utils::globalVariables(c(".data", "x", "y"))
.onLoad <- function(libname, pkgname) {
registerDoSEQ()
invisible()
}
#' Quote Operator
#'
#' Shorthand notation for the \code{\link[base:substitute]{quote}} function.
#' The quote operator simply returns its argument unevaluated and can be applied
#' to any \R expression.
#'
#' @name quote
#'
#' @param expr any syntactically valid \R expression.
#'
#' @details
#' Useful for calling \link[=models]{model functions} with quoted parameter
#' values defined in terms of one or more of the following variables.
#' \describe{
#' \item{\code{nobs}}{number of observations in data to be \link{fit}.}
#' \item{\code{nvars}}{number of predictor variables.}
#' \item{\code{y}}{the response variable.}
#' }
#'
#' @return
#' The quoted (unevaluated) expression.
#'
#' @seealso \code{\link[base:substitute]{quote}}
#'
#' @examples
#' ## Stepwise variable selection with BIC
#' glm_fit <- fit(sale_amount ~ ., ICHomes, GLMStepAICModel(k = .(log(nobs))))
#' varimp(glm_fit)
#'
. <- function(expr) {
eval(substitute(quote(expr)))
}
as_string <- function(x, ...) {
UseMethod("as_string")
}
as_string.default <- function(x, ...) {
x <- format(x, trim = TRUE, justify = "none", drop0trailing = TRUE)
as_string(structure(as.character(x), names = names(x)), ...)
}
as_string.character <- function(x, sep = ", ", conj = character(), ...) {
x <- trimws(x)
if (length(conj)) {
n <- length(x)
if (n > 1) x[n] <- paste(conj, x[n])
if (n == 2) x <- paste(x[1], x[2])
}
if (length(sep)) paste(x, collapse = sep) else x
}
attach_objects <- function(
what, pos = 2L, name = deparse1(substitute(what), backtick = FALSE)
) {
make_attach <- attach
make_attach(what, pos, name, warn.conflicts = FALSE)
do.call(on.exit, list(substitute(detach(name))), envir = parent.frame())
}
class1 <- function(x) {
class(x)[1]
}
combine_inputs <- function(x) {
names(x) <- make_names_along(x, map("char", class, x))
all_data <- NULL
for (i in seq_along(x)) {
data <- as.data.frame(x[[i]])
if (is.null(all_data)) all_data <- data[NULL]
same_cols <- intersect(names(all_data), names(data))
if (!identical(all_data[same_cols], data[same_cols])) {
throw(Error(
"Cannot combine ", names(x)[i], " with previous data fames due to ",
"differences in column values or attributes."
))
}
diff_cols <- setdiff(names(data), same_cols)
all_data[diff_cols] <- data[diff_cols]
x[[i]] <- update(x[[i]], data = data[NULL, , drop = FALSE])
}
list(data = all_data, candidates = ListOf(x))
}
combine_model_slots <- function(models, types) {
init <- data.frame(type = types, weights = FALSE)
any_ordered <- any(map("logi", function(model) {
"ordered" %in% model@response_types
}, models))
info_list <- map(function(model) {
types <- model@response_types
res <- data.frame(type = types, weights = model@weights)
factor_match <- match("factor", types, nomatch = 0)
if (any_ordered && !("ordered" %in% types) && factor_match) {
res <- rbind(
res,
data.frame(type = "ordered", weights = res$weights[factor_match])
)
}
res
}, models)
info <- Reduce(function(x, y) {
res <- merge(x, y, by = "type")
res$weights <- if (nrow(res)) res$weights.x | res$weights.y else logical()
res[c("weights.x", "weights.y")] <- NULL
res
}, info_list, init)
list(
response_types = info$type,
weights = switch(length(unique(info$weights)) + 1,
FALSE, info$weights[1], info@weights)
)
}
complete_subset <- function(...) {
is_complete <- complete.cases(...)
map(function(x) subset(x, is_complete), list(...))
}
fget <- function(x, package = character()) {
throw(check_packages(package))
if (is.character(x)) {
x <- paste(c(package, x), collapse = "::")
err_msg <- paste0("Function `", x, "` not found.")
} else {
err_msg <- "Invalid function."
}
res <- get0(x, mode = "function")
if (is.null(res)) throw(Error(err_msg))
if (length(package)) {
envir <- environment(res)
if (!isNamespace(envir) || getNamespaceName(envir) != package) {
throw(Error("Function is not from the ", package, " package."))
}
}
res
}
get0 <- function(x, mode = "any") {
if (is.character(x) && length(x) == 1) {
expr <- str2lang(x)
if (is.name(expr)) {
base::get0(x, mode = mode)
} else if (is.call(expr) && any(expr[[1]] == c("::", ":::"))) {
base::get0(as.character(expr[[3]]), mode = mode,
envir = asNamespace(expr[[2]]))
}
} else if (mode %in% c("any", mode(x))) {
x
}
}
get_optim_field <- function(object, name = NULL) {
object <- object@params@optim
if (is.null(name)) object else slot(object, name)
}
get_perf_metrics <- function(x, y) {
generic_name <- "performance"
classes <- substring(methods(generic_name), nchar(generic_name) + 2)
class <- match_class(x, classes)
method <- fget(paste0(generic_name, ".", class))
metrics <- c(eval(formals(method)$metrics))
is_defined <- map("logi", function(metric) {
types <- metricinfo(metric)[[1]]$response_types
any(map("logi", is, list(x), types$observed) &
map("logi", is, list(y), types$predicted))
}, metrics)
metrics[is_defined]
}
has_grid <- function(object) {
is(object, "TunedInput") || is(object, "TunedModel") ||
(is(object, "MLModel") && nrow(object@gridinfo))
}
has_varimp <- function(object) {
!is.null(body(object@varimp))
}
identical_elements <- function(x, transform = identity, ...) {
target <- transform(x[[1]])
compare <- function(current) identical(transform(current), target, ...)
all(map("logi", compare, x[-1]))
}
is_counting <- function(x) {
isTRUE(attr(x, "type") == "counting")
}
is_empty <- function(x) {
prod(size(x)) == 0
}
is_one_element <- function(x, class = "ANY") {
is.vector(x) && length(x) == 1 && is(x[[1]], class)
}
is_optim_method <- function(x, ...) {
UseMethod("is_optim_method")
}
is_optim_method.default <- function(x, ...) {
FALSE
}
is_optim_method.MLInput <- function(x, ...) {
is_optim_method(x@params, ...)
}
is_optim_method.MLModel <- function(x, ...) {
is_optim_method(x@params, ...)
}
is_optim_method.MLOptimization <- function(x, type = "ANY", ...) {
is(x, type)
}
is_optim_method.ModelSpecification <- function(x, ...) {
is_optim_method(x@params, ...)
}
is_optim_method.NullOptimization <- function(x, ...) {
is_optim_method.default(x, ...)
}
is_optim_method.TrainingParams <- function(x, ...) {
is_optim_method(x@optim, ...)
}
is_response <- function(x, types) {
map("logi", function(type) {
if (type == "binary") {
is(x, "factor") && nlevels(x) == 2
} else {
is(x, type)
}
}, types)
}
is_trained <- function(x, ...) {
UseMethod("is_trained")
}
is_trained.MLModel <- function(x, ...) {
length(x@steps) > 0
}
is_trained.ModelRecipe <- function(x, ...) {
recipes::fully_trained(x)
}
is_trained.step <- function(x, ...) {
recipes::is_trained(x)
}
make_id <- function(prefix = character(), n = 4, sep = ".") {
suffix <- sample(c(letters, LETTERS, 0:9), n, replace = TRUE)
paste(c(prefix, paste(suffix, collapse = "")), collapse = sep)
}
make_names_along <- function(x, default = "..", unique = TRUE, sep = ".") {
if (length(default) == 1) default <- rep_len(default, length(x))
old_names <- names(x)
names(x) <- default
if (!is.null(old_names)) {
keep <- nzchar(old_names) & !is.na(old_names)
names(x)[keep] <- old_names[keep]
}
if (unique) make_unique(names(x), sep = sep) else names(x)
}
make_names_len <- function(n, prefix) {
paste0(rep_len(prefix, n), seq_len(n))
}
make_unique <- function(names, sep = ".") {
sort_order <- order(names)
counts <- table(names)
unames <- map(function(count, name) {
paste0(name, if (count > 1) paste0(sep, seq_len(count)))
}, counts, names(counts))
names[sort_order] <- unlist(unames)
names
}
map <- function(.object, ...) {
UseMethod("map")
}
map.character <- function(.object, .fun, ...) {
type <- match.arg(.object, c("character", "complex", "double", "integer",
"list", "logical", "numeric", "raw"))
res <- simplify(map(.fun, ...))
storage.mode(res) <- type
res
}
map.function <- function(.object, ...) {
nonempty <- all(lengths(list(...)))
if (nonempty) mapply(FUN = .object, ..., SIMPLIFY = FALSE) else list()
}
match_class <- function(object, choices) {
f <- function(x, ...) UseMethod("f")
f.default <- function(x, ...) NA_character_
for (choice in choices) {
assign(paste0("f.", choice), eval(substitute(function(x, ...) choice)))
}
f(object)
}
match_indices <- function(indices, choices) {
lookup <- structure(seq_along(choices), names = choices)
indices <- na.omit(names(lookup)[lookup[indices]])
if (is_empty(indices)) {
indices <- names(lookup)[1]
throw(LocalWarning(
"Specified indices not found; using ", indices, " instead."
))
}
indices
}
max.progress_index <- function(x, ...) {
attr(x, "max")
}
missing_names <- function(x, data) {
x[!(x %in% names(data))]
}
na.add <- function(object, at) {
if (any(at)) {
df <- tibble(object = object)
df <- df[pmax(cumsum(!at), 1), ]
df[at, ] <- NA
object <- df$object
}
object
}
ndim <- function(x) {
length(size(x))
}
new_params <- function(envir, ...) {
args <- c(as.list(envir), ...)
missing <- map("logi", function(x) is.name(x) && !nzchar(x), args)
if (any(missing)) {
throw(Error(note_items(
"Missing values for required argument{?s}: ", names(args)[missing], "."
)))
}
args[lengths(args) > 0]
}
new_progress_bar <- function(total, object, index = 0) {
backend <- getDoParName()
progress <- function(...) NULL
snow_opts <- list()
if (backend == "doSEQ") index <- as.numeric(index)
width <- max(round(0.25 * console_width()), 10)
input <- substr(class(as.MLInput(object)), 1, width)
model <- substr(as.MLModel(object)@name, 1, width)
format <- paste(input, "|", model)
if (index > 0) format <- paste0(index, ": ", format)
if (backend %in% c("doSEQ", "doSNOW")) {
format <- paste(format, "[:bar] :percent | :eta")
}
pb <- progress_bar$new(
format = format,
total = total,
clear = TRUE,
show_after = 0
)
if (is(index, "progress_index") && index == 1) {
pb$message(paste0(
names(index), if (is.finite(max(index))) paste0("(", max(index), ")")
))
}
if (total) {
pb$tick(0)
body(progress) <- quote(pb$tick())
if (backend == "doSNOW") snow_opts$progress <- progress
}
list(pb = pb, progress = progress, snow_opts = snow_opts)
}
new_progress_index <- function(init = 0, max = Inf, name = character()) {
structure(init, max = max, names = name, class = "progress_index")
}
note_items <- function(
begin, values, end = character(), add_names = FALSE, add_size = FALSE,
sep = ", ", conj = character()
) {
if (add_names && length(names(values))) {
values <- paste(names(values), values, sep = " = ")
}
size <- length(values)
if (add_size && size) {
values <- c(
paste0("[1", if (size > 1) paste0(":", size), "] ", values[1]), values[-1]
)
}
end <- paste0(end, "{qty(size)}")
pluralize(begin, as_string(values, sep = sep, conj = conj), end)
}
nvars <- function(x, model) {
stopifnot(is(x, "ModelFrame"))
model <- as.MLModel(model)
res <- switch(model@predictor_encoding,
"model.frame" = {
x_terms <- attributes(terms(x))
nrow(x_terms$factors) - x_terms$response - length(x_terms$offset)
},
"model.matrix" = ncol(model.matrix(x[1, , drop = FALSE], intercept = FALSE))
)
if (is.null(res)) NA else res
}
permute_int <- function(n, size = n) {
inds <- sample.int(n, size)
half_size <- size / 2
inds1 <- head(inds, half_size)
inds2 <- tail(inds, -half_size)
res <- data.frame(i = c(inds1, inds2), j = c(inds2, inds1))
res[order(res$i), ]
}
push <- function(x, object, ...) {
UseMethod("push")
}
push.TrainingStep <- function(x, object, ...) {
stopifnot(is(object, "MLModelFit"))
steps <- ListOf(c(x, attr(object, ".MachineShop")$model@steps))
names(steps) <- make_names_len(length(steps), class(x))
attr(object, ".MachineShop")$model@steps <- steps
object
}
rand_int <- function(n = 1) {
sample.int(.Machine$integer.max, n)
}
required_packages <- function(object) {
input <- as.MLInput(object)
require <- if (is(input, "ModelRecipe")) {
c("survival", "recipes")
} else if (is(response(input), "Surv")) {
"survival"
}
union(settings("require"), require)
}
round_int <- function(...) {
as.integer(round(...))
}
sample_replace <- function(x, inds) {
if (!is.logical(inds)) {
old_inds <- inds
inds <- structure(logical(length(x)), names = names(x))
inds[old_inds] <- TRUE
}
x[inds] <- sample(x[!inds], sum(inds), replace = TRUE)
x
}
seq_boot <- function(src, dest) {
indices <- seq_len(nrow(src))
pad_size <- nrow(dest) - nrow(src)
if (pad_size >= 0) {
c(indices, sample(indices, pad_size, replace = TRUE))
} else {
sample(indices, nrow(dest))
}
}
seq_inner <- function(from, to, length) {
x <- seq(from, to, length = length + 2)
x[-c(1, length + 2)]
}
seq_int <- function(...) {
as.integer(seq(...))
}
seq_nvars <- function(x, model, length) {
nvars <- nvars(x, model)
length <- min(length, nvars)
vals <- if (length > 1) {
if (nvars < 500) {
seq(2, nvars, length = length)
} else {
2^seq(1, log2(nvars), length = length)
}
} else {
numeric()
}
round_int(vals)
}
seq_range <- function(from, by, bounds, length) {
if (length > 0) {
to <- min(from + by * (length - 1), bounds[2])
x <- seq(from, to, length = length)
x[x >= bounds[1]]
} else {
seq(from, length = length)
}
}
set_model_names <- function(x) {
name <- "Model"
level_names <- list()
for (i in seq_along(x)) {
if (is.null(x[[i]][[name]])) x[[i]][[name]] <- rep(name, nrow(x[[i]]))
x[[i]][[name]] <- as.factor(x[[i]][[name]])
arg_name <- names(x)[i]
level_names[[i]] <- if (!is.null(arg_name) && nzchar(arg_name)) {
rep(arg_name, nlevels(x[[i]][[name]]))
} else {
levels(x[[i]][[name]])
}
}
level_names <- level_names %>% unlist %>% make_unique %>% relist(level_names)
for (i in seq_along(x)) levels(x[[i]][[name]]) <- level_names[[i]]
x
}
simplify <- function(x) {
if (length(x)) simplify2array(x, higher = TRUE) else x
}
size <- function(x, dim = integer()) {
res <- dim(x)
if (is.null(res)) res <- length(x)
if (length(dim)) res[dim] else res
}
stepAIC_args <- function(formula, direction, scope) {
if (is.null(scope$lower)) scope$lower <- ~ 1
if (is.null(scope$upper)) scope$upper <- formula[-2]
formula[-2] <- if (direction == "backward") scope$upper else scope$lower
list(formula = formula, scope = scope)
}
subset_selected <- function(object, slot_name, id = character()) {
if (length(id)) {
keep <- map("char", slot, slot(object, slot_name), "id") %in% id
slot(object, slot_name) <- slot(object, slot_name)[keep]
}
object
}
subset_names <- function(x, select = NULL) {
indices <- seq_along(x)
names(indices) <- x
select <- eval(substitute(select), as.list(indices), parent.frame())
if (is.character(select)) {
x <- intersect(x, select)
} else if (is.numeric(select)) {
x <- x[select]
} else if (!is.null(select)) {
throw(Warning("Invalid `select` value of class ", class1(select), "."))
}
x
}
switch_class <- function(EXPR, ...) {
blocks <- eval(substitute(alist(...)))
eval.parent(blocks[[match_class(EXPR, names(blocks))]])
}
unnest <- function(data) {
stopifnot(is(data, "data.frame"))
df <- data.frame(row.names = seq_len(nrow(data)))
for (name in names(data)) {
x <- data[[name]]
if (ndim(x) > 1) {
x <- if (is.data.frame(x)) unnest(x) else as.data.frame(as(x, "matrix"))
name <- paste0(name, "$", names(x))
}
df[name] <- x
}
df
}
vector_to_function <- function(x, type) {
err_msg <- paste0("Value of '", deparse1(substitute(x)),
"' must be a function, function name, or vector of these.")
if (is(x, "MLMetric")) x <- list(x)
if (is(x, "vector")) {
x <- as.list(x)
types <- make_names_len(length(x), type)
x_names <- character()
for (i in seq_along(x)) {
if (is(x[[i]], "character")) {
x_name <- gsub("^.*[:]{2}(?!.*[:]{2})", "", x[[i]], perl = TRUE)
x[[i]] <- fget(x[[i]])
} else if (is(x[[i]], "MLMetric")) {
x_name <- x[[i]]@name
} else if (is(x[[i]], "function")) {
x_name <- types[i]
} else {
throw(Error(err_msg))
}
name <- names(x)[i]
x_names[i] <- if (is.null(name) || !nzchar(name)) x_name else name
}
names(x) <- make_unique(x_names)
function(...) unlist(map(function(fun) fun(...), x))
} else if (is(x, "function")) {
x
} else {
throw(Error(err_msg))
}
}
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.