knitr::opts_chunk$set( collapse = TRUE, comment = "#>" )
this_year <- as.integer(format(Sys.Date(), "%Y"))
Archaeologists, geologists, and other palaeoscientists use different systems for numbering years in the distant past. For example, the year 10,000 BCE is 11,950 Before Present or 11.95 ka. It is usually fine to store years as a plain numeric vector in R, but sometimes it helps to be explicit about which system is being used:
The era package helps in these cases by providing classes which define the 'era' associated with a vector of years and functions for formatting, combining, and transforming years with different eras. This vignette is an introduction to the main features of the package.
library("era") library("tibble") library("dplyr")
Vectors of years with an era are represented by the yr
(era_yr
) class, which is constructed with yr()
:
yr(c(10000, 11000, 12000), "BP")
The first argument is a numeric vector of years. These can be integers or doubles.
The second argument, era
, defines the numbering system associated with the years.
This is an object of class era
which defines the parameters of the calendar, epoch and time scale.
Most of the time, you can simply specify the abbreviated label of the era, which will be looked up in the standard eras defined by eras()
:
yr(c(10000, 11000, 12000), "BCE") yr(c(10000, 11000, 12000), "uncal BP") yr(c(10000, 11000, 12000), "ka")
yr_era()
returns details of the era associated with a yr
vector:
neolithic <- yr(11700:7500, "BP") yr_era(neolithic)
yr_era()
, and its pipe-friendly alias yr_set_era()
, can also be used to set the era of an existing object:
chalcolithic <- 7500:6000 yr_era(chalcolithic) <- yr_era(neolithic) yr_era(chalcolithic)
Note that this only updates the vector's era attribute; it doesn't change the data itself.
To convert years from one era to another, you need to use the yr_transform()
function.
yr
vectors fit nicely into tables, both base data frames and tibbles:
postglacial <- tribble( ~period, ~start_ka, "Late Holocene", 4.2, "Mid Holocene", 8.326, "Early Holocene", 11.7, "Younger Dryas", 12.9, "Bølling-Allerød", 14.7, "Heinrich 1", 17.0 ) postglacial |> mutate(start_ka = yr(start_ka, "ka"))
era includes built-in definitions of many time scales and year numbering systems from contemporary and historic calendars.
eras()
returns the full list of built-in definitions.
You can use any definition in this list by passing its abbreviated label
to era()
or as the era
argument of yr()
or any other function in the package:
era("BP") yr(10000, "BP") yr_transform(yr(10000, "BP"), "BCE")
If you need to use a time scale that is not in this list, you can define it yourself with era()
.
Suggestions for new eras to include in the package are also welcome; please create an issue on GitHub with suggestions.
all_eras <- eras() all_eras$this_year <- NA na_era <- is.na(era_year_days(all_eras$unit)) all_eras$this_year[!na_era] <- this_year(all_eras$label[!na_era]) knitr::kable(all_eras)
Eras are defined by the era
class with the following parameters:
1
) or backwards (-1
) from the epochThese parameters are passed to era()
to construct an era
object.
epoch
, unit
, scale
, and direction
determine the transformation between eras;
label
and name
are purely descriptive.
You can define arbitrary eras by using the era()
function directly:
era("T.A.", epoch = -9021, name = "Third Age", direction = 1)
As long as all the parameters are specified correctly, user-defined eras can also be used in yr_transform()
.
yr_transform()
{#yr_transform}Use yr_transform()
to convert between eras:
postglacial |> mutate(start_ka = yr(start_ka, "ka")) |> mutate(start_bp = yr_transform(start_ka, era("BP")), start_bce = yr_transform(start_ka, era("BCE")))
This function implements a generic algorithm for transforming years based on the era parameters described above.
This means that, with a few exceptions (see invalid transformations, you can transform between any two eras that can be described by the era
class.
By default, era transformations are exact:
yr(500000, "BCE") |> yr_transform(era("ka"))
Often, this precision is not necessary.
For example, when converting years between calendar- and present-based eras, the r this_year - 1950
year difference between the formal definition of "Present" and the actual present is rarely significant on a geologic time scale.
Use the precision
argument of yr_transform
to get rounded results:
yr(10000, "BP") |> yr_transform(era("BCE"), precision = 1000) yr(500000, "BCE") |> yr_transform(era("mya"), precision = 0.1)
Some transformations are not possible.
Notably, the length of a 'radiocarbon year' is not well defined on a calendar time scale without calibration.
Eras that use non-calendar year unit are represented with an NA
and will cause an error if passed to yr_transform()
:
era_unit(era("uncal BP")) yr_transform(yr(9000, "uncal BP"), era("cal BP"))
c14_calibrate()
from the stratigraphr package implements radiocarbon calibration with yr
objects.
Conversion between eras that both have an NA
unit are also an error, following the R convention that NA == NA
is NA
.
In other words, we don't know whether two non-calendar units are the same non-calendar unit.
This means that it is not possible to use yr_transform()
to convert bp (radiocarbon years Before Present) to bce (radiocarbon years before the Common Era) years, for example.
The yr
class is based on vctrs, ensuring type- and size-stable computations.
For example, you can do arithmetic with year vectors:
a <- yr(1500, "CE") b <- yr(2020, "CE") b - a
But only when they have the same era:
c <- yr(0.5, "ka") b - c
Note that, when comparing eras, only the parameters significant to the transformation are considered (i.e. not label
or name
).
This means that it is possible to combine year vectors with differently-named but functionally equivalent eras, for example era("BP")
and era("cal BP")
, although doing so will print a warning about the loss of information:
era("BP") == era("BC") era("BP") == era("cal BP") yr(1000, "BP") + yr(1000, "cal BP")
Years will be coerced to a plain numeric vector if a computation means their era no longer makes sense:
a * b
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.