Nothing
# Infrastructure for auto-detecting design variables and supporting multi-factor designs.
# Single-factor models use the variable name "x"; multi-factor models use "x1", "x2", ...
# Detection is performed by inspecting the formula and excluding the response and parameters.
#' Detect design variables from a model formula
#'
#' @description
#' Inspects the formula to identify which symbols are design variables (as opposed to
#' parameters or the response). Enforces the naming convention: \code{"x"} for
#' single-factor models and \code{"x1"}, \code{"x2"}, \ldots for multi-factor models.
#'
#' @param model A formula describing the model.
#' @param parameters Character vector of parameter names (excluded from design variables).
#'
#' @return Character vector of design variable names, sorted in numerical order for
#' multi-factor models (e.g. \code{c("x1", "x2", "x10")}).
#'
detect_design_vars <- function(model, parameters) {
response <- as.character(model[[2L]])
all_vars <- all.vars(model)
remaining <- setdiff(all_vars, c(response, parameters))
has_x <- "x" %in% remaining
x_multi <- grep("^x[0-9]+$", remaining, value = TRUE)
# Sort numerically: x1 < x2 < x10 (not lexicographic x1 < x10 < x2)
if (length(x_multi) > 0L)
x_multi <- x_multi[order(as.integer(sub("^x", "", x_multi)))]
if (has_x && length(x_multi) > 0L)
stop(
"The model formula mixes the single-factor variable 'x' with multi-factor ",
"variables 'x1', 'x2', ... - use one convention or the other.",
call. = FALSE
)
if (!has_x && length(x_multi) == 0L)
stop(
"No design variable found in the formula. ",
"Use 'x' for single-factor models or 'x1', 'x2', ... for multi-factor models.",
call. = FALSE
)
if (has_x) "x" else x_multi
}
# Returns TRUE when design_vars has more than one element (multi-factor model).
is_multifactor <- function(design_vars) length(design_vars) > 1L
# Returns the coordinate column names of a design data.frame (everything except "Weight").
coord_cols <- function(design) setdiff(names(design), "Weight")
# Renames "Point" to the design variable name for single-factor user-supplied designs,
# enabling backward-compatible use of data.frame(Point, Weight).
normalize_design_cols <- function(design, design_vars) {
if ("Point" %in% names(design) && length(design_vars) == 1L)
names(design)[names(design) == "Point"] <- design_vars[1L]
design
}
# Latin Hypercube Sample: n points in d dimensions.
# design_space: named list with one element c(min, max) per factor.
# Returns an n x d numeric matrix with column names matching names(design_space).
lhs_sample <- function(n, design_space) {
d <- length(design_space)
nms <- names(design_space)
perms <- replicate(d, sample.int(n)) # n x d stratification
u <- (perms - 1L + matrix(stats::runif(n * d), n, d)) / n
for (j in seq_len(d))
u[, j] <- design_space[[j]][1L] + u[, j] * diff(design_space[[j]])
colnames(u) <- nms
u
}
# Coerce a user-supplied design_space to a canonical named list.
# Accepts c(min, max) for 1D (for backward compat) or a named list for multi-factor.
# design_vars: character vector from detect_design_vars().
canonicalise_design_space <- function(design_space, design_vars) {
if (is.list(design_space)) {
if (!setequal(names(design_space), design_vars))
stop(
"names(design_space) must match the design variables detected in the formula (",
paste(design_vars, collapse = ", "), ").",
call. = FALSE
)
return(design_space[design_vars]) # ensure consistent ordering
}
# Numeric vector: only valid for single-factor models
if (length(design_vars) > 1L)
stop(
"design_space must be a named list for multi-factor models, e.g. ",
"list(x1 = c(0, 10), x2 = c(0, 5)).",
call. = FALSE
)
if (!is.numeric(design_space) || length(design_space) != 2L)
stop("design_space must be a numeric vector of length 2.", call. = FALSE)
stats::setNames(list(design_space), design_vars)
}
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.