library(rdantic)
#>
#> Attaching package: 'rdantic'
#> The following object is masked from 'package:graphics':
#>
#> frame
#> The following object is masked from 'package:base':
#>
#> dateR has three quiet failure modes this vignette’s types guard against:
a Date is a number wearing a class, a factor is an integer
wearing labels, and a plain string is neither until something parses it.
rdantic gives each of these its own type instead of letting them
silently interoperate with plain numbers and strings.
Dates and datetimes
date accepts Date vectors,
datetime accepts POSIXct vectors. Unlike plain
numbers, ISO-8601 text is parsed – it is the one unambiguous
serialization of an instant – but never silently to NA:
text that does not parse is an error, not a missing value.
date("2024-05-17") # ISO-8601 is unambiguous, so it is parsed
#> [1] "2024-05-17"
date(as.Date("2024-05-17"))
#> [1] "2024-05-17"
datetime("2024-05-17T09:30:00")
#> [1] "2024-05-17 09:30:00 UTC"
date("17/05/2024") # wrong layout, not a silent NA
#> Error:
#> ! 1 validation problem in date
#> <value> expected date, got chr[1] "17/05/2024" -- expected YYYY-MM-DD
date(19860) # a number is not a date
#> Error:
#> ! 1 validation problem in date
#> <value> expected date, got num[1] 19860 -- wrap it explicitly: as.Date()
num(Sys.Date()) # ... and a date is never silently a number
#> Error:
#> ! 1 validation problem in num
#> <value> expected num, got date[1] "2026-10-15" -- a <Date> is never silently unclassedLike any other type, a date can carry a length or be used inside a union or a container:
Restricted factors
fct(a, b, ...) accepts a factor with exactly those
levels, and promotes character input whose values are all among them.
Use one_of() (vignette("types-in-depth")) when
a plain string should come out; use fct() when a factor
with a fixed, ordered level set should.
size <- fct("low", "mid", "high")
size("mid") # character, promoted to a factor
#> [1] mid
#> Levels: low mid high
levels(size(c("high", "low")))
#> [1] "low" "mid" "high"
size("enormous") # not one of the declared levels
#> Error:
#> ! 1 validation problem in fct("low", "mid", "high")
#> <value> expected fct("low", "mid", "high"), got chr[1] "enormous" -- levels are low, mid, high
fct()(factor("anything")) # fct() with no levels: any factor, no coercion
#> [1] anything
#> Levels: anythingMissing values
NA sails through most R operators without complaint.
no_na(T) wraps any type to additionally reject it – see
vignette("types-in-depth") for no_na()
alongside the other combinators.