Agent-almanac build-parameterized-report
git clone https://github.com/pjt222/agent-almanac
T=$(mktemp -d) && git clone --depth=1 https://github.com/pjt222/agent-almanac "$T" && mkdir -p ~/.claude/skills && cp -r "$T/i18n/caveman/skills/build-parameterized-report" ~/.claude/skills/pjt222-agent-almanac-build-parameterized-report-cedaf2 && rm -rf "$T"
i18n/caveman/skills/build-parameterized-report/SKILL.mdBuild Parameterized Report
Create reports that accept parameters to generate multiple customized variations from single template.
When Use
- Generating same report for different departments, regions, time periods
- Creating client-specific reports from template
- Building dashboards filtering to specific subsets
- Automating recurring reports with different inputs
Inputs
- Required: Report template (Quarto or R Markdown)
- Required: Parameter definitions (names, types, defaults)
- Optional: List of parameter values for batch generation
- Optional: Output directory for generated reports
Steps
Step 1: Define Parameters in YAML
For Quarto (
report.qmd):
--- title: "Sales Report: `r params$region`" params: region: "North America" year: 2025 include_forecast: true format: html: toc: true ---
For R Markdown (
report.Rmd):
--- title: "Sales Report" params: region: "North America" year: 2025 include_forecast: true output: html_document ---
Got: YAML header contains
params: block with named parameters, each having default value of correct type.
If fail: Rendering fails with "object 'params' not found"? Ensure
params: block correctly indented under YAML frontmatter. For Quarto, params must be at top level of YAML, not nested under format:.
Step 2: Use Parameters in Code
```{r} #| label: filter-data data <- full_dataset |> filter(region == params$region, year == params$year) nrow(data) ``` ## Overview for `r params$region` This report covers the `r params$region` region for `r params$year`. ```{r} #| label: forecast #| eval: !expr params$include_forecast # This chunk only runs when include_forecast is TRUE forecast_model <- forecast::auto.arima(data$sales) forecast::autoplot(forecast_model) ```
Got: Code chunks reference parameters via
params$name. Conditional chunks use #| eval: !expr params$flag for Quarto. Inline R expressions like `r params$region` render dynamic text.
If fail:
params$name returns NULL? Verify parameter name matches exactly between YAML definition and code reference (case-sensitive). Check default values correct type.
Step 3: Render with Custom Parameters
Single render:
# Quarto quarto::quarto_render( "report.qmd", execute_params = list(region = "Europe", year = 2025) ) # R Markdown rmarkdown::render( "report.Rmd", params = list(region = "Europe", year = 2025), output_file = "report-europe-2025.html" )
Got: Single report renders successfully with custom parameter values overriding YAML defaults. Output file created at specified path.
If fail: Quarto render fails? Check
quarto CLI installed and on PATH. R Markdown render fails? Verify rmarkdown installed. Ensure parameter names in execute_params (Quarto) or params (R Markdown) match YAML definitions exactly.
Step 4: Batch Render Multiple Reports
regions <- c("North America", "Europe", "Asia Pacific", "Latin America") years <- c(2024, 2025) # Generate all combinations combinations <- expand.grid(region = regions, year = years, stringsAsFactors = FALSE) # Render each purrr::pwalk(combinations, function(region, year) { output_name <- sprintf("report-%s-%d.html", tolower(gsub(" ", "-", region)), year) quarto::quarto_render( "report.qmd", execute_params = list(region = region, year = year), output_file = output_name ) })
Got: One HTML file per region-year combination.
If fail: Check parameter names match exactly between YAML and code. Ensure all parameter values valid.
Step 5: Add Parameter Validation
#| label: validate-params stopifnot( "Region must be a valid region" = params$region %in% valid_regions, "Year must be numeric" = is.numeric(params$year), "Year must be reasonable" = params$year >= 2020 && params$year <= 2030 )
Got: Validation code chunk runs at start of each render, stops with informative error if any parameter out of range or wrong type.
If fail:
stopifnot() produces unhelpful error messages? Switch to explicit if (!cond) stop("message") calls for clearer diagnostics.
Step 6: Organize Output
# Create output directory output_dir <- file.path("reports", format(Sys.Date(), "%Y-%m")) dir.create(output_dir, recursive = TRUE, showWarnings = FALSE) # Render with output path quarto::quarto_render( "report.qmd", execute_params = list(region = region), output_file = file.path(output_dir, paste0("report-", region, ".html")) )
Got: Output files written to date-stamped subdirectory with descriptive names (e.g.,
reports/2025-06/report-europe.html).
If fail:
dir.create() fails? Check parent directory exists and is writable. On Windows, verify path length does not exceed 260 characters.
Checks
- Report renders with default parameters
- Report renders with each set of custom parameters
- Parameters validated before processing
- Output files named descriptively
- Conditional sections render correctly based on parameters
- Batch generation completes for all combinations
Pitfalls
- Parameter name mismatch: YAML names must exactly match
references in codeparams$name - Type coercion: YAML may parse
as integer but code expects character. Be explicit.year: 2025 - Conditional evaluation: Use
not#| eval: !expr params$flag
in Quartoeval = params$flag - File overwriting: Without unique output names, each render overwrites previous
- Memory in batch mode: Long batch runs may accumulate memory. Consider using
for isolation.callr::r()
See Also
- base Quarto document setupcreate-quarto-report
- tables that adapt to parametersgenerate-statistical-tables
- parameterized academic reportsformat-apa-report