-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathera.Rmd
More file actions
233 lines (171 loc) · 8.06 KB
/
era.Rmd
File metadata and controls
233 lines (171 loc) · 8.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
---
title: "Years with an era"
output:
rmarkdown::html_vignette:
toc: true
toc_depth: 2
vignette: >
%\VignetteIndexEntry{Years with an era}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
```
```{r include=FALSE}
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](https://en.wikipedia.org/wiki/Before_Present) or 11.95 [ka](https://en.wikipedia.org/wiki/Year#Symbols).
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:
* When you have data that mixes different systems
* When you want to transform years between different systems
* When you need to do arithmetic with years
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.
```{r setup, message=FALSE}
library("era")
library("tibble")
library("dplyr")
```
## Years with an era {#yr}
Vectors of years with an era are represented by the `yr` (`era_yr`) class, which is constructed with `yr()`:
```{r 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](#era).
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()`:
```{r yr-era-eg}
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:
```{r yr-era-get}
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:
```{r yr-era-set}
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_transform).
`yr` vectors fit nicely into tables, both base data frames and tibbles:
```{r eg-tbl}
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 definitions {#era}
era includes built-in definitions of many time scales and year numbering systems from contemporary and historic calendars.
`eras()` returns the [full list](#era-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:
```{r eg-use-era}
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](#defining-other-eras) with `era()`.
Suggestions for new eras to include in the package are also welcome; please [create an issue](https://github.com/joeroe/era/issues) on GitHub with suggestions.
### List of built-in eras {#era-list}
```{r era-table, echo=FALSE}
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)
```
### Defining other eras
Eras are defined by the `era` class with the following parameters:
* **label**: an abbreviated label that uniquely identifies the era
* **name**: the full name of the era
* **epoch**: the origin year from which years are counted (in Gregorian astronomical years)
* **unit**: the unit of years counted, defined as its length in solar days
* **scale**: the number of years represented by one unit
* **direction**: whether years are counted forwards (`1`) or backwards (`-1`) from the epoch
These 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:
```{r custom-era}
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()`.
## Converting between eras: `yr_transform()` {#yr_transform}
Use `yr_transform()` to convert between eras:
```{r transform}
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](#invalidtransform), you can transform between any two eras that can be described by the `era` class.
### Transformation precision
By default, era transformations are exact:
```{r yr-transform-precision1}
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:
```{r yr-transform-precision2}
yr(10000, "BP") |>
yr_transform(era("BCE"), precision = 1000)
yr(500000, "BCE") |>
yr_transform(era("mya"), precision = 0.1)
```
### Invalid transformations {#invalidtransform}
Some transformations are not possible.
Notably, the length of a 'radiocarbon year' is not well defined on a calendar time scale without [calibration](https://en.wikipedia.org/wiki/Radiocarbon_calibration).
Eras that use non-calendar year unit are represented with an `NA` and will cause an error if passed to `yr_transform()`:
```{r transform-unit, error=TRUE}
era_unit(era("uncal BP"))
yr_transform(yr(9000, "uncal BP"), era("cal BP"))
```
`c14_calibrate()` from the [stratigraphr](https://stratigraphr.joeroe.io) 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.
## Arithmetic with year vectors {#arithmetic}
The `yr` class is based on [vctrs](https://vctrs.r-lib.org/), ensuring type- and size-stable computations.
For example, you can do arithmetic with year vectors:
```{r yr-arith}
a <- yr(1500, "CE")
b <- yr(2020, "CE")
b - a
```
But only when they have the same era:
```{r yr-arith-error, error=TRUE}
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:
```{r era-equality}
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:
```{r yr-multiply}
a * b
```