formex (format expressions) is a vocabulary + detection + transformation engine for the column types found in research data. Point it at a column and it tells you what the values are — a calendar date, an ISBN, a US state, a person name, a currency amount — and then standardizes them to a stable, analysis-ready form.
It is built around a versioned ontology of semantic types, a library of deterministic detectors, and a two-stage router → verifier classifier that returns a graceful, confidence-aware answer rather than a forced guess.
Installation
# install.packages("remotes")
remotes::install_github("lecy/formex")The learned router additionally uses xgboost (a soft dependency); without it, formex falls back to a model-free signature router.
Two entry points
1. guess_data_type() — what is this column?
library(formex)
guess_data_type(c("03/15/2019", "12/31/2020", "01/01/2021"))$route
#> data_type "temporal"
#> semantic_family "date"
#> semantic_type "calendar"
#> format_label "calendar"
#> depth 4 # resolved all the way to a leaf
#> confidence 1.00The $route record anchors the column to the ontology (data_type → semantic_family → semantic_type → format_label) and truncates gracefully: when the values cannot pin a leaf, it stops at the deepest level it can actually defend (depth 0–4). The legacy detector-based fields ($guess, $ontology) are returned alongside, unchanged.
2. fx_stabilize() — put it in a standard form
fx_stabilize(c("isbn 0395629764", "ISBN 957-33-0471-6"),
"administrative", "isbn")$stable
#> "0395629764" "9573304716"
fx_stabilize(c("California", "TX", "Ohio"), "geographic", "us_state")$stable
#> "CA" "TX" "OH"Each ontology row carries a recipe (a small transform DSL) that normalizes the raw values and reports the stable format + import rule.
How it works
-
Router (Stage 1) shortlists candidate semantic types. Two ship: a learned xgboost model over the full value profile (
fx_extract_features()), and a model-free signature router.guess_data_type(router=)picks the strategy. - Verifier (Stage 2) confirms a leaf deterministically with confirm = detect ∘ transform, gated by a foil-selectivity test so permissive types truncate instead of claiming a false leaf.
-
Ontology (
fx_ontology()) is the shared vocabulary — stablesemantic_type_ids and per-type recipes — thatguess_data_type()andfx_stabilize()both speak.