--- title: "Extending aion" author: "N. Frerebeau" date: "`r Sys.Date()`" output: rmarkdown::html_vignette: number_sections: yes fig_caption: yes toc: true bibliography: bibliography.bib vignette: > %\VignetteIndexEntry{Extending aion} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` ```{r setup} library(aion) ``` **aion** offers a simple API that can be extended and used by other specialized packages. The following packages rely on **aion**: * [**ananke**](https://github.com/tesselle/ananke) (quantitative chronology in archaeology). * [**kairos**](https://github.com/tesselle/kairos) v2.0 (analysis of chronological patterns from archaeological count data). * [**ArchaeoPhases**](https://github.com/ArchaeoStat/ArchaeoPhases) v2.0 (post-processing of MCMC simulations for chronological modelling). # Calendars and Dates The following example is used to build a simple solar calendar with 365 days each year and no leap-year rule. This is the ancient Egyptian calendar. You will find full details of the calculations and detailed explanations in @reingold2018 (p. 29). You can define additional calendars by creating S4 classes that inherit from the `TimeScale` class exported by **aion**: ```{r} ## Egyptian calendar E <- setClass( Class = "EgyptianCalendar", prototype = list( name = "Egyptian", fixed = -272787, direction = 1L, year = 365 ), contains = "TimeScale" ) ``` Once the calendar has been defined, you need to build methods for converting *rata die* to and from this calendar: ```{r} ## Convert Egyptian dates to rata die ## NB: this method MUST return a RataDie object setMethod( f = "fixed", signature = c( year = "numeric", month = "numeric", day = "numeric", calendar = "EgyptianCalendar" ), definition = function(year, month, day, calendar) { rd <- calendar_fixed(calendar) + 365 * (year - 1) + 30 * (month - 1) + day - 1 as_fixed(rd) } ) ## Convert rata die to Egyptian dates ## NB: this method MUST return a data.frame setMethod( f = "as_date", signature = c(object = "numeric", calendar = "EgyptianCalendar"), definition = function(object, calendar) { day <- object - calendar_fixed(calendar) year <- day %/% 365 + 1 month <- (day %% 365) %/% 30 + 1 day <- day - 365 * (year - 1) - 30 * (month - 1) + 1 data.frame(year = year, month = month, day = day) } ) ## Convert rata die to Egyptian years setMethod( f = "as_year", signature = c(object = "numeric", calendar = "EgyptianCalendar"), definition = function(object, calendar, ...) { (object - calendar_fixed(calendar)) %/% 365 + 1 } ) ``` Now you can use your calendar: ```{r} ## Create a calendar object cal <- E() ## Convert 161/7/15 in rata die fixed( year = 161, month = 7, day = 15, calendar = cal ) ## Convert -214193 r.d. to an Egyptian date as_date(-214193, calendar = cal) ``` The definition of new calendars, combined with the Julian and Gregorian calendars already included in **aion**, allows you to build conversion tools: ```{r} ## Build a conversion function from Gregorian CE years to Egyptian years Gregorian_to_Egyptian <- convert(CE(), E()) ## Convert 2023 (Gregorian) to the Egyptian calendar Gregorian_to_Egyptian(2023) ``` # Time Series A time series object is simply an $n \times m \times p$ `array`, with $n$ being the number of observations, $m$ being the number of series and with the $p$ columns of the third dimension containing extra variables for each series. This `array` comes with an extra `time` slot that store the observations times expressed in *rata die*. You can create classes that inherits from the `TimeSeries` class. As an example, you can create a class that represent the results of the calibration of radiocarbon dates (this code comes from the [**ananke**](https://packages.tesselle.org/ananke/) package): ```{r} .CalibratedAges <- setClass( Class = "CalibratedAges", slots = c( ages = "numeric", # Stores the radiocarbon ages to be calibrated errors = "numeric", # Store the standard deviation of the radiocarbon ages curves = "character" # Store the name of the calibration curve ), contains = "TimeSeries" ) ``` All methods defined in **aion** can then be used on objects belonging to this new class (e.g. `plot()`). # References