ksformat 0.8.4
New features
- Added
flevels(): extracts discrete value-label mappings from aks_formatobject (or registered format name) as a tidy two-columndata.frame(value,label). -
fnew()now supports numeric pattern mode fortype = "numeric": pass one unnamed%f-style pattern (for example"$%,.2f"or"%.1f%%") to format continuous numeric values directly. -
fnew_bid()gains anignore_caseargument. WhenTRUE, both the forward format and reverse invalue use case-insensitive matching. DefaultFALSEpreserves existing behaviour.
ksformat 0.8.1
Documentation refresh
- Added a vignette example showing how to use
franges()labels directly withtidyr::complete()and how to extract unique labels from theaesevformat mappings without converting tofactor().
Internal refactoring (no breaking changes)
-
R/format_parse.Rhas been split in two: text-to-object parsing stays informat_parse.R(874 lines); object-to-text rendering and CSV CNTLOUT import/export (fexport(),fimport(),.format_to_text(), etc.) moves to the newR/format_serialize.R(755 lines). - Three DRY internal helpers added to
utilities.R:.is_eval_label(),.parse_range_key_by_type(),.format_range_interval(). Duplicate switch/if-chains acrossformat_apply.R,format_create.R, andformat_library_app.Rnow delegate to these helpers. - Range-table now carries a
discrete_numeric_possibleflag computed at format creation time.fput()/fput_all()use it to skip theas.character()+match()discrete-key pass for numeric / Date / POSIXt inputs against formats whose discrete keys are all non-numeric strings, broadening the existing fast path. - Friendly-interval regex in
.block_to_stratified_range_format()is now built once per format parse instead of once per mapping entry.
ksformat 0.7.2
New features
-
finput()gains anignore_caseargument. WhenTRUE, label lookup is case-insensitive (equivalent to SASINVALUE name (nocase)). DefaultFALSEpreserves existing behaviour. -
fparse()now correctly propagates the(nocase)option onINVALUEblocks to the resultingks_invalueobject. Previously the flag was parsed but silently discarded. -
fexport()/fparse()round-trips now preserveignore_casefor invalue objects: exporting anocaseinvalue emitsINVALUE name (nocase)which re-imports withignore_case = TRUE. -
print.ks_invalue()now displays a(nocase)flag in the header whenignore_case = TRUE.
ksformat 0.7.1
CRAN release: 2026-05-21
New features
-
fputk()gains ana_as_stringargument. WhenTRUE, anNAin any key component is preserved as the literal string"NA"produced bypaste()instead of being restored toNA_character_. This enables round-trip lookups against formats built viafmap(paste(..., sep = "|"), values), where the stored keys themselves contain"NA". DefaultFALSEpreserves existing behavior (NA →.missing/keep_na). - New
finputk()— composite-label wrapper around INVALUE lookup, mirroringfputk()on the reverse direction. Supports the samesepandna_as_stringarguments and dispatches on the stored invalue’starget_type.
Documentation
- Vignette Example 28: Composite Key Lookup with NA Components — explains why
paste()-built keys contain the literal string"NA"forNAinputs, shows the incorrect result with the defaultna_as_string = FALSE, and demonstrates the correct round-trip withna_as_string = TRUEusing a clinical LBPARAMCDderivation scenario. - Vignette Example 29: Composite Label Invalue Lookup with
finputk()— basic two-column reverse lookup andna_as_string = TRUEusage withNAkey components. -
examples/CompositeKeyNA.R— runnable companion script for both examples.
ksformat 0.7.0
New features
- New format type
stratified_range— combines a discrete stratum (study arm, subject id, composite key, …) with per-stratum numeric / Date / POSIXct range buckets. Apply withfputk(), passing the stratum column(s) first and the value column last. - New builder
fmap_strata(stratum, low, high, label, inc_low, inc_high, sep)— produces aks_fmapready forfnew(..., type = "stratified_range"). The chosen separator is carried as an attribute and picked up automatically byfnew(). - New builder
fmap_ranges(low, high, label, inc_low, inc_high)— convenience helper that turns parallel vectors of numeric / Date / POSIXct bounds and labels into canonical range keys, removing the need to hand-craft"low,high,inc_low,inc_high"strings. -
fparse()/fexport()support the new type via theVALUE name (stratified_range, range_subtype: numeric|date|datetime, strata_sep: |)block syntax. Both canonical"STRATUM|low,high,inc_low,inc_high"keys and the friendly"STRATUM"|[low, high)interval form are accepted, including per-stratum.missing|STRATUM/.other|STRATUMdirectives. -
print.ks_format()renders stratified formats grouped underStratum "X":headers.
Documentation
- Vignette Example 26: Stratified Range Lookup with
fputk()— programmatic and text-based construction, date subtype with per-subject windows, per-stratum and global.otherfallbacks, andfexport()/fparse()roundtrip. - Vignette Example 27: Plain Range Lookup with
fmap_ranges()— builds a numeric age-band format without hand-crafted canonical keys. -
examples/StratifiedRanges.R— runnable companion script.
ksformat 0.6.7
Documentation
- Added vignette Example 25: Date Range Bucketing covering
date_rangeanddatetime_rangetypes: fiscal-year bucketing,fparse()with ISO bounds,LOW/HIGHopen-ended arms,fput_all()multilabel overlapping windows, auto-detection,fexport()/fparse()roundtrip, anddatetime_rangeshift bucketing. - Added
examples/DateRanges.R— a self-contained runnable script with the same scenarios for quick interactive exploration.
ksformat 0.6.6
New features
-
date_rangeanddatetime_rangeformat types: bucket Date or POSIXct values into character labels using interval bounds written as ISO date/datetime strings. Both types reuse the numeric range-table fast path (sorted-disjoint ranges hitfindInterval()in C). -
fnew()acceptstype = "date_range"/"datetime_range"and a new optionaldate_formatargument for parsing custom bound strings. -
fparse()accepts interval notation with date/datetime bounds, e.g.[2024-01-01, 2025-01-01) = "FY24"and[2024-01-01 08:00, 2024-01-01 16:00) = "Day". The type is auto-detected when no explicit subtype is given. -
fexport()renders date/datetime range bounds as ISO strings, enabling full roundtrip throughfparse(). - Bounds support
LOW/HIGHkeywords (rendered as-Inf/+Infand emitted back asLOW/HIGHon export) and exclusive(/)brackets.
ksformat 0.6.5
Performance
- Precomputed range table:
ks_formatobjects now carry a pre-builtrange_tablefield. Range keys are parsed once at format-creation time (infnew(),fparse(),fimport()) rather than on everyfput()call. -
findInterval()fast path infput(): sorted, non-overlapping numeric ranges with standard[low, high)semantics now use R’s built-infindInterval()(O(n log k) in C), giving a ~10–14× speedup over the previous per-range R loop on large inputs (benchmarked at 1M rows). -
skip_discreteoptimisation infput(): pure numeric-range formats (no discrete keys) with numeric input now skip theas.character()+match()step entirely. -
is_missing(): removed a redundantis.nan()pass on numeric vectors —is.na()already returnsTRUEforNaN.
Bug Fixes
-
.build_range_table(): ranges defined out-of-order are now sorted by(low, high)before storage, so thefindIntervalfast path triggers regardless of definition order. -
.build_range_table(): removed a deadattr<-loop that silently had no effect (subsetting a character vector creates a copy, stripping any attribute set on the subset).
ksformat 0.6.4
New Features
- Added
franges(): extracts all range entries from aks_formatobject as a tidydata.framewith columnslow,high,inc_low,inc_high, andlabel. Accepts either aks_formatobject or a registered format name. - Added
fmap_to_ranges(): reverse-looks up range bounds by label — given a vector of coded values that match range labels in a format, returns the correspondinglow/highbounds (and inclusivity flags) per element.
ksformat 0.6.3
Bug Fixes
- Fixed
fput()(andfputk()) losing thetzoneattribute when returningPOSIXctvalues from a value-type format. The result vector was seeded from a tzone-less NA, so values were silently displayed in the local timezone instead of the source timezone (e.g. UTC), causing an apparent time-shift. Thetzoneattribute of the mapped values is now propagated to the result.
ksformat 0.6.2
New Features
- Added
format_library_app()Shiny browser for the global format library, including filters by name/object type, per-object details, and mapping table rendering for bothks_formatandks_invalueentries. - Added an RStudio addin entry (Format Library Browser) to launch
format_library_app()from the Addins menu.
Enhancements
- Replaced plain-text print preview in the app with a formatted mapping table that shows mappings, range rules, and special directives (
.missing,.other) in structured form. - Added app management UX improvements: explicit quit action with confirmation modal, plus confirmations for destructive clear/remove operations.
Documentation
- Added
format_library_app()docs and package index references. - Updated README with interactive browser usage and behavior summary.
ksformat 0.6.1
Documentation
- Cheat sheet updated: added
fputk()examples (basic composite key,fmap()data-driven Date lookup,fparse()text-defined Date lookup), addedfmap()to the Function Reference table, and rearranged layout to fit landscape page. - Vignette Example 22 added: “Date Lookup via
fparse()andfputk()” — character lookup, native Date lookup withfmap(), and round-trip viafexport()/fparse().
ksformat 0.6.0
Breaking Changes
-
fnew()no longer accepts thereverseparameter. Usefmap(keys, values)instead ofsetNames(values, keys)withreverse = FALSEto create data-driven formats consistently for all types.
New Features
- New
fmap(keys, values)helper creates a key-value mapping that tellsfnew()to use the natural direction (keys → values) without reversal. Works identically for character, numeric, Date, POSIXct, and logical formats.
Documentation
- Vignette Example 21 rewritten: “Consistent Data-Driven Formats with
fmap()” — demonstrates howfmap(keys, values)replaces the oldsetNames()+reverse = FALSEpattern. - Updated Example 20 (Composite Key Lookup) to use
fmap().
ksformat 0.5.1
Bug Fixes
- Fixed Example 20 (Composite Key Lookup) in vignette: added missing
reverse = FALSEto the character format created withsetNames(), which caused all lookups to return “NOT FOUND”.
ksformat 0.5.0
New Features
-
fnew()gains areverseparameter for explicit control over named-vector direction. Setreverse = FALSEto use the naturalsetNames(values, keys)convention consistently for all format types — character, numeric, Date, POSIXct, and logical. The default (NULL) preserves backward-compatible auto-detection: reversal for character/numeric, no reversal for value types.
Documentation
- New vignette Example 21: “Consistent Data-Driven Formats with
reverse” — demonstrates how to build lookup formats from data frames using the samesetNames()pattern for all output types. - Updated
fnew()documentation with detailed explanation of the named-vector reversal convention and the newreverseparameter.