Add dials parameter
Guide for creating new dials parameters for hyperparameter tuning. Use when a developer needs to define custom tuning parameters for models, recipes, or workflows, including quantitative parameters (continuous/integer), qualitative parameters (categorical), parameters with transformations, and data-dependent parameters requiring finalization.From its SKILL.md
npx -y skills add tidymodels/skills --skill add-dials-parameterAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 9 stars9 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
21.1 KB, ~4.6k tokens by cl100k_base, as published. Nobody here has run it
Add Dials Parameter
Create custom tuning parameters for hyperparameter tuning in Tidymodels
Guide for creating new dials parameters for hyperparameter tuning. Use when a developer needs to define custom tuning parameters for models, recipes, or workflows, including quantitative parameters (continuous/integer), qualitative parameters (categorical), parameters with transformations, and data-dependent parameters requiring finalization.
Two Development Contexts
This skill supports two distinct development contexts with different capabilities and constraints:
1. Extension Development (Primary Context)
Use when: Creating a new R package that defines custom tuning parameters
-
β Build new packages extending Tidymodels with custom parameters
-
β Use all exported dials functions with
dials::prefix -
β Cannot use internal functions (
:::) -
π Start here: Extension Development Guide
Package detection: DESCRIPTION file does NOT have Package: dials
2. Source Development (Advanced Context)
Use when: Contributing parameter definitions directly to tidymodels/dials repository
-
β Contribute parameters to dials package itself
-
β Access internal helper functions without
dials::prefix -
β Use validation helpers (
check_type(),check_range()) -
β Create custom finalize functions with
range_get()/range_set() -
π Start here: Source Development Guide
Package detection: DESCRIPTION file has Package: dials
Getting Started
Before you begin, verify your development context:
# Extension development (most common)
usethis::create_package("myextension")
# DESCRIPTION will have: Package: myextension
# Source development (contributing to dials)
# Clone repository: git clone https://github.com/tidymodels/dials
# DESCRIPTION will have: Package: dials
INSTRUCTIONS FOR CLAUDE:
Detect development context by checking:
-
DESCRIPTION file check (most reliable):
-
If
Package: dialsβ Source development -
If
Package: [anything else]β Extension development
-
-
Prompt signals (when DESCRIPTION not available):
Extension indicators:
-
"for my package"
-
"I'm building/creating [package name]"
-
"new package called [name]"
-
"my [package] package"
-
No mention of cloning or PR
Source indicators:
-
"contributing to dials"
-
"PR to tidymodels/dials"
-
"I'm in the dials repo"
-
"forked tidymodels/dials"
-
"working on a feature branch"
-
"clone of tidymodels/dials"
-
-
When uncertain:
-
Ask explicitly: "Are you creating a new package or contributing to dials itself?"
-
Default to extension development (most common use case)
-
Apply appropriate patterns:
-
Extension: Use dials:: prefix, link to extension-guide.md, create DESCRIPTION if needed
-
Source: No prefix, link to source-guide.md, assume dials repo structure exists
Overview
dials is the tuning parameter infrastructure package for Tidymodels. It provides:
-
Parameter object definitions (quantitative and qualitative)
-
Parameter range specifications and transformations
-
Grid generation methods (regular, random, space-filling)
-
Integration with tune, parsnip, recipes, and workflows packages
The name reflects the idea that tuning predictive models can be like turning a set of dials on a complex machine.
Key Concepts
- Parameter Types: Quantitative (numeric) vs Qualitative (categorical)
- Range Specification: Fixed ranges, unknown bounds, transformations
- Finalization: Resolving data-dependent parameters with training data
- Grid Integration: How parameters work with grid generation functions
Repository Access (Optional but Recommended)
INSTRUCTIONS FOR CLAUDE: Check if repos/dials/ exists in the current
working directory. Use this to guide development:
If repos/dials/ exists:
-
β Use it as a reference throughout development
-
Read source files (e.g.,
repos/dials/R/param_mtry.R) to study implementation patterns -
Read test files (e.g.,
repos/dials/tests/testthat/test-param_mtry.R) for testing patterns -
Reference these files when answering complex questions or solving problems
-
Look at actual code structure, validation patterns, and edge case handling
If repos/dials/ does NOT exist:
-
Suggest cloning the repository using the scripts in Repository Access Guide
-
This is optional but strongly recommended for high-quality development
-
If the user declines, reference files using GitHub URLs:
-
Format:
https://github.com/tidymodels/dials/blob/main/R/[file-name].R -
Example: https://github.com/tidymodels/dials/blob/main/R/param_mtry.R
-
This allows users to click through to see implementations
-
When to use repository references:
-
Complex implementation questions (e.g., "How does dials handle finalization?")
-
Debugging issues (compare user's code to working implementation)
-
Understanding patterns (study similar parameters)
-
Test design (see how dials tests edge cases)
-
Architecture decisions (understand internal structure)
See Repository Access Guide for setup instructions.
Parameter Type Decision Tree
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β What type of tuning parameter do you need? β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββ΄ββββββββββββββββββββ
β β
βΌ βΌ
Numeric values Categorical choices
(continuous or integer) (discrete options)
β β
βΌ βΌ
βββββββββββββββββββ βββββββββββββββββββ
β QUANTITATIVE β β QUALITATIVE β
β PARAMETER β β PARAMETER β
βββββββββββββββββββ βββββββββββββββββββ
β β
β β
βββββββββββββ¬βββββββββββββ β
βΌ βΌ βΌ βΌ
Simple Transformed Data- Examples:
range (log scale) dependent - activation()
- weight_func()
β β β - prune_method()
βΌ βΌ βΌ
Examples: Examples: Examples:
- threshold - penalty - mtry
- mixture - learn_rate - num_comp
- neighbors - cost - sample_size
Decision guide:
-
Quantitative, simple range: Fixed numeric bounds, no transformation β Quantitative Parameters
-
Quantitative, transformed: Log scale or other transformation β Quantitative Parameters + Transformations
-
Quantitative, data-dependent: Upper bound depends on dataset β Quantitative Parameters + Data-Dependent Parameters
-
Qualitative: Discrete categorical options β Qualitative Parameters
Complete Examples
Example 1: Simple Quantitative Parameter
A threshold parameter with fixed range (extension pattern):
# R/param_my_threshold.R
#' Threshold value
#'
#' A threshold parameter for filtering or classification decisions.
#'
#' @param range A two-element vector with the lower and upper bounds.
#' @param trans A transformation object (default NULL for no transformation).
#'
#' @details
#' This parameter is used for models or recipes that require a threshold value.
#'
#' @examples
#' my_threshold()
#' my_threshold(range = c(0, 0.5))
#'
#' @export
my_threshold <- function(range = c(0, 1), trans = NULL) {
dials::new_quant_param(
type = "double",
range = range,
inclusive = c(TRUE, TRUE),
trans = trans,
label = c(my_threshold = "Threshold Value"),
finalize = NULL
)
}
Example 2: Transformed Quantitative Parameter
A penalty parameter on log scale (extension pattern):
# R/param_my_penalty.R
#' Penalty amount
#'
#' A penalty parameter for regularization on log scale.
#'
#' @param range A two-element vector with the lower and upper bounds
#' (in log10 units).
#' @param trans A transformation object (default log10 transformation).
#'
#' @details
#' This parameter uses a log10 transformation, so `range = c(-5, 0)`
#' represents actual penalty values from 10^-5 to 1.
#'
#' @examples
#' my_penalty() # Range: 10^-10 to 1
#' my_penalty(range = c(-5, 0)) # Range: 10^-5 to 1
#'
#' @export
my_penalty <- function(range = c(-10, 0), trans = scales::transform_log10()) {
dials::new_quant_param(
type = "double",
range = range,
inclusive = c(TRUE, TRUE),
trans = trans,
label = c(my_penalty = "Penalty Amount"),
finalize = NULL
)
}
Example 3: Data-Dependent Parameter with Built-in Finalize
A parameter with unknown upper bound (extension pattern):
# R/param_num_features.R
#' Number of features
#'
#' The number of features to select, depends on data.
#'
#' @param range A two-element vector with the lower and upper bounds.
#' @param trans A transformation object (default NULL).
#'
#' @details
#' The upper bound is set to `unknown()` and must be finalized using
#' `finalize()` with training data.
#'
#' @examples
#' num_features()
#'
#' # Finalize with data
#' param <- num_features()
#' finalized <- dials::finalize(param, mtcars[, -1])
#' finalized$range$upper # Will be number of columns
#'
#' @export
num_features <- function(range = c(1L, dials::unknown()), trans = NULL) {
dials::new_quant_param(
type = "integer",
range = range,
inclusive = c(TRUE, TRUE),
trans = trans,
label = c(num_features = "# Features to Select"),
finalize = dials::get_p # Built-in finalize function
)
}
Example 4: Custom Finalize Function
A parameter with custom finalization logic (extension pattern):
# R/param_num_initial_terms.R
#' Number of initial MARS terms
#'
#' The number of initial terms for MARS model, depends on data.
#'
#' @param range A two-element vector with the lower and upper bounds.
#' @param trans A transformation object (default NULL).
#'
#' @details
#' The upper bound is set to `unknown()` and is finalized using a custom
#' function based on the earth package formula: min(200, max(20, 2 * ncol(x))) + 1
#'
#' @examples
#' num_initial_terms()
#'
#' # Finalize with data
#' param <- num_initial_terms()
#' finalized <- dials::finalize(param, mtcars[, -1])
#' finalized$range$upper
#'
#' @export
num_initial_terms <- function(range = c(1L, dials::unknown()), trans = NULL) {
dials::new_quant_param(
type = "integer",
range = range,
inclusive = c(TRUE, TRUE),
trans = trans,
label = c(num_initial_terms = "# Initial MARS Terms"),
finalize = get_initial_mars_terms
)
}
# Custom finalize function
get_initial_mars_terms <- function(object, x) {
# Calculate upper bound based on number of predictors
upper_bound <- min(200, max(20, 2 * ncol(x))) + 1
upper_bound <- as.integer(upper_bound)
# Get current range and update upper bound
bounds <- dials::range_get(object)
bounds$upper <- upper_bound
dials::range_set(object, bounds)
}
Example 5: Qualitative Parameter
A categorical parameter with options (extension pattern):
# R/param_aggregation.R
#' Aggregation method
#'
#' The method to use for aggregating embeddings.
#'
#' @param values A character vector of possible methods.
#'
#' @details
#' This parameter defines how embeddings are aggregated.
#' By default, no aggregation is performed.
#'
#' @examples
#' values_aggregation
#' aggregation()
#' aggregation(values = c("none", "mean"))
#'
#' # Sample values
#' set.seed(123)
#' aggregation() %>% dials::value_sample(3)
#'
#' @export
aggregation <- function(values = values_aggregation) {
dials::new_qual_param(
type = "character",
values = values,
default = "none",
label = c(aggregation = "Aggregation Method")
)
}
#' @rdname aggregation
#' @export
values_aggregation <- c("none", "min", "max", "mean", "sum")
Quick Navigation
Core Guides
-
Extension Development Guide - Creating new packages with custom parameters
-
Source Development Guide - Contributing to dials package
Parameter Types
-
Parameter System Overview - Architecture and parameter classes
-
Quantitative Parameters - Creating numeric parameters
-
Qualitative Parameters - Creating categorical parameters
-
Transformations - Using log scale and custom transformations
-
Data-Dependent Parameters - Using unknown() and finalization
-
Grid Integration - How parameters work with grids
Source Development
-
Testing Patterns (Source) - dials-specific testing
-
Best Practices (Source) - dials conventions and patterns
-
Troubleshooting (Source) - Common issues in dials
Prerequisites
For Extension Development
Before creating custom parameters in a new package, ensure your package is properly set up:
-
R Package Structure: See Extension Prerequisites
-
Dependencies: Add
dialsto DESCRIPTION Imports -
Roxygen: Configure documentation system
-
Testing: Set up testthat framework
For Source Development
To contribute parameters to dials:
-
Clone the repository:
git clone https://github.com/tidymodels/dials cd dials -
Install dependencies:
pak::pak() -
Load the package:
devtools::load_all()
See Source Development Guide for complete setup.
Development Workflow
Fast Iteration Cycle
For rapid parameter development:
- Create parameter function in
R/directory - Load with
devtools::load_all() - Test interactively in console
- Document with roxygen comments
- Verify with tests
See Development Workflow for details.
Testing Your Parameters
Essential tests for all parameters:
-
Range validation: Parameter accepts valid ranges
-
Type checking: Correct type enforcement
-
Grid integration: Works with
grid_regular(),grid_random() -
Value utilities:
value_sample()andvalue_seq()work correctly -
Edge cases: Invalid inputs produce errors
See testing guides:
-
Extension: Testing Requirements
-
Source: Testing Patterns (Source)
Package-Specific Patterns
File Naming (Source Development)
dials follows strict naming conventions:
-
Parameter files:
R/param_[name].R -
Test files:
tests/testthat/test-params.R(shared),test-constructors.R -
One parameter per file (usually)
Documentation Patterns
Use roxygen tags consistently:
#' @inheritParams new_quant_param
#' @param range A two-element vector with the lower and upper bounds.
#' @details
#' This parameter is used for...
#' @examples
#' my_param()
#' @export
See Roxygen Documentation for complete patterns.
Creating Companion Values Vectors
For qualitative parameters, create a values_* vector:
#' @rdname param_name
#' @export
values_param_name <- c("option1", "option2", "option3")
This convention is strongly recommended for consistency.
Next Steps
For Extension Developers
- Read Extension Development Guide
- Choose your parameter type: Quantitative or Qualitative
- Implement your parameter following the examples above
- Add tests following Testing Requirements
- Document with roxygen following Documentation Guide
For Source Contributors
- Read Source Development Guide
- Study existing parameters in
repos/dials/R/param_*.R - Understand Parameter System Overview
- Follow Best Practices (Source)
- Add tests to
tests/testthat/test-params.R - Submit PR following Source Guide checklist
Related Skills
-
add-yardstick-metric - Custom metrics may need custom tuning parameters
-
add-recipe-step - Recipe steps often have tunable parameters
-
add-parsnip-model - Model specifications have tunable main arguments
-
add-parsnip-engine - Model engines have tunable parameters
File Creation Guidelines
Extension development:
-
R/param_[name].R (with complete roxygen docs and examples)
-
tests/testthat/test-param_[name].R (comprehensive tests)
-
README.md (only if package has no README)
-
Expected total: 2-3 files (aim for these targets; acceptable to exceed by 2-3 files if implementation requires it)
Source development:
-
R/param_[name].R (with complete roxygen docs and examples)
-
tests/testthat/test-param_[name].R (or additions to existing test file)
-
Expected total: 2 files (aim for these targets; acceptable to exceed by 2-3 files if implementation requires it)
Files to avoid creating:
Documentation files (content belongs in roxygen comments):
-
IMPLEMENTATION_SUMMARY.md, IMPLEMENTATION_NOTES.md, QUICKSTART.md, QUICK_REFERENCE.md
-
INDEX.md, FILE_GUIDE.md, SUMMARY.md, OVERVIEW.md, INTEGRATION_GUIDE.md
-
example_usage.R, USAGE_EXAMPLE.R
PR-related files (content belongs in conversation):
-
PR_CHECKLIST.md, PR_DESCRIPTION.md, PR_SUMMARY.md
-
NEWS_entry.md, pkgdown_update.txt
-
WORKFLOW_COMMANDS.sh, setup.sh
For PRs to dials:
-
README.md (dials already has one)
-
test-params-addition.R (tell user in conversation what to add)
Where content belongs:
-
Examples β roxygen @examples in R file
-
Implementation notes β roxygen @details in R file
-
PR description β conversation with user
-
NEWS entry β conversation (maintainer adds it)
-
Test additions β conversation (tell user what to add)
Creating extra documentation files clutters the codebase. All documentation should be in roxygen comments (for code) or in conversation (for PR descriptions).
See extension-guide.md Step 5 and source-guide.md "File Creation Guidelines for PRs" for detailed enforcement rules.
Last Updated: 2026-03-31
What ships with it: 28 files
410.1 KB alongside SKILL.md, 3 of them executable
evals/
- evals.json14.2 KB
- grading-config.json7.6 KB
- README.md8.7 KB
references/
- best-practices-source.md16.2 KB
- data-dependent-parameters.md23.9 KB
- extension-guide.md26.2 KB
- grid-integration.md18.6 KB
- package-best-practices.md9.1 KB
- package-development-workflow.md6.9 KB
- package-extension-prerequisites.md16.1 KB
- package-extension-requirements.md33.7 KB
- package-imports.md6.3 KB
- package-repository-access.md13.9 KB
- package-roxygen-documentation.md13.9 KB
- package-testing-patterns.md12.2 KB
- package-troubleshooting.md11.4 KB
- parameter-system.md16.5 KB
- qualitative-parameters.md20.7 KB
- quantitative-parameters.md19.4 KB
- scripts/clone-tidymodels-repos.ps1runs9.5 KB
- scripts/clone-tidymodels-repos.pyruns10.1 KB
- scripts/clone-tidymodels-repos.shruns8.5 KB
- scripts/README.md6.7 KB
- scripts/verify-setup.R6.8 KB
- source-guide.md21.8 KB
- testing-patterns-source.md18.3 KB
- transformations.md17.4 KB
- troubleshooting-source.md15.4 KB