The goal of casper is to provide a spectra class for R that exposes a standard interface and create a patafrom that allows other R packages to build on. The package will provide basic IO, plotting and conversion functionality, but that is about it. casper is implemented with ease of use in mind, but it should not slow you down.

Installing and loading casper

The best way to get casper is to install it directly from the github repository. You will need the devtools package to do it.

library("devtools")
install_github("meireles/casper")

Assuming that everything went smoothly, you should be able to load casper like any other package.

library("casper")

Reading spectra and creating a spectra object

First, explore the example dataset spec_matrix_example

casper comes with limited IO capabilities. To illustrate how to create a spectra object, we will use an example dataset called spec_matrix_example. Samples are in rows, and wavelengths in columns, and the first column is the sample name (in this case, a species name). The column names match wavelength labels. I tried to format spec_matrix_example as a typical spectral dataset in csv format.

# Example spectral dataset in matrix format.
spec_matrix_example[1:4, 1:3]

# Note that this is NOT a spectra object. You can verify this by either asking what class `spec_example` is or using casper's `is_spectra()` function.

class(spec_matrix_example)
is_spectra(spec_matrix_example)

Constructing a spectra object

The spectra class holds the essential information used in spectral dataset: reflectance, wavelengths, etc. The class has a bunch of requirements in terms of both format and values. For instance, relative reflectance must be between 0 and 1.

If your data is in a matrix with the same format as spec_matrix_example (check previous section for details), you can construct a spectra object by calling the as.spectra() function.

# Make a spectra object if you have a matrix in the right format
spec = casper::as.spectra(spec_matrix_example)

# Did it work?
is_spectra(spec)

Alternativelly, you can create a spectra object using the more flexible spectra() constructor, which takes three arguments: (1) a reflectance matrix, (2) a vector of wavelengths and (3) the sample names.

# (1) Create a reflectance matrix.
#     In this case, by removing the species column
rf = spec_matrix_example[ , -1 ]

# Check the result
rf[1:4, 1:3]

# (2) Create a vector with wavelength labels that match
#     the reflectance matrix columns.
wl = colnames(rf)

# Check the result
wl[1:4]

# (3) Create a vector with sample labels that match
#     the reflectance matrix rows.
#     In this case, use the first colum of spec_matrix_example
sn = spec_matrix_example[ , 1] 

# Check the result
sn[1:4]

# Finally, construct the spectra object using the `spectra` constructor
spec = spectra(reflectance = rf, wavelengths = wl, names = sn)

# And hopefully this worked fine
is_spectra(spec)

Converting a spectra object into a matrix

It is possible to convert a spectra object to a matrix format, using the as.matrix() function. casper will (1) place wavelengths in columns, assigning wavelength labels to colnames, and (2) samples in rows, assigning sample names to rownames. Since R imposes strict on column name formats and sometimes on row names, as.matrix() will try to fix potential dimname issues if fix_names != "none".

# Make a matrix from a `spectra` object
spec_as_mat = as.matrix(spec, fix_names = "none")
spec_as_mat[1:4, 1:3]

Exploring a spectra object

casper exposes a few ways to plot and query spectral data in spectra format. TODO ...

Plotting

The workhorse function for plotting spectra is plot(). It will jointly plot each spectrum in the spectra object. You should be able to pass the usual plot arguments to it, such as col, ylab, etc.

You can also plot the quantile of a spectra object with plot_quantile(). It's second argument, total_prob, is the total "mass" that the quantile encompasses. For instance, a total_prob = 0.95 covers 95% of the variation in the spectra object; i.e. it is the 0.025 to 0.975 quantile. The quantile plot can stand alone or be added to a current plot if add = TRUE.

Last but not least, you can also shade spectral regions with the plot_spec_regions() function. casper provides a default_spec_regions() matrix as an example, but you obviously can customize it for your needs.

par(mfrow = c(1, 3))

# Simple spectra plot
plot(spec, lwd = 0.75, lty = 1, col = "grey25", main = "All Spectra")

# Stand along quantile plot
plot_quantile(spec, total_prob = 0.8, main = "80% spectral quantile", 
              col = rgb(1, 0, 0, 0.5), lwd = 0.5, border = TRUE)

# Combined quantile and individual spctra plot
# With an added bonus of shading 4 spectral regions
plot(spec, lwd = 0.25, lty = 1, col = "grey50", "Spectra, quantile and regions")
plot_quantile(spec, total_prob = 0.8, 
              col = rgb(1, 0, 0, 0.25), add = TRUE, border = FALSE)
plot_spec_regions(spec, regions = default_spec_regions(), add = TRUE)

Querying

casper lets you query the spectra object and get summary infomation. You can easly get sample names with names() and wavelength labels with wavelengths(). It is also possible to recover the

# Get the vector of all sample names
# Note that duplicate sample names are permitted
n = names(spec)
n[1:5]

# Or get the vector of wavelengths
w = wavelengths(spec)
w[1:5]

# You can also get the dimensions of your `spectra` object
dim(spec)

If you really need the raw reclectance, you can retrieve it with the reflectance() function.

Subsetting spectra

You can subset the spectra using a notation similar to the [ i , j] function used in matrices and data.frames. The first argument in [ i, ] matches sample names, whereas the second argument [ , j ] matches the wavelength names. Here are some examples of how [ works in specrta:

# Subset spectra to all entries where sample_name matches "species_8"
spec_sp8 = spec[ "species_8", ]

# Check the results
dim(spec_sp8)

# Plotting the seubset result should work just fine
par(mfrow = c(1, 2), cex.main = 0.8, cex.axis = 0.6, cex.lab = 0.8)

plot(spec_sp8, col = "red", main = "Species 8 spectra")
plot_quantile(spec, total_prob = 1.0, add = TRUE,  col = rgb(0.2, 0.2, 0.2, 0.2), border = FALSE)
plot_spec_regions(spec_sp8, default_spec_regions(), col = rgb(1, 0.5, 0, 0.1), add = TRUE)

# And maybe further subset to the visible wavelengths only
spec_sp8 = spec_sp8[ , 400:700 ]

# This subset should still plot just fine
plot(spec_sp8, col = "red", main = "Visible spectra for species 8")
plot_quantile(spec, total_prob = 1.0, add = TRUE,  col = rgb(0.2, 0.2, 0.2, 0.2), border = FALSE)

Note that you can (1) subset samples using indexes and (2) use character or numeric to subset wavelengths. As said before, you cannot use indexes to subset wavelengths though.

# Subset samples by index should work. It is also OK to subset by wavelength 
# using numerics or characters.
reflectance(spec_sp8[ 1 , "405"]) == reflectance(spec_sp8[ 1 , 405])

#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#
# But remember that you CANNOT use indexes to subset wavelengths!
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!#

# Something that is obvioulsy an index, like using 2 instead of 401 (the 2nd band), will fail.
spec_sp8[ , 2 ]

# However, `casper` canot detect if you meant to get the two last bands when
# you use 2000:2001. It will assume that you wanted wavelengths "2000" and "2001"
# Bottomline, be very careful not to use indexes to subset wavelengths!

Manipulating samples and wavelength labels

You may want to edit certain simple attributes of spectra, such as make all sample names uppercase. This is easlily attainable in casper:

spec_new = spec

# Replace names with an uppercase version
names(spec_new) = toupper(names(spec_new))

# Check the results
names(spec_new)[1:5]

You may want to fiddle with the reflectance itself. This is easy to do, but there are some constraints. For example, casper will not allow you to have negative reflectance values or values greater than 1.

# Scale reflectance by 0.75
# spec_new[] = reflectance(spec_new) * 0.75
spec_new = spec_new * 0.75

# Plot the results
plot(spec, col = "blue", lwd = 0.75, cex.axis = 0.75)
plot(spec_new, col = "orange", lwd = 0.75, add = TRUE)

However, casper will throw an error if you try to perform an illegal operation to reflectance, for instance

# Trying to add 1.0 to all reflectance values will fail.
spec_new[] = reflectance(spec_new) + 1.0


annakat/casper_defunct documentation built on May 10, 2019, 11:50 a.m.