The datey package provides a standardised mapping of dates onto an annual grid together with precise date and duration-related arithmetic.
If you work primarily with mortality rates and time intervals defined by year but your input data uses dates, and precision is important, then it is worth considering using datey.
Classic examples are mortality experience analysis and the valuation of life assurance and annuities. Mortality rates are defined per annum but experience and valuation data is usually defined using dates (i.e. days).
The benefits of using datey are:
A consistent framework for mapping dates to annual units. Even the mighty CMI has come a cropper over inconsistencies on this point.
Fixed precision arithmetic. This approach excludes some common bugs arising from the imprecision of floating point arithmetic[^FloatingPoint]. This is a sufficiently common problem that there is a CRAN FAQ on the topic. And, in a mortality-specific context, Terry Therneau wrote this note on the problems floating point can cause for users his R surv package.1
Handling whether a date means the start, during or end of a day. This may seem trivial but systematic errors can accumulate and end up being material.
For more detail on the motivation for datey, see Why datey?.
Installation
You can install the development version of datey from GitHub with:
# install.packages("pak")
pak::pak("logmu-org/r-datey")Example
library(datey)
# Create datey from a base R date ...
start <- as_start_day(as.Date("2018-09-12")) # Include *all* start day
# ... or direct from year/month/day
exit <- mid_day(2024, 3, 7) # Death is mid-day on average
# ... or simply as a fractional calendar year
t <- datey(2021.234) # A date in the middle of the exposure period
c(start, t, exit) # 2018-09-12.0 2021-03-27.4098 2024-03-07.5
#> [1] 2018-09-12.0 2021-03-27.4098 2024-03-07.5
interval <- start %to% exit # Exposure period
interval # [2018-09-12.0, 2024-03-07.5)
#> [1] [2018-09-12.0, 2024-03-07.5)
interval %includes% t # Test if a point in time is in an interval
#> [1] TRUE
exit - start # Duration of exposure period
#> [1] 5.485804 yr
interval$duration # Same thing
#> [1] 5.485804 yr
interval$duration * 0.01 # Implicit conversion to years when mixed with numerics
#> [1] 0.05485804A hands-on guide is provided in Get started.
