Skip to content
Permalink
Branch: master
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
226 lines (166 sloc) 16.6 KB
---
title: "Getting Started"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{Introduction}
%\VignetteEngine{knitr::rmarkdown}
\usepackage[utf8]{inputenc}
---
# Overview
The [**isotopia**](http://isotopia.kopflab.org/) package provides several isotopic data types that can be initialized by calling the respective `ratio`, `abundance`, `delta`, `fractionation_factor` and `intensity` functions. Each data type has additional attributes (such as name of the minor and major isotopes, and what compound it represents, what the reference ratio is for delta values, and what notation is used), which are all described in great detail in the help functions of [**isotopia**](http://isotopia.kopflab.org/) that are accessible directly from R. Each data type can be initialized as a single vector of isotopic data or an entire system of isotope values for the same element (e.g. all oxygen or all sulfur isotopes). As all isotope data objects are implemented as extensions of primitive data types in R, they can be structured and aggregated in all the ways familiar to people with prior R experience, but should be intuitive enough to be useful "out of the box" for users new to this language. Isotope data types can then be converted from one type to another using `to_ratio`, `to_abundance`, `to_delta`, `to_fractionation_factor` methods, can be used in operations (`mass_balance`, `fractionate`, etc.) or transferred from one notation to another using `switch_notation`. Here, I provide a few examples how [**isotopia**](http://isotopia.kopflab.org/) works and how it can be used, with the complete documentation available in the reference manual. To look at the newest version of this tutorial directly within R, call the vignette `vignette("isotopia")`.
# Data types
After *isotopia* is [installed](http://isotopia.kopflab.org/), it can be loaded at any time like any other R package using `library(isotopia)`. The basic data types are initialized simply by calling the respective `ratio`, `abundance`, `delta` and `fractionation_factor` functions with single or multiple values.
```{r data-types}
library(isotopia)
show(ratio(0.1))
show(abundance(c(0.1, 0.2)))
show(delta(100, notation = "permil"))
show(fractionation_factor(seq(0.97, 1.03, by=0.01), notation = "alpha"))
show(intensity(100, unit = "mV"))
```
## Attributes
All data types have certain attributes that are stored with the data values. For example, an isotope ratio can specify what minor and major isotope it represents and what compound it belongs to.
```{r}
show(ratio(`13C` = 0.011, major = "12C", compound = "CO2"))
```
And a fractionation factor, for example, can additionally describe what the two reservoirs are between which it fractionates (introducing the shortcut ff instead of the identical long version fractionation_factor in the following).
```{r}
show(ff(`13C` = 0.995, major = "12C", ctop = "CO2", cbot = "DIC"))
```
All attributes can also be changed on an already initialized object using the set_attrib() function. However, changing previously defined attributes will always trigger a warning to alert the user to the fact that they are overwriting an attribute.
```{r}
r <- ratio(`18O` = 0.002, major = "16O", compound = "CO2")
r <- set_attrib(r, minor = "17O")
show(r)
```
There are also a large number of safeguards in place that trigger errors if non-sensical isotope values are initialized (for example a negative isotope ratio or alpha fractionation factor).
## Isotope systems
Entire isotope systems can be initialized in identical ways, by simply passing several separate values (or entire sequences of values) to the initialization functions (introducing the shortcut ab instead of the identical long version abundance in the following).
```{r}
show(ab(`33S` = 0.0075, `34S` = 0.0421, `36S` = 0.0002, major = "32S"))
```
# Notation
Closely related to the attributes system is the notation system implemented in [**isotopia**](https://github.com/sebkopf/isotopia). Notation is special because it is an attribute that, when changed, also changes the numerical value of an isotope object with it. All isotope value objects keep track internally what notation they are in, which allows them to be used correctly in any operations and conversions completely independent of what notation the user prefers to work in. Notation is first specified when an isotope value object is initialized and several different notations are implemented for the different isotope value objects. If not specified during intialization, [**isotopia**](https://github.com/sebkopf/isotopia) assumes tha an object is created with its default notation. A number of default settings can be specified and retrieved using ```set_iso_opts()``` and ```get_iso_opts()```. Here an example of checking and setting the default notation for fractionation factors (which can be either $\alpha$ values, raw $\epsilon=\alpha-1$ or $\epsilon$ values in permil notation), initializing a new object with default notation (i.e. without specifying `notation="x"` during initialization) and converting it back and forth.
```{r}
show(get_iso_opts("default_ff_notation"))
show(ff(1.02)) # alpha notation
set_iso_opts(default_ff_notation = "permil")
show(p <- ff(20)) # permil notation
show(switch_notation(p, "eps"))
show(switch_notation(p, "alpha"))
```
It is important to note that of course all of these values are equivalent, they are just representions of the same fractionation factor in different notation. Accordingly, they behave **exactly** the same in all calculations implemented by [**isotopia**](https://github.com/sebkopf/isotopia) regardless what notation they are in.
# Conversions
```{r}
i <- intensity(`32S` = 9502, `33S` = 75, `34S` = 421, `36S` = 2,
major = "32S", unit = "#")
show(i)
r <- to_ratio(i)
show(r)
ab <- to_abundance(r)
show(ab)
```
Because the system of intensities (here as ion counts #) had the major isotope attribute specified, the conversion ```to_ratio``` could automatically figure out what ratios to form. Without specifying which one is the major isotope, the intensities would have still initialized just fine but [**isotopia**](https://github.com/sebkopf/isotopia) would have thrown an error when trying to convert to isotope ratios. There's much more functionality in the conversions, which are all listed in the reference manual available directly within R by calling ```?isotopia``` or ```?to_ratio``` or any other function defined in the package.
## Delta values and reference standards
In the case of delta values, conversions often require the specification or use of a reference ratio. This can simply be done by specifying the reference ratio when converting to_delta and since [**isotopia**](https://github.com/sebkopf/isotopia) stores the reference ratio with the delta value object, it can be used automatically in the reverse calculation.
```{r}
r <- ratio(`13C` = 0.0115, major = "12C")
ref_r <- ratio(`13C` = 0.011237, major = "12C", compound = "VPDB")
d <- to_delta(r, ref_ratio = ref_r)
show(d)
show(to_ratio(d))
```
Additionally, [**isotopia**](https://github.com/sebkopf/isotopia) keeps a register of known reference materials with several default values already entered and the possibility for the user to add additional ones they want to use (with the ```register_standard()``` function). Standards can be retrieved as ratio objects by calling ```get_standard()``` and specifying which standard to retrieve for which isotope (see the manual in section A.2.8 for details). The list of all registered ratios can be retrieved as any other option with a call to ```get_iso_opts``` (here turned into a table with the k-table or ```kable``` command provided by the knitr package - Xie, 2013):
```{r, results='asis'}
library(knitr)
kable(get_iso_opts("standards"), format="markdown")
```
Registered standards provide [**isotopia**](https://github.com/sebkopf/isotopia) with the means to automatically select the correct reference ratio during conversions with delta objects that have sufficiently specific attributes (a message informs the user what was selected, if not enough information is provided to match exactly to one correct standard, this will fail with an error unless the user specifically provides a reference ratio for the conversion).
```{r}
d <- delta(`2H` = 100, major = "1H", ref = "VSMOW")
show(d)
show(to_ratio(d))
```
# Operations
With the conversions and data types all in place, [**isotopia**](https://github.com/sebkopf/isotopia) can easily expand its func- tionality by building on top of the data types. Currently, operations are limited to a number of key features, such as ```mass_balance()``` calculations for fractional abundances and delta values, as well as fractionating (```fractionate()```) isotope data objects with ```fractionation_factors``` and shifting the reference frame on delta values (```shift_reference()```). As always, attributes are carried through these operations in the most sensible way for what they actuallly represent.
## Mass balance
Mass balance makes use of an additional attribute not mentioned before, the weight attribute. This allows one to weight values according to their reservoir sizes such that during mass balance calculations, isotopically different pools are mixed according to their relative proportions. Weight can be specified either during initialization or by using the ```weight()``` function later on. Imagine a reservoir of CO2 that receives a tiny spike of heavily labeled additional carbon. For convenience, we're introducing here the [**isotopia**](https://github.com/sebkopf/isotopia) options to set the default minor and major isotope names - this is nice for working on a problem in a specific isotope system. Also, we're going to do the mass balance exact by converting to fractional abundances (although [**isotopia**](https://github.com/sebkopf/isotopia) provides the approximate ```mass_balance()``` directly with delta value objects as well).
```{r}
set_iso_opts(
default_minor = "13C",
default_major="12C",
default_ab_notation = "percent")
res <- delta(-10, compound = "CO2", ref = "VPDB", weight = 100)
show(res)
spike <- ab(seq(5, 25, by = 5), compound = "Cspike")
show(spike)
mb <- mass_balance(
to_ab(res), # convert reservoir to abundance
weight(spike, 0.1) #weight spike
)
show(mb)
```
Notice that the result of the mass balance again is a weighted isotope value object itself. It can be converted to other data types or you can keep adding additional components to it with mass balance calculations. In fact, since [**isotopia**](https://github.com/sebkopf/isotopia) keeps track of the weight, you can keep tagging multiple mass balances together (the ```mass_balance()``` function takes as many parameters as desired). Additionally, since R implements basic arithmetic operators as functions, [**isotopia**](https://github.com/sebkopf/isotopia) redefines adding (+) and subtracting (-) for abundance and delta objects to be interpreted as mass balance calculations. This means ```mass_balance(x, y)``` is the same as ```x + y``` for these isotope value objects. This allows short-hand calculations like the following (although ```mass_balance()``` is recommended in more complex situations for clarity of recording what is happening). Here, we are adding a heavy relatively small but heavy pool (40permil, weight=2) to a circumneutral reservoir (5permil, weight=10) and then remove an isotopically light fraction from the pool (-10permil, weight=4).
```{r}
mb <-
delta(5, weight = 10) +
delta(40, weight = 2) -
delta(-10, weight = 4)
show(mb)
```
## Fractionate
During fractionation, a fractionation factor modifies an isotope value object (for example an isotope ratio or a delta value).
```{r}
a <- ff(1.05, ctop = "DIC", cbot = "CO2", notation = "alpha")
r <- ratio(0.114, compound = "CO2")
r <- fractionate(a, r)
show(r)
```
Notice that [**isotopia**](https://github.com/sebkopf/isotopia) automatically keeps track of what compound is represented. Af- ter fractionation, the ratio represents no longer $CO[2]$ but $DIC$ according to the fractionation factors attributes. If these attributes do not "cancel" correctly, this command fails with an error and the relevant error message. Same as with ```mass_balance()```, [**isotopia**](https://github.com/sebkopf/isotopia) implements arithmetic shorthand for this, isotope value objects can be simply fractionationed by multiplying with a fractionation factor. I.e., ```fractionate(a, b)``` is the same as ```a * b``` (this also means fractionation factors can be easily chained with ```a1 * a2 * a3 * b``` but only if the "numerators" and "denominators" cancel properly).
```{r}
ff(-25, notation = "permil", ctop = "Corg", cbot = "DIC") *
ff(-5, notation = "permil", ctop = "DIC", cbot = "CO2") *
delta(100, compound = "CO2")
```
## Shift reference
The last operation to introduce for now is shifting a reference frame. This is only defined for ```delta``` values and requires the denominator and numerator to cancel (otherwise fails with an error). It is also implemente with the ```delta * delta``` arithmetic shorthand. This is a typical scenario useful for processing laboratory data which is measured against a standard of known isotopic composition relative to an international reference.
```{r}
sample <- delta(-5, compound = "sample", ref = "my_std")
standard <- delta(-2.5, compound = "my_std", ref = "VPDB")
show(shift_reference(sample, standard))
show(sample * standard)
```
## Arithmetic
Several of the arithmetic shorthands were introduced already, but there are several more (for all, see the manual). For all of these, it is always recommend to use the actual real functions in more complex scenarios for clarity. Here's just an example of what [**isotopia**](https://github.com/sebkopf/isotopia) can automatically keep track of in terms of isotope data objects. Here are two ways of turning isotope ratios into a fractionation factor in permil notation - it works booth by explicit mention of each functional step, or by the arithmetic equivalent.
```{r}
r1 <- ratio(0.011)
r2 <- ratio(0.0113)
p <- switch_notation(to_ff(r1, r2), "permil")
show(p)
p <- (r1/r2 - 1) * 1000
show(p)
```
# Testing
Testing of all functionality in [**isotopia**](https://github.com/sebkopf/isotopia) is implemented using the **testthat** package (Wickham, 2011; Wickham & Chan, 2014), which provides a simple and uniform way of writing tests that can be run automatically to report any incorrect behaviour immediately. This enables multiple developers to contribute to the core functionality of the project without the risk of breaking prior implementations, but also allows users to easily write a few tests of their own to be confident that the package is doing what it is supposed to be doing, or just to test their own code and formulas on a regular basis. Here are few examples from the many tests already implemented for [**isotopia**](https://github.com/sebkopf/isotopia) to give an idea of the range of functionality tests:
```{r}
library(testthat)
set_iso_opts(default_ab_notation = "raw",
default_delta_notation = "permil",
default_ff_notation = "alpha")
expect_error(ratio(-0.2), "cannot be negative")
expect_false(is.ratio(abundance(0.1)))
expect_equal(to_ff(delta(200), delta(-200)), ff(1.2 / 0.8))
expect_is({
amix <- abundance(`13C` = 0.2, weight = 2, compound = "a") +
abundance(`13C` = 0.5, compound = "b") +
abundance(`13C` = 0.3, weight = 3, compound = "c")}, "Abundance")
expect_equal(get_label(amix), "a+b+c F 13C")
expect_equal(get_value(amix), (0.2*2 + 0.5 + 0.3*3) / (2+1+3))
expect_equal(get_value(ff(0.8) * delta(200) + delta(100), "permil"), 1000*(0.8*1.2 - 1 + 0.1)/2)
```
# Future extensions
The [**isotopia**](https://github.com/sebkopf/isotopia) package currently implements a lot of the core functionality for isotope arithmetic. However, there is much that could built on top of it, including support for mass-scaling and mass-independent data objects and multiply subsituted isotopologues. The goal with all of these would be to provide an interface that can implement rigorous unit tests to ensure calculations are always performed the exact same way, tools to convert between reference frames and make it easier to compare and visualize data in different isotopic spaces, and, above all, to make it fun, intuitive and reproducible to work with isotopic data.
# References
- [Wickham, H., 2011. testthat: Get started with testing. The R Journal 3, 5-10.](http://journal.r-project.org/archive/2011-1/RJournal_2011-1_Wickham.pdf)
- [Wickham, H., Chang, W., 2014. devtools: Tools to make developing R code easier.](http://cran.r-project.org/package=devtools)
- [Xie, Y., 2013b. knitr: A general-purpose package for dynamic report generation in R.](http://cran.r-project.org/web/packages/knitr/index.html)
You can’t perform that action at this time.