# Introduction to the rice package

# 1 Introduction

Radiocarbon dating requires a range of calculations, for example calibration1234, translations between pMC, \(\text{F}^{14}\text{C}\), \(^{14}\text{C}\) age and \(\Delta^{14}\text{C}\), and assessing the impacts of contamination. This package provides functions to do so in R.

# 2 Installation

On first usage of the package, it has to be installed:

    install.packages('rice')

The companion data package ‘rintcal’ which has the radiocarbon calibration curves will be installed if it isn’t already. New versions of R packages appear regularly, so please re-issue the above command regularly to remain up-to-date, or use:

    update.packages()

To obtain access to the calibration curves and radiocarbon functions, first the package has to be loaded:

    library(rice)

    ## Loading required package: rintcal

# 3 Radiocarbon

C-14 or radiocarbon is a radioactive isotope that decays with a half-life of around 5730 years, and which is commonly used to date organic material back to around 50,000 years ago.

As cosmic rays interact with N-14, they produce C-14 at a global rate of around 6 kg C-14 per year. As can be seen in the first panel of the below Figure, if C-14 were stable and allowed to fill the atmosphere (as 14CO2) at that rate for 50,000 years, it’d reach 300,000 kg. However, since C-14 decays at a constant rate, over time an equilibrium would be reached between production and decay (top-right panel). Additionally, C-14 does not only accumulate in the atmosphere, but also diffuses into the ocean which is much larger than the atmosphere (bottom-left panel). 14C is usually expressed as the 14C/12C ratio (bottom-right). The dashed line is the atmospheric 14C/12C ratio in AD 1950 (since the ocean has lower 14C/12C ratios, its 14C ages are older).

    layout(matrix(1:4, ncol=2, byrow=TRUE))
    C14.cycle(as.ratio=FALSE, exchange=0, halflife=Inf) # top-left panel
    C14.cycle(as.ratio=FALSE, exchange=0) # top-right
    C14.cycle(as.ratio=FALSE) # bottom-left
    C14.cycle() # bottom-right

Given a starting concentration \(A_0\) of some organic material that we want to find the age of, the remaining amount of radiocarbon at time \(t\) can be found as \(A_t = A_0 e^{-\lambda t}\):

    howmuchC14(0)

    ## 1 mg carbon contains 5.02e+19 C atoms

    ## 14C atoms remaining at 0 cal BP (F=0.976): 5.76e+07

    ## 19.1 14C atoms in the sample will decay each day

    ## For a 12C current of 25 micro-ampere (1.56e+14 12C/second) at the AMS detector,
    ##   179.03 14C particles would be counted per second (10741.8 per minute)

    howmuchC14(55e3)

    ## 1 mg carbon contains 5.02e+19 C atoms

    ## 14C atoms remaining at 55000 cal BP (F=0.002): 1.15e+05

    ## 0.0382 14C atoms in the sample will decay each day

    ## For a 12C current of 25 micro-ampere (1.56e+14 12C/second) at the AMS detector,
    ##   0.359 14C particles would be counted per second (21.54 per minute)

    x <- seq(0, 55e3, length=100) # a sequence of ages
    y <- sapply(x, function(x) howmuchC14(x, talk=FALSE)[1])
    plot(x, y, type="l", xlab="time (cal BP)", ylab="C-14 remaining")

Younger samples will have more C-14 atoms left than older ones, and thus will get higher counts-per-second at the AMS’s C-14 detector. Want to hear a ‘sonification’ of the counts-per-second of C-14 atoms? The frequency of the tone relates to the counts per second, and the clicks represent the particles crashing into the detector. A visualisation of the counts as well as how they translate into a C-14 age is also provided. (This requires the ‘audio’ R package to be installed; if it isn’t, a notification will be displayed with installation instructions.)

    radio(30000)

The radiocarbon dating of material of a certain calendar age (e.g., 9000 cal BP) can be simulated quickly and cheaply as:

    sim.date(9000, 10) # 10 dates

    ##     age er
    ## 1  8135 44
    ## 2  8010 44
    ## 3  8015 44
    ## 4  8096 44
    ## 5  8043 44
    ## 6  8111 44
    ## 7  8081 44
    ## 8  8009 44
    ## 9  7938 44
    ## 10 8052 44

Radiocarbon laboratories correct their measurements for fractionation (to -25 ‰ by default) and for background measurements before they are reported. These calculations can be seen here:

    adjust.fractionation(9000, -17) # the sample's d13C was measured at -17

    ## [1] 9131.286

    adjust.background(9000, 50, 48000, 200) # a well-oiled machine, with backgrounds of F=0.00254

    ##        C14   C14.er
    ## 1 9042.384 50.73721

# 4 Calibration curves

C-14 ages are not exactly similar to calendar ages, owing to past fluctuations in atmospheric C-14 concentrations. We need calibration curves to correct for these fluctuations. The calibration curves can be plotted (we’re adding a 1:1 line to see how C14 ages deviate from calendar ages over time):

    draw.ccurve()
    grid()
    abline(0, 1, lty=2)

Or, comparing two calibration curves, on the BC/AD scale:

    draw.ccurve(1000, 2020, BCAD=TRUE, cc2='marine20', add.yaxis=TRUE)

Or zooming in to between AD 1600 and 2000:

    draw.ccurve(1600, 1950, BCAD=TRUE)

Note the wiggles, or recurring C-14 ages? Calibration curves such as IntCal20 come with 3 columns: cal BP (\(\theta\)), the corresponding C-14 ages (\(\mu\)), and their errors (\(\sigma\)). Whereas each cal BP or BC/AD year has a single \(\mu\) and \(\sigma\), owing to wiggles in the calibration curves, any single \(\mu\) will often have multiple \(\theta\)’s:

    BCADtoC14(1694) # gives 129 +- 9 14C BP

    ##   C14 er
    ## 1 129  9

    C14toBCAD(129) # the curve crosses 129 14C BP 5 times

    ## [1] 1917.000 1876.500 1873.022 1810.667 1725.500 1693.995

Let’s add these values to the previous plot:

    draw.ccurve(1600, 1950, BCAD=TRUE)
    abline(h=BCADtoC14(1694), lty=3)
    abline(v=C14toBCAD(129), lty=3)

Atmospheric nuclear tests around AD 1950-1964 caused a huge human-made C-14 peak (resulting in highly negative C-14 ages):

    draw.ccurve(1600, 2020, BCAD=TRUE, cc2='nh1')

Since the postbomb curve dwarfs the IntCal20 curve, we could also plot both on separate vertical axes:

    draw.ccurve(1600, 2020, BCAD=TRUE, cc2='nh1', add.yaxis=TRUE)

The calibration curves can also be plotted in the timescales of F14C, pMC or \(\Delta{14}\text{C}\) (see below), e.g.:

    draw.ccurve(50000, 35000, timescale="D")

Some older calibration curves are also available for historical interest, e.g.:

    draw.ccurve(cc1="stuiver_suess_1966", cc2="pearson_stuiver_1986")

# 5 Timescales

This package provides functions to translate values between the radiocarbon-relevant timescales of cal BP (calendar years before AD 1950), BC/AD (here we mean cal BC/AD, but shorten this to BC/AD), b2k (years before AD 2000, popular in the ice core community), C14, \(\text{F} ^{14} \text{C}\), pMC and \(\Delta ^{14} \text{C}\). The following Table lists the available functions:

from\to | calBP | BCAD | b2k | C14 | F14C | pMC | Delta14C
--- | --- | --- | --- | --- | --- | --- | ---
calBP | - | `calBPtoBCAD` | `calBPtob2k` | `calBPtoC14` | `calBPtoF14C` | `calBPtopMC` | `calBPtoDelta14C`
BCAD | `BCADtocalBP` | - | `BCADtob2k` | `BCADtoC14` | `BCADtoF14C` | `BCADtopMC` | `BCADtoDelta14C`
b2k | `b2ktocalBP` | `b2ktoBCAD` | - | `b2ktoC14` | `b2ktoF14C` | `b2ktopMC` | `b2ktoDelta14C`
C14 | `C14tocalBP` | `C14toBCAD` | `C14tob2k` | - | `C14toF14C` | `C14topMC` | `C14toDelta14C`
F14C | NA | NA | NA | `F14CtoC14` | - | `F14CtopMC` | `F14CtoDelta14C`
pMC | NA | NA | NA | `pMCtoC14` | `pMCtoF14C` | - | `pMCtoDelta14C`
Delta14C | NA | NA | NA | `Delta14CtoC14` | `Delta14CtoF14C` | `Delta14CtopMC` | -

As an example of the above functions, the IntCal20 C14 age and error belonging to one or more cal BP or cal BCAD ages can be found (interpolating linearly where necessary):

    calBPtoC14(10.5)

    ##   C14 er
    ## 1 168 11

    BCADtoC14(1940:1950)

    ##    C14 er
    ## 1  170 11
    ## 2  174 11
    ## 3  178 11
    ## 4  181 11
    ## 5  185 11
    ## 6  188 11
    ## 7  190 11
    ## 8  193 11
    ## 9  195 11
    ## 10 197 11
    ## 11 199 11

To translate between cal BC/AD and cal BP ages, we can use (the last example avoids 0 BC/AD, since some calendars do not include zero):

    BCADtocalBP(2025)

    ## [1] -75

    BCADtocalBP(-1, zero=TRUE)

    ## [1] 1951

    BCADtocalBP(-1, zero=FALSE)

    ## [1] 1950

Delta14C (\(\Delta\)14C, a proxy for atmospheric 14C concentration at t cal BP) can be transferred to F14C, and the other way around:

    Delta14CtoF14C(152, t=4000)

    ##        F14C
    ## 1 0.7100834

    F14CtoDelta14C(0.71, t=4000)

    ##   Delta14C
    ## 1 151.8647

This can also be done with C14 ages:

    C14toDelta14C(152, t=4000)

    ##   Delta14C
    ## 1 591.9353

    Delta14CtoC14(592, t=4000)

    ## [1] 151.6734

Although ages are most often expressed as 14C BP, radiocarbon labs calculate these ages from the measured F14C values. Since 14C BP = -8033 * ln(F), the distributions of especially older 14C ages and those with large errors become skewed, sometimes with their tails extending into infinite ages:

    draw.CF(50000, 3000)

Here’s a function to transform values between multiple timescales and visualise them:

    fromto(100, "calBP")

    ## 100 cal BP equals 1850 cal BC/AD, 124 14C BP, 0.98 F14C, 98.47 pMC, -3.33 Delta14C (cc=1)

These functions can be used to investigate \(\Delta^{14}\text{C}\) over time:

    x <- seq(0, 55e3, length=1e3)
    cc <- calBPtoC14(x)
    Dcc <- C14toDelta14C(cc[,1], cc[,2], x)

    par(mar=c(4,3,1,3), bty="l")
    plot(x/1e3, Dcc[,1]+Dcc[,2], type="l", xlab="kcal BP", ylab="")
    mtext(expression(paste(Delta, ""^{14}, "C")), 2, 1.7)
    lines(x/1e3, Dcc[,1]-Dcc[,2])

We can also use draw.ccurve to plot the IntCal20 curve as both C-14 years and \(\Delta^{14}\text{C}\):

    draw.ccurve(cc2="IntCal20", timescale2="D", add.yaxis=TRUE)

# 6 Pooling dates

Sometimes, the same material is measured using multiple radiocarbon dates. If we can be sure that the dated material stems from one single age in time (e.g., multiple dates on the same single bone, or perhaps the cereal grains within one bowl which could be assumed to all stem from the same season), then we can check to which degree the dates agree using a Chi2-test (Ward & Wilson 1978)5. If they do agree, then a pooled mean can be calculated. For example, take the Shroud of Turin, which was dated multiple times in three different labs:

    data(shroud)
    shroud

    ##            ID   y er
    ## 1   AA-3367.1 591 30
    ## 2   AA-3367.2 690 35
    ## 3   AA-3367.3 606 41
    ## 4   AA-3367.4 701 33
    ## 5   Ox-2575.1 795 65
    ## 6   Ox-2575.2 730 45
    ## 7   Ox-2575.3 745 55
    ## 8  ETH-3883.1 733 61
    ## 9  ETH-3883.2 722 56
    ## 10 ETH-3883.3 635 57
    ## 11 ETH-3883.4 639 45
    ## 12 ETH-3883.5 679 51

Let’s check if we can pool the dates:

    pool(shroud$y,shroud$er)

    ## ! Scatter too large to calculate the pooled mean
    ## Chisq value: 20.697, p-value 0.037 < 0.05

    Zu <- grep("ETH", shroud$ID) # Zurich lab only
    pool(shroud$y[Zu],shroud$er[Zu])

    ## pooled mean: 676.1 +- 23.7
    ## Chi2: 2.745, p-value 0.601 (>0.05, OK)

    ## [1] 676.1406  23.7443

Then the weighted mean can be calculated, with the error taken as the largest of the weighted uncertainty and the standard deviation:

    weighted_means(shroud$y[Zu],shroud$er[Zu])

    ## wmean 676.1, error is max of weighted uncertainty (23.7) & sdev (44.3): 44.3

    ## [1] 676.1  44.3

If it can indeed be safely assumed that all dates stem from the same (unknown) calendar year, then the age distribution of that single year can be plotted together with the individual calibrated ages:

    as.one(shroud$y,shroud$er)

    ## point estimates (mean, median, mode and midpoint): 629, 652, 653 & 619 cal BP

    ## 95% hpd ranges: 583-570 (31.4%), 667-647 (63.5%)

It would however often be much safer to assume that the multiple dates were deposited over not just one calendar year but rather over a period, e.g., over 50 years. To do so, a moving bin is made, and for each bin placement it is checked how much of the calibrated distribution of each date fits within that bin. Here is an example, using a bin width of 100 years, moving at 25 year steps (the top value indicates that around 660 cal BP, a total of around 4-5 dates fit within the 100-year bin):

    as.bin(shroud$y,shroud$er, 100, move.by=25)

    ## point estimates (mean, median, mode and midpoint): 642, 628, 625 & 637 cal BP

    ## 95% hpd ranges: 757-516 (95%)

The spread of multiple calibrated dates can be visualised and summarised:

    spread(shroud$y,shroud$er)

    ## average spread: 65.8 calendar years (median 56.6)
    ## 95% range: 2.3 to 187.9

The time-span between two dates can be calculated (by sampling n pairs of random ages from both calibrated distributions and plotting the time-span for each pair):

    span(700, 20, 750, 20)

    ## average span: 32.5 calendar years (median 19.1)
    ## 95% range: 2.5 to 113.2

We can assess to what degree two calibrated distributions are overlapping (as the minimum calibrated height for each calendar year in a range). For example, imagine two dates from the same archaeological layer, a twig (3820 ± 40 C-14 BP, requiring calibration with IntCal20) and a marine shell (4430 ± 40 C-14 BP, requiring Marine20, with a regional marine offset of 90 ± 25). By what percentage do the two calibrated distributions overlap?

    y <- c(3820, 4430+90)
    er <- c(40, sqrt(40^2 + 25^2))
    cc <- c(1,2)
    overlap(y, er, cc=cc)

    ## overlap: 10.8%

The calibrated ranges of radiocarbon dates can also be displayed in a table (either on a webbrowser or as Word document):

    data(shroud)
    calibratable(shroud$y, shroud$er, shroud$ID, BCAD=TRUE)

Lab ID | 14C BP (± sd) | 95% range (cal BC/AD) | 95% hpd ranges (cal BC/AD)
--- | --- | --- | ---
AA-3367.1 | 591 ± 30 | 1305 – 1408 | 1302 – 1368 (69.2%) 1380 – 1410 (25.8%)
AA-3367.2 | 690 ± 35 | 1272 – 1386 | 1270 – 1321 (62.8%) 1358 – 1390 (32.2%)
AA-3367.3 | 606 ± 41 | 1295 – 1410 | 1295 – 1410 (95%)
AA-3367.4 | 701 ± 33 | 1267 – 1383 | 1267 – 1317 (71%) 1360 – 1388 (24%)
Ox-2575.1 | 795 ± 65 | 1059 – 1323 | 1047 – 1083 (5.1%) 1095 – 1102 (0.5%) 1125 – 1140 (1.2%) 1148 – 1303 (86.8%) 1367 – 1380 (1.4%)
Ox-2575.2 | 730 ± 45 | 1223 – 1380 | 1220 – 1310 (83.3%) 1361 – 1387 (11.7%)
Ox-2575.3 | 745 ± 55 | 1182 – 1379 | 1178 – 1192 (2%) 1202 – 1320 (83.8%) 1359 – 1389 (9.2%)
ETH-3883.1 | 733 ± 61 | 1181 – 1385 | 1177 – 1193 (2%) 1201 – 1326 (77.1%) 1352 – 1394 (15.8%)
ETH-3883.2 | 722 ± 56 | 1212 – 1386 | 1216 – 1326 (74.9%) 1348 – 1395 (20.1%)
ETH-3883.3 | 635 ± 57 | 1279 – 1410 | 1278 – 1408 (95%)
ETH-3883.4 | 639 ± 45 | 1283 – 1400 | 1282 – 1398 (95%)
ETH-3883.5 | 679 ± 51 | 1252 – 1393 | 1265 – 1398 (95%)
Calibration curve: IntCal20 (Reimer et al. 2020)

# 7 Contamination

To calculate the effect of contamination on radiocarbon ages, e.g. what age would be observed if material with a “true” radiocarbon age of 5000 ± 20 14C BP would be contaminated with 10% of modern carbon (F14C=1)?

    contaminate(5000, 20, 10, F.contam=1)

    ## True age in F14C: 0.53664 +- 0.00134

    ## Observed F14C: (0.9*0.53664) + (0.1*1) = 0.58298 +- 0.00121

    ## Observed C14 age: 4334.6 +- 16.6

Or imagine that you measured a dinosaur bone, dating to far beyond the limit of radiocarbon dating, and the sample is very clean as it contains only 0.5% ± 0.1% modern contamination:

    contaminate(66e6, 1e6, 0.5, 0.1, 1)

    ## True age in F14C: 0 +- 0

    ## Observed F14C: (0.995*0) + (0.005*1) = 0.005 +- 0.00101

    ## Observed C14 age: 42726.7 +- 1639.7

The other way round, e.g., inferring what would happen to an observed age if its assumed 10% modern contamination were to be removed:

    clean(9000, 100, 10)

    ## Observed age as F14C: 0.32616 +- 0.00409

    ## True F14C: (0.9*0.32616) - (0.1*1) = 0.25123 +- 0.00455

    ## True C14 age: 11098 +- 145.7

We can also calculate the amount of contamination, or muck, required to ‘explain away’ certain ages. For example, one of the measurements of the Shroud of Turin dates to 591 ± 30 C14 BP. How much modern contamination would have to be inferred for the material to really date to, say, AD 40?

    muck(591, 30, BCADtoC14(40)[,1], 0, 1)

    ## Observed age: 591 +- 30 C14 BP (0.929+-0.003 F14C)

    ## Target age: 1970 C14 BP (0.783 F14C)

    ## Calculation: (0.929-0.783)/(1 - 0.783) = 0.67383

    ## Contamination required: 67.4+-1.6%

So we’d require the sample to have been contaminated by 67% modern carbon to still date to around AD 40. But what if the sample had been repaired in, say, the AD 1532 fire, thus adding material of an not-entirely-modern F14C value (i.e., taking into account both the atmospheric C-14 concentrations in AD 1532 and the fact that some of the C14 will have decayed since then)?

    perFaith <- BCADtoC14(40)
    repairF <- BCADtoF14C(1532)
    muck(591, 30, perFaith[,1], perFaith[,2], repairF[,1], repairF[,2])

    ## Observed age: 591 +- 30 C14 BP (0.929+-0.003 F14C)

    ## Target age: 1970 C14 BP (0.783 F14C)

    ## Calculation: (0.929-0.783)/(0.963 - 0.783) = 0.80984

    ## Contamination required: 81+-2%

This means that the dated sample would have to consist almost entirely of Medieval age material - which is exactly what was found by Damon et al. (1989)6.

What if we had a sample with a known percentage of contamination, and wanted to know the required activity (F14C) of said contamination to explain away a date? This can be done by providing the percentage contamination (e.g., 10%):

    muck(500, 20, 600, 25, perc.contam=10)

    ## Observed age: 500 +- 20 C14 BP (0.94+-0.002 F14C)

    ## Target age: 600 C14 BP (0.928 F14C)

    ## Calculation: 0.928 + ((0.94-0.928) / 0.1) = 1.044

    ## F of contamination: 1.044 +- 0.035

The effect of different levels of contamination can be visualised:

    real.14C <- seq(0, 50e3, length=200)
    contam <- seq(0, 10, length=101) # 0 to 10% contamination
    contam.col <- rainbow(length(contam))
    plot(0, type="n", xlim=c(0, 55e3), xlab="real 14C age", ylim=range(real.14C), ylab="observed 14C age")
    for (i in 1:length(contam)) {
      observed <- contaminate(real.14C, 0, contam[i], 0, 1, talk=FALSE, MC=FALSE)
      lines(real.14C, observed[,1], col = contam.col[i])
    }

If that is too much code for you, try this function instead:

    draw.contamination()

# 8 Fractions

Sometimes, one needs to estimate a missing radiocarbon age from a sample which has C14 dates on both the entire sample and on fractions, but where one of the samples was too small to be dated. This can be used in for example soils separated into size fractions, or samples dated using both bulk and humic/humin fractions, where one of the samples turns out to be too small to be dated. This equation requires the bulk age, the ages of the dated fractions, and the carbon contents and weights of all fractions.

    Cs <- c(.02, .05, .03, .04) # carbon contents of each fraction
    wghts <- c(5, 4, 2, .5) # weights for all fractions, e.g., in mg
    ages <- c(130, 130, 130, NA) # ages of all fractions. The unmeasured one is NA
    errors <- c(10, 12, 10, NA) # errors, unmeasured is NA
    fractions(150, 20, Cs, wghts, ages, errors) # assuming a bulk age of 150 +- 20 C14 BP

    ## estimated C14 age of fraction 4: 518.8 +- 436.7

The above function can also be used to find the expected age of an entire sample, given the fractions and their ages - please type `?fractions` for more detail.

# 9 Calibration

Now on to calibration of radiocarbon dates. We can obtain the calibrated probability distributions from radiocarbon dates, e.g., one of 130 ± 10 C14 BP:

    calib.130 <- caldist(130, 10, BCAD=TRUE)
    plot(calib.130, type="l")

It is also possible to find the likelihood of a single calendar year for our radiocarbon age, e.g., 145 cal BP:

    l.calib(145, 130, 10)

    ## [1] 0.0052052

To sample n=100 random values from a calibrated distribution (where the probability of a year being sampled is proportional to its calibrated height):

    dice <- r.calib(100, 130, 10)
    plot(density(dice))
    rug(dice)

For reporting purposes, calibrated dates are often reduced to their 95% highest posterior density (hpd) ranges (please report all, not just your favourite one!):

    hpd(calib.130)

    ##   from   to perc
    ## 1 1710 1684 13.0
    ## 2 1733 1719  8.1
    ## 3 1758 1758  0.1
    ## 4 1824 1803  8.3
    ## 5 1892 1832 50.8
    ## 6 1928 1905 14.8

Additionally, calibrated dates are often reduced to single point estimates. Note however how poor representations they are of the entire calibrated distribution!

    calib.2450 <- caldist(2450, 20)
    plot(calib.2450, type="l")
    points.2450 <- point.estimates(calib.2450)
    points.2450

    ## weighted mean        median          mode      midpoint
    ##        2540.0        2512.5        2666.0        2531.5

    abline(v=points.2450, col=1:4, lty=2)

Want a plot of the radiocarbon and calibrated distributions, together with their hpd ranges?

    calibrate(2450, 40)

Sometimes one would want to smooth a calibration curve to take into account the fact that material has accumulated over a certain time (e.g., a tree, or peat). To do so, a calibration curve can be smoothed to produce a tailor-made calibration curve, after which this one is used to calibrate the date:

    mycurve <- smooth.ccurve(smooth=50)
    calibrate(2450, 40, thiscurve=mycurve)

Calibrating ‘young’ radiocarbon dates (close to 0 C14 BP) can cause an error, because a bomb curve might be required to capture the youngest ages. Do not worry, there is an option to avoid that error:

    try(calibrate(130,30))

    ## Error in build.curve(y = age, er = error, cc = cc, thiscurve = thiscurve,  :
    ##   please provide a postbomb curve

    calibrate(130, 30, bombalert=FALSE)

It is also possible to analyse the calibrated probability distributions, e.g. what is the probability (between 0 and 1) that the date stems from material that is of the age of 150 cal BP or younger? Or that it is older than that age?

    younger(150, 130, 10)

    ## [1] 0.7667408

    older(150, 130, 10)

    ## [1] 0.2332592

Or if you wish to calculate the probability covered between two age points (e.g., here between 300 and 150 cal BP):

    p.range(300, 150, 130, 10)

    ## [1] 0.2332592

The probabilities reported by `p.range` should be similar to those reported by the `hpd` function mentioned earlier. Any discrepancies can be explained by rounding errors in the calculations (e.g., hpd’s settings of `every`, `age.round` and `prob.round`).

At times there could be a lag in the date, for example if material has accumulated over decades. We can calibrate a date and then add a lag, by adding or subtracting either a normal distribution or a gamma one:

    push.normal(2450,40, 400,20)

    ##   from   to perc
    ## 1 3110 2758   95

# 10 Marine offsets

Dates on marine material will often have to be calibrated with the Marine20 calibration curve7, and many coastal locations will have an additional regional reservoir offset (deltaR) (Reimer and Reimer 2006)8. The on-line database at http://calib.org/marine/ is very useful for this; it features the radiocarbon ages and deltaR of many shells of known collection date. The data from this database were downloaded (in August 2024) and can be queried. For example, a map can be drawn with all shell data within certain coordinates:

    myshells <- map.shells(S=54, W=-8, N=61, E=0) # the northern part of the UK

If you don’t have the R package ‘rnaturalearth’ installed, you will be asked to install it if possible, because the resulting maps will look much nicer. Same for the github package ‘rnaturalearthhires’, which produces more detailed maps.

The output can also be queried:

    head(myshells)
    shells.mean(myshells)

    ##       lon   lat  no taxonN   dR dSTD collected res res.error C14 er       lab
    ## 428 -3.15 55.97 524    146 -141   57      1851 386        58 511 57  SRR-1818
    ## 431 -5.00 54.17 527    125 -180   47      1890 334        47 444 47 SRR-1821a
    ## 432 -5.00 54.17 528    125 -129   63      1890 385        64 495 63 SRR-1821b
    ## 433 -6.00 55.83 529     48 -224   46      1890 290        46 400 46 SRR-1822a
    ## 434 -6.00 55.83 530     48 -233   52      1890 281        52 391 52 SRR-1822b
    ## 435 -5.33 57.83 531     90 -171   29      1900 346        30 442 29  SRR-357a
    ##                                                                                                                                                                                                                                                         ref
    ## 428 Harkness, D D,, 1983. The extent of the natural 14C deficiency in the coastal environment of the United Kingdom,. Journal of the European Study Group on Physical, Chemical and Mathematical Techniques Applied to Archaeology PACT 8 (IV.9):351-364.
    ## 431 Harkness, D D,, 1983. The extent of the natural 14C deficiency in the coastal environment of the United Kingdom,. Journal of the European Study Group on Physical, Chemical and Mathematical Techniques Applied to Archaeology PACT 8 (IV.9):351-364.
    ## 432 Harkness, D D,, 1983. The extent of the natural 14C deficiency in the coastal environment of the United Kingdom,. Journal of the European Study Group on Physical, Chemical and Mathematical Techniques Applied to Archaeology PACT 8 (IV.9):351-364.
    ## 433 Harkness, D D,, 1983. The extent of the natural 14C deficiency in the coastal environment of the United Kingdom,. Journal of the European Study Group on Physical, Chemical and Mathematical Techniques Applied to Archaeology PACT 8 (IV.9):351-364.
    ## 434 Harkness, D D,, 1983. The extent of the natural 14C deficiency in the coastal environment of the United Kingdom,. Journal of the European Study Group on Physical, Chemical and Mathematical Techniques Applied to Archaeology PACT 8 (IV.9):351-364.
    ## 435 Harkness, D D,, 1983. The extent of the natural 14C deficiency in the coastal environment of the United Kingdom,. Journal of the European Study Group on Physical, Chemical and Mathematical Techniques Applied to Archaeology PACT 8 (IV.9):351-364.
    ##                 taxon    feeding
    ## 428 Modiolus modiolus suspension
    ## 431   Littorina rudis    deposit
    ## 432   Littorina rudis    deposit
    ## 433  Chamelea gallina suspension
    ## 434  Chamelea gallina suspension
    ## 435   Dosinia exoleta suspension

    ## wmean -143.4, error is max of weighted uncertainty (5.3) & sdev (58.3): 58.3

    ## [1] -143.4   58.3

You can also extract say the 20 shells closest to a coordinate, e.g., 20 East and 30 South:

    myshells <- find.shells(20, -30, 20)
    shells.mean(myshells, distance=TRUE)

    ## wmean 5.1, error is max of weighted uncertainty (5.6) & sdev (49.5): 49.5

    ## [1]  5.1 49.5

Instead of a static map, for `find.shells` and `map.shells` you can also request an interactive, browsable map, which will open in your Internet browser:

    find.shells(120, 10, 50, browse=TRUE)

# 11 More maps

The `p3k14c` R package9 contains over 175,000 radiocarbon dates (!) and is available on github10 (at c. 25 MB it’s too big for CRAN). Within `rice`, the data from `p13k14c` can be downloaded, plotted and browsed as follows:

    p3k14c <- map.dates()

For another “database of databases”, have a look at c14bazAAR11 which is also on github (and too big for CRAN). After installing that package from github, type `c14bazAAR::db_info_table` to see a table of available databases.

# 12 Multiple calibrations

It is also possible to draw multiple calibrated distributions:

    set.seed(123)
    dates <- sort(sample(500:2500,5))
    errors <- .05*dates
    depths <- 1:length(dates)
    my.labels <- c("my", "very", "own", "simulated", "dates")
    draw.dates(dates, errors, depths, BCAD=TRUE, labels=my.labels, age.lim=c(0, 1800))

or add them to an existing plot:

    plot(250*1:5, 5:1, xlim=c(0, 1800), ylim=c(5,0), xlab="AD", ylab="dates")
    draw.dates(dates, errors, depths, BCAD=TRUE, add=TRUE, labels=my.labels, mirror=FALSE)

or get creative (inspired by Jocelyn Bell Burnell12, Joy Division13 and the Hallstatt Plateau14):

    n <- 50; set.seed(42) # number of dates; always the same answer
    from <- 2200; to <- 2900 # calendar age limits
    y <- rnorm(n, 2620, 30) - 6*(1:n) # going through the Hallstatt Plateau

    # set up an empty plot with black background
    par(bg="black", mar=rep(1,4))
    plot(0, type="n", xlim=c(to, from), ylim=c(n,-2), xlab="", ylab="")

    for(i in 1:n) { # for each date...
      tmp <- draw.dates(y[i], 20, i, add=TRUE,
        mirror=FALSE, draw.hpd=FALSE, col="black", border=NA,
        peak=4, as.unit=TRUE) # distributions in black
      outline <- approx(tmp$ages, tmp$prob, seq(from, to, length=500), rule=2)
      y0 <- rnorm(500, i, 0.05) # make some noise
      lines(outline$x, y0-4*outline$y, col="white")
    }

1. Stuiver, R., Polach, H.A., 1977. Discussion: reporting of 14C data. Radiocarbon 19, 355-363 http://dx.doi.org/10.1017/S0033822200003672↩︎

2. Reimer, P.J., Brown, T.A., Reimer, R.W., 2004. Discussion: reporting and calibration of post-bomb 14C Data. Radiocarbon 46, 1299-1304 http://dx.doi.org/10.1017/S0033822200033154↩︎

3. Millard, R., 2014. Conventions for reporting radiocarbon determinations. Radiocarbon 56, 555-559 http://dx.doi.org/10.2458/56.17455↩︎

4. Reimer, P.J., et al., 2020. The IntCal20 Northern Hemisphere radiocarbon age calibration curve (0-55 cal kBP). Radiocarbon 62, 725-757 http://dx.doi.org/10.1017/S0033822200032999↩︎

5. Ward, G.K., Wilson, S., 1978. Procedures for comparing and combining radiocarbon age determinations: A critique. Archaeometry 20, 19-31 http://dx.doi.org/10.1111/j.1475-4754.1978.tb00208.x↩︎

6. Damon, P., et al., 1989. Radiocarbon dating of the Shroud of Turin. Nature 337, 611–615. https://doi.org/10.1038/337611a0↩︎

7. Heaton, T.J., et al., 2020. Marine20-the marine radiocarbon age calibration curve (0-55,000 cal BP). Radiocarbon 62, 779-820 http://dx.doi.org/10.1017/RDC.2020.68↩︎

8. Reimer, P.J., Reimer, R.W., 2006. A marine reservoir correction database and on-line interface. Radiocarbon 43, 461-463. http://dx.doi.org/10.1017/S0033822200038339↩︎

9. Bird, D., Miranda, L., Vander Linden, M. et al., 2022. p3k14c, a synthetic global database of archaeological radiocarbon dates. Scientific Data 9, 27. https://doi.org/10.1038/s41597-022-01118-7↩︎

10. https://github.com/people3k/p3k14c↩︎

11. https://github.com/ropensci/c14bazAAR↩︎

12. https://www.cam.ac.uk/stories/journeysofdiscovery-pulsars↩︎

13. https://www.radiox.co.uk/artists/joy-division/unknown-pleasures-album-cover-meaning/↩︎

14. https://en.wikipedia.org/wiki/Hallstatt_plateau↩︎