Skip to content
Back to skills

Add Dials Parameter

ASecurity

**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. ----------------------------------------------------------------------------...

  • 10 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added May 26, 2026
developmentgobashtestingdebugginggitapidocumentation

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 20 files and shows the line behind each finding

Scanned May 27, 2026

npx -y skills add tidymodels/skills --skill add-dials-parameter --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Add Dials Parameter?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Add Dials Parameter
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tidymodels-add-dials-parameter/badge)](https://www.skillsdirectory.com/skills/tidymodels-add-dials-parameter)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
# 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](references/extension-guide.md)

**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](references/source-guide.md)

**Package detection:** DESCRIPTION file has `Package: dials`

--------------------------------------------------------------------------------

## Getting Started

**Before you begin**, verify your development context:

```r
# 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:**

1. **DESCRIPTION file check** (most reliable):

   - If `Package: dials` → Source development

   - If `Package: [anything else]` → Extension development

2. **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"

3. **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

1. **Parameter Types**: Quantitative (numeric) vs Qualitative (categorical)
2. **Range Specification**: Fixed ranges, unknown bounds, transformations
3. **Finalization**: Resolving data-dependent parameters with training data
4. **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](references/package-repository-access.md)

- 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](references/package-repository-access.md) 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](references/quantitative-parameters.md)

- **Quantitative, transformed**: Log scale or other transformation →
  [Quantitative Parameters](references/quantitative-parameters.md) +
  [Transformations](references/transformations.md)

- **Quantitative, data-dependent**: Upper bound depends on dataset →
  [Quantitative Parameters](references/quantitative-parameters.md) +
  [Data-Dependent Parameters](references/data-dependent-parameters.md)

- **Qualitative**: Discrete categorical options → [Qualitative
  Parameters](references/qualitative-parameters.md)

--------------------------------------------------------------------------------

## Complete Examples

### Example 1: Simple Quantitative Parameter

A threshold parameter with fixed range (extension pattern):

```r
# 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
# 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
# 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
# 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
# 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](references/extension-guide.md) - Creating new
  packages with custom parameters

- [Source Development Guide](references/source-guide.md) - Contributing to dials
  package

### Parameter Types

- [Parameter System Overview](references/parameter-system.md) - Architecture and
  parameter classes

- [Quantitative Parameters](references/quantitative-parameters.md) - Creating
  numeric parameters

- [Qualitative Parameters](references/qualitative-parameters.md) - Creating
  categorical parameters

- [Transformations](references/transformations.md) - Using log scale and custom
  transformations

- [Data-Dependent Parameters](references/data-dependent-parameters.md) - Using
  unknown() and finalization

- [Grid Integration](references/grid-integration.md) - How parameters work with
  grids

### Source Development

- [Testing Patterns (Source)](references/testing-patterns-source.md) -
  dials-specific testing

- [Best Practices (Source)](references/best-practices-source.md) - dials
  conventions and patterns

- [Troubleshooting (Source)](references/troubleshooting-source.md) - 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](references/package-extension-prerequisites.md)

- **Dependencies**: Add `dials` to DESCRIPTION Imports

- **Roxygen**: Configure documentation system

- **Testing**: Set up testthat framework

### For Source Development

To contribute parameters to dials:

1. Clone the repository:
   ```bash
   git clone https://github.com/tidymodels/dials
   cd dials
   ```

2. Install dependencies:
   ```r
   pak::pak()
   ```

3. Load the package:
   ```r
   devtools::load_all()
   ```

See [Source Development Guide](references/source-guide.md) for complete setup.

--------------------------------------------------------------------------------

## Development Workflow

### Fast Iteration Cycle

For rapid parameter development:

1. **Create** parameter function in `R/` directory
2. **Load** with `devtools::load_all()`
3. **Test** interactively in console
4. **Document** with roxygen comments
5. **Verify** with tests

See [Development Workflow](references/package-development-workflow.md) 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()` and `value_seq()` work correctly

- **Edge cases**: Invalid inputs produce errors

See testing guides:

- Extension: [Testing
  Requirements](references/package-extension-requirements.md#testing-requirements)

- Source: [Testing Patterns (Source)](references/testing-patterns-source.md)

--------------------------------------------------------------------------------

## 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:

```r
#' @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](references/package-roxygen-documentation.md) for
complete patterns.

### Creating Companion Values Vectors

For qualitative parameters, create a `values_*` vector:

```r
#' @rdname param_name
#' @export
values_param_name <- c("option1", "option2", "option3")
```

This convention is strongly recommended for consistency.

--------------------------------------------------------------------------------

## Next Steps

### For Extension Developers

1. Read [Extension Development Guide](references/extension-guide.md)
2. Choose your parameter type:
   [Quantitative](references/quantitative-parameters.md) or
   [Qualitative](references/qualitative-parameters.md)
3. Implement your parameter following the examples above
4. Add tests following [Testing
   Requirements](references/package-extension-requirements.md#testing-requirements)
5. Document with roxygen following [Documentation
   Guide](references/package-roxygen-documentation.md)

### For Source Contributors

1. Read [Source Development Guide](references/source-guide.md)
2. Study existing parameters in `repos/dials/R/param_*.R`
3. Understand [Parameter System Overview](references/parameter-system.md)
4. Follow [Best Practices (Source)](references/best-practices-source.md)
5. Add tests to `tests/testthat/test-params.R`
6. Submit PR following [Source Guide](references/source-guide.md) checklist

### Related Skills

- [add-yardstick-metric](../add-yardstick-metric/SKILL.md) - Custom metrics may
  need custom tuning parameters

- [add-recipe-step](../add-recipe-step/SKILL.md) - Recipe steps often have
  tunable parameters

- [add-parsnip-model](../add-parsnip-model/SKILL.md) - Model specifications have
  tunable main arguments

- [add-parsnip-engine](../add-parsnip-engine/SKILL.md) - 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

Files in this skill

  • SKILL.md20.7 KB
  • evals/README.md8.7 KB
  • evals/evals.json14 KB
  • evals/grading-config.json7.5 KB
  • references/best-practices-source.md16.2 KB
  • references/data-dependent-parameters.md23.5 KB
  • references/extension-guide.md26.2 KB
  • references/grid-integration.md18.7 KB
  • references/package-best-practices.md9.1 KB
  • references/package-development-workflow.md6.9 KB
  • references/package-extension-prerequisites.md16.1 KB
  • references/package-extension-requirements.md33.7 KB
  • references/package-imports.md6.3 KB
  • references/package-repository-access.md13.9 KB
  • references/package-roxygen-documentation.md13.4 KB
  • references/package-testing-patterns.md12.2 KB
  • references/package-troubleshooting.md11.4 KB
  • references/parameter-system.md16.4 KB
  • references/qualitative-parameters.md20.6 KB
  • references/quantitative-parameters.md19.4 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.