A Toolkit for Research Workflows
Overview
Provides utility functions to help researchers implement best practices for their coding projects. Includes tools for reading and cleaning data files, initializing R projects with a standard folder structure and optional YAML configuration, creating 'Quarto' documents from reproducible templates with optional sample data and custom styling, detecting the execution context across interactive, 'Quarto', and script-based workflows, splitting data frames into group-level output files, applying analysis functions to each group with optional parallel execution, and rendering syntactic tree diagrams as standalone PNG images via 'Typst'.
New features
- Added
run_by_group(), the apply half of the split-apply workflow. Accepts either a manifest CSV produced bywrite_by_group(manifest = TRUE)or a named list of data frames. Applies a user-supplied function to each group subset and collects the results into a flat tibble (when the function returns a data frame) or a nested tibble with a list-column (when it returns anything else). Supports parallel execution viafurrrandfuturethrough theworkersargument, with a ceiling atmax(1L, parallelly::availableCores() - 1L)to reserve one core for the main session. Aseedargument enables reproducible parallel execution for analyses involving randomness. - Added
read_clean_csv()for reading CSV files into a tibble withjanitor::clean_names()applied automatically. Supports explicit missing-value codes viana, selective row dropping viadrop_na(acceptsTRUEor a character vector of column names), an optional ingest summary viasummary, and pass-through arguments toreadr::read_csv()via....
Show all changes in 0.4.0Hide the rest of the changes in 0.4.0
- Added
write_clean_csv()for writing data frames to CSV with clean column names. Appliesjanitor::clean_names()if column names are not already clean and reports affected columns via cli feedback. - Added
check_project()for auditing a project directory against toolero conventions. Checks for expected folders, an.Rprojfile,renv.lock, a git repository, a README, a.gitignore, and hidden files such as.RDataor.Rhistory. Operates in two modes: a cli report (default) or a tibble return for programmatic use (error = FALSE). - Added
qmd_to_r()for extracting R code chunks from any.qmdfile into a standalone.Rscript viaknitr::purl(). The output path defaults to the same directory as the input with the extension replaced. Thedocumentationargument controls how much context is preserved in the extracted script. - Added
generate_project_config()for writing a skeleton YAML project configuration file pre-filled with the standard toolero folder structure. Intended to be edited by the user and passed toinit_project()via the newconfigargument.filenameis required and explicit;pathdefaults to".". Anoverwriteargument (defaultFALSE) guards against accidental replacement of an existing config. The file extension is normalized to.ymlregardless of what is supplied. - Added Palmer Penguins attribution (Horst, Hill & Gorman, 2020) to the template
.qmd, thecreate_qmd()roxygen@detailssection, and a provenance note ininst/extdata/.
Breaking changes
init_project(): the standard folder structure has been revised to better reflect research workflow conventions established by The Carpentries and UW-Madison Libraries. The new standard set isdata-raw/,data/,scripts/,output/figures/,output/tables/, andreports/. The previous set (data/,data-raw/,images/,plots/,results/,scripts/,docs/,R/) is no longer created by default.init_project():extra_foldershas been renamed tocustom_folders. The argument now supports a dplyr-select-like syntax: bare names add folders (e.g."models"), names prefixed with"-"suppress creation of that folder from the resolved set (e.g."-output/figures"). Suppression removes only the named leaf -- parent directories are preserved. Duplicate additions emit an informational message and are skipped; references to non-existent folders via"-"emit a warning.create_qmd(): no longer copiesstyles.cssandheader.htmlfrom the package into the project. Custom styling is now controlled exclusively by the newuse_styleargument. Projects that relied oncreate_qmd()copying UW-branded assets should useinit_project(uw_branding = TRUE)to scaffold those files, then passuse_style = TRUEtocreate_qmd()to wire them into the YAML.create_qmd(): sample data is now copied intodata-raw/instead ofdata/, consistent withinit_project()'s folder structure.
New features (continued from above)
init_project(): addedconfigargument. When supplied, the folder list in the YAML file replaces the built-in standard structure entirely.custom_foldersis still applied on top of the config-derived set. Configs are produced bygenerate_project_config()and can be stored in the user home directory for reuse across project types.create_qmd(): addedinclude_examplesargument (defaultTRUE). WhenTRUE, copies a sample dataset (sample.csv) intodata-raw/, a placeholder logo (logo.png) intoassets/, and uses a worked example template with aparamsblock referencing the sample data. WhenFALSE, creates a blank skeleton.qmdwith only the YAML header and a setup chunk -- no sample data, no logo, no example analysis block.create_qmd(): addeduse_styleargument (defaultFALSE). AcceptsFALSE(no custom styling),TRUE(scansassets/for.cssand.htmlfiles), or a directory path (scans that directory instead). When exactly one.cssfile is found, it is added ascss:in the YAML. When exactly one.htmlfile is found, it is added asinclude-before-body:. If multiple files of either type are found, the function errors and asks the user to specify which one to use viayaml_data. This decouples styling frominit_project()and supports non-UW branding workflows.- Added
inst/templates/skeleton.qmd-- a minimal Quarto template used wheninclude_examples = FALSE. Contains the YAML header, a setup chunk withlibrary(toolero), and a single placeholder heading. - Added
inst/templates/logo.png-- a placeholder logo image copied intoassets/wheninclude_examples = TRUE. Reads "your logo goes here" so the user knows to replace it with their own branding. write_by_group():group_colnow accepts a character vector of column names, enabling grouping by more than one column at once. Sanitized filenames join multiple columns with--(e.g.group_col = c("species", "sex")on an Adelie male producesadelie--male.csv); only combinations actually present in the data produce files, not the full cross-product of possible values. Whenmanifest = TRUE, the manifest gains one column per grouping variable (holding the raw, unsanitized value) in addition to a compositegroup_valuecolumn joining the raw values with" | ". Single-column calls are unaffected -- filenames, manifest schema, and behavior are unchanged from previous versions.write_by_group(): addeddrop_naargument (defaultTRUE). Rows with a missing value in any grouping column are dropped before splitting, with a cli message reporting how many rows were dropped and from which column(s) -- this was previously silent, undocumented behavior inherited fromsplit(). Setdrop_na = FALSEto instead treat missing values as their own group rather than dropping them.
Bug fixes
create_qmd():use_style = TRUEnow correctly copiesrci-banner.pngfrominst/assets/into the projectassets/directory. Previously the banner was only copied inside theinclude_examplesblock and was silently omitted whenuse_style = TRUEwas combined withinclude_examples = FALSE.create_qmd():filenameargument now normalizes the file extension to.qmdviafs::path_ext_set(). Passing"my-document"and"my-document.qmd"both producemy-document.qmd; a double extension is never added.init_project(): path construction now usesfs::path()throughout rather thanglue::glue("{path}/{folder}"), ensuring correct behavior on all platforms.init_project(): branding files are now copied frominst/assets/rather thaninst/extdata/, consistent with the rest of the package.
From NEWS.md in the release
Install
Health
- OK13 OK2026-10-17
- NOTE12 OK, 1 NOTE2026-10-01
- OK13 OK2026-08-04
- NOTE12 OK, 1 NOTE2026-08-01
- OK13 OK2026-06-09
Show 2 earlier changesHide 2 earlier changes
- ERROR12 OK, 1 ERROR2026-06-08
- OK5 OK2026-04-25
Documentation
- Help pages
- 15 (3 internal)includes a package overview page
- Examples that run
- 0%8 only when donttest examples are enabled (R CMD check --as-cran) · 3 never run · 1 hold no code
- Exported functions with examples
- 100%
- Documented parameters
- 100%
- Return-value docs
- 100%
- Help pages citing references
- 7%
Downloads
Repository
- PRs merged (all time)
- not measured
- Median days to close, 50 most recently updated closed issues
- 10
- Median days to close, 50 most recently updated closed PRs
- not measured
Stars over time
Releases over time
Issues over time
Commits over time
10 development-tooling and community-health practices detected across 7 families in the upstream repository
Checks run against github.com/erwinlares/toolero on 2026-10-18.
The R CMD check workflow runs on Linux, macOS and Windows, and on R-devel
GitHub Pages site last deployed 2026-10-09 · The repository has a site deploy workflow
pkgdown site last built 2026-10-09
Show all practicesHide 3 practices
This repository shows signs of AI coding tools.
- Claude Codefirst seen 2026-04-24Named in .Rbuildignore: .claudeCommits: at least 1 crediting it in the message
- Claude Opus 51 commit · Sep 2026
Dependencies
Installing toolero adds 83 packages (44 with compiled code, 50 MB of source tarballs). Heaviest: stringi 11 MB, bslib 5.6 MB, pak 3.8 MB.
Code & Tests
People & History
Pick two releases to compare their code metrics.
- 0.4.0Latest2026-07-16 · current release · diff ↗ ·
added 6 exports
arborize, check_project, generate_project_config, qmd_to_r, run_by_group, write_clean_csv - 0.3.0
- 0.2.02026-04-24
- RR 4.6.0 released · 2026-04-24
- RR 4.5.0 released · 2025-04-11
Package metadata
- First published
- 2026-04-24
- Total releases
- 3 / 1 yrs
- License
- MIT + file LICENSE OSI
- Minimum R
- ≥ 4.2.0
- Download size
- 4.0 MB
Cite
Cite this package
Run in R for the authors' preferred citation:
citation("toolero")The package provides a citation file that builds its entry when R runs it. Run citation() to see it.
Cite the R Observatory
For a number measured here: a download total, a coverage figure, an archival date.
From data release v2026-10-21, which the citation names so these numbers can be found later. More on citing and the projects behind them.