# datey The **datey** package provides a standardised mapping of dates, including fractions of a day, onto a discrete annual grid, together with exact date and duration 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: 1. **Standardised mapping of dates to a uniform annual timescale.** There is no unique way to map dates to an annual timescale. Without standardisation, sooner or later errors will arise.[^1] 2. **Fixed precision arithmetic.** Using fixed precision excludes common bugs arising from the imprecision of floating point arithmetic.[^2] 3. Handling **whether a date means the start, during or end of a day**. This issue is usually ignored[^3], but systematic errors can accumulate and end up being material. For more detail on the motivation for **datey**, see [Why **datey**?](https://r-datey.logmu.org/articles/why-datey.html). ## Installation Install from CRAN: ``` r install.packages("datey") ``` Or install the latest development version from GitHub: ``` r # install.packages("pak") pak::pak("logmu-org/r-datey") ``` ## Example ``` r library(datey) # Create datey from a base R date ... start <- start_day(as.Date("2018-09-12")) # Exposure includes the whole day # ... or direct from year/month/day exit <- mid_day(2024, 3, 7) # Death is mid-day on average # ... or as a fractional calendar year (which will be rounded to grid precision) 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 # Converted to years when mixed with plain numbers #> [1] 0.05485804 ``` A hands-on guide is provided in [Get started](https://r-datey.logmu.org/articles/datey.html). [^1]: Even the highly-regarded [CMI](https://www.actuaries.org.uk/learn-and-develop/continuous-mortality-investigation) has had issues with inconsistencies on this point within the same model. [^2]: This is sufficiently common that it has a [CRAN FAQ](https://CRAN.R-project.org/doc/FAQ/R-FAQ.html#Why-doesn_0027t-R-think-these-numbers-are-equal_003f). Also see [this note](https://therneau.r-universe.dev/survival/doc/tiedtimes.pdf) on problems caused by floating point imprecision for the `survival` package. Interestingly, that author’s preferred approach is to use integer day counts, which is also fixed precision. [^3]: Possibly on grounds of triviality, but also sometimes simply because handling it is messy in date systems that do not handle fractions of a day. # Package index ## Package overview - [`datey-package`](https://r-datey.logmu.org/reference/datey-package.md) : Exact date and duration arithmetic on an annual grid ## Create a `datey` or `durationy` - [`datey()`](https://r-datey.logmu.org/reference/datey.md) [`start_day()`](https://r-datey.logmu.org/reference/datey.md) [`mid_day()`](https://r-datey.logmu.org/reference/datey.md) [`end_day()`](https://r-datey.logmu.org/reference/datey.md) : Create a `datey` - [`durationy()`](https://r-datey.logmu.org/reference/durationy.md) : Create a `durationy` from an annual duration - [`seq(`*``*`)`](https://r-datey.logmu.org/reference/seq.md) [`seq(`*``*`)`](https://r-datey.logmu.org/reference/seq.md) : Create `datey` or `durationy` sequence vector - [`c(`*``*`)`](https://r-datey.logmu.org/reference/combine.md) [`c(`*``*`)`](https://r-datey.logmu.org/reference/combine.md) [`c(`*``*`)`](https://r-datey.logmu.org/reference/combine.md) : Combine multiple `datey`, `durationy` or `datey_interval` vectors - [`` `[`( ``*``*`)`](https://r-datey.logmu.org/reference/subset.md) [`` `[`( ``*``*`)`](https://r-datey.logmu.org/reference/subset.md) [`` `[`( ``*``*`)`](https://r-datey.logmu.org/reference/subset.md) [`` `[<-`( ``*``*`)`](https://r-datey.logmu.org/reference/subset.md) [`` `[<-`( ``*``*`)`](https://r-datey.logmu.org/reference/subset.md) [`` `[<-`( ``*``*`)`](https://r-datey.logmu.org/reference/subset.md) : Subset `datey`, `durationy` or `datey_interval` vectors ## Properties of `datey` and `durationy` - [`to_ymdf()`](https://r-datey.logmu.org/reference/datey_components.md) [`` `$`( ``*``*`)`](https://r-datey.logmu.org/reference/datey_components.md) : Get year, month, day or day_fraction breakdown of a `datey` - [`is_datey()`](https://r-datey.logmu.org/reference/is_type.md) [`is_datey_interval()`](https://r-datey.logmu.org/reference/is_type.md) [`is_durationy()`](https://r-datey.logmu.org/reference/is_type.md) : Is `x` a `datey`, `durationy` or `datey_interval`? - [`is_start_day()`](https://r-datey.logmu.org/reference/is_xxx_day.md) [`is_mid_day()`](https://r-datey.logmu.org/reference/is_xxx_day.md) : Is a `datey` the start (or end) or middle of a day? - [`is_leap_year()`](https://r-datey.logmu.org/reference/is_leap_year.md) : Is `x` a leap year? ## Conversion to years - [`as.double(`*``*`)`](https://r-datey.logmu.org/reference/as_years_datey.md) [`as.integer(`*``*`)`](https://r-datey.logmu.org/reference/as_years_datey.md) : Convert a `datey` to calendar years (including fractional part) - [`as.double(`*``*`)`](https://r-datey.logmu.org/reference/as_years_durationy.md) [`as.integer(`*``*`)`](https://r-datey.logmu.org/reference/as_years_durationy.md) : Convert a `durationy` to duration in years ## Operators and statistics - [`Ops(`*``*`)`](https://r-datey.logmu.org/reference/ops.md) : Operators for `datey`, `durationy` and `datey_interval` - [`mean(`*``*`)`](https://r-datey.logmu.org/reference/mean.md) [`mean(`*``*`)`](https://r-datey.logmu.org/reference/mean.md) [`mean(`*``*`)`](https://r-datey.logmu.org/reference/mean.md) : Mean value of `datey` or `durationy` - [`Summary(`*``*`)`](https://r-datey.logmu.org/reference/max_min.md) [`Summary(`*``*`)`](https://r-datey.logmu.org/reference/max_min.md) [`Summary(`*``*`)`](https://r-datey.logmu.org/reference/max_min.md) : Minimum, maximum or range of `datey` or `durationy` ## `datey_interval` - [`datey_interval()`](https://r-datey.logmu.org/reference/datey_interval.md) [`` `%to%` ``](https://r-datey.logmu.org/reference/datey_interval.md) : Create a `datey_interval` - [`is_proper()`](https://r-datey.logmu.org/reference/interval_nature.md) [`all_proper()`](https://r-datey.logmu.org/reference/interval_nature.md) [`is_collapsed()`](https://r-datey.logmu.org/reference/interval_nature.md) [`all_collapsed()`](https://r-datey.logmu.org/reference/interval_nature.md) [`any_collapsed()`](https://r-datey.logmu.org/reference/interval_nature.md) : Properties of a `datey_interval` - [`` `$`( ``*``*`)`](https://r-datey.logmu.org/reference/interval_properties.md) : Get the start, end or duration of a `datey_interval` - [`interval_includes()`](https://r-datey.logmu.org/reference/interval_includes.md) [`` `%includes%` ``](https://r-datey.logmu.org/reference/interval_includes.md) : Whether a `datey_interval` includes a `datey` - [`all_of_time`](https://r-datey.logmu.org/reference/all_of_time.md) : 'All of time' — the maximum valid `datey_interval` ## Formatting and printing - [`as.character(`*``*`)`](https://r-datey.logmu.org/reference/text_from_datey.md) [`format(`*``*`)`](https://r-datey.logmu.org/reference/text_from_datey.md) [`print(`*``*`)`](https://r-datey.logmu.org/reference/text_from_datey.md) : Format or print a `datey` - [`as.character(`*``*`)`](https://r-datey.logmu.org/reference/text_from_durationy.md) [`format(`*``*`)`](https://r-datey.logmu.org/reference/text_from_durationy.md) [`print(`*``*`)`](https://r-datey.logmu.org/reference/text_from_durationy.md) : Format or print a `durationy` - [`as.character(`*``*`)`](https://r-datey.logmu.org/reference/text_from_datey_interval.md) [`format(`*``*`)`](https://r-datey.logmu.org/reference/text_from_datey_interval.md) [`print(`*``*`)`](https://r-datey.logmu.org/reference/text_from_datey_interval.md) : Format or print a `datey_interval` ## NA handling - [`is.na(`*``*`)`](https://r-datey.logmu.org/reference/is_NA.md) [`anyNA(`*``*`)`](https://r-datey.logmu.org/reference/is_NA.md) [`is.na(`*``*`)`](https://r-datey.logmu.org/reference/is_NA.md) [`anyNA(`*``*`)`](https://r-datey.logmu.org/reference/is_NA.md) [`is.na(`*``*`)`](https://r-datey.logmu.org/reference/is_NA.md) [`anyNA(`*``*`)`](https://r-datey.logmu.org/reference/is_NA.md) : Whether `datey`, `durationy` or `datey_interval` are NA - [`NA_datey_`](https://r-datey.logmu.org/reference/NAs.md) [`NA_datey_interval_`](https://r-datey.logmu.org/reference/NAs.md) [`NA_durationy_`](https://r-datey.logmu.org/reference/NAs.md) : The `datey`, `durationy` and `datey_interval` versions of NA - [`valid_years_start`](https://r-datey.logmu.org/reference/integer_constants.md) [`valid_years_end`](https://r-datey.logmu.org/reference/integer_constants.md) [`valid_duration_years_max`](https://r-datey.logmu.org/reference/integer_constants.md) : Integer constants # Articles ### All vignettes - [Get started with datey](https://r-datey.logmu.org/articles/datey.md): - [The datey specification](https://r-datey.logmu.org/articles/spec.md): - [Why datey?](https://r-datey.logmu.org/articles/why-datey.md):