library(knitr) # load knitr to enable options library(respR) # load respR opts_chunk$set(collapse = TRUE, comment = "#>", cache = FALSE, tidy = FALSE, highlight = TRUE, fig.width = 10, fig.height = 5, fig.align = "center", R.options = list( scipen = 999, digits = 4))
The following are alternative methods of extracting rates from multiple replicates in intermittent-flow respirometry using calc_rate
or auto_rate
. They have been mostly superseded by calc_rate.int
and auto_rate.int
. See vignette("intermittent_long")
.
However we have left the details here in case they are of use in other cases. The main advantage to these are that they allow rates to be extracted from different data regions within each replicate or allow different methods to be used.
calc_rate
{#calc_rate}calc_rate.int
allows consistent region selection criteria to be applied to each replicate, and is usually the best way of extracting rates from intermittent-flow data. calc_rate
however also allows you to extract multiple rates from a dataset in a single command, and this can allow for rates from different regions in each replicate. Obviously, this requires you to know the row locations or timings of replicates.
calc_rate
allows data regions to be chosen by oxygen
, time
, or row
ranges. In the case of row
or time
, multiple subset regions can be specified, with the from
and to
inputs acting as vectors of paired values. Using this we can extract a rate from each replicate with one command.
We can use the same replicate start and end locations as in the example here to extract a rate from each complete replicate.
# inspect data urchin_int <- inspect(intermittent.rd) # calc rates urchin_int_rates <- calc_rate(urchin_int, from = c(1, 2101, 3901), to = c(1900, 3550, 4831), by = "row")
summary(urchin_int_rates)
We can see this produces exactly the same result as in the example here. Note, because calc_rate.int
has not been used there are no values in the $rep
column. calc_rate
does not consider multiple rates as coming from separate replicates. Instead it ranks them in order of inputs, as indicated by the $rank
column.
We can also extract by time values, and here we will also apply a different time window within each replicate.
urchin_int_rates <- calc_rate(urchin_int, from = c(200, 2300, 4100), to = c(1800, 3000, 4400), by = "time")
By default, the first is shown in print
and plot
, but the pos
input can be used to view others.
plot(urchin_int_rates, pos = 3)
Calling summary()
will show the coefficients, locations and values of all rates:
summary(urchin_int_rates)
Using calc_rate
like this allows you to extract rates from different regions within each replicate, or even multiple rates from each.
subset_data
{#subset}Another option for extracting replicates from a larger dataset is the subset_data
function. This allows you to easily subset both data frames and inspect
objects by time, row, or oxygen ranges. You can then pipe (|>
or %>%
) the subset directly to other functions such as calc_rate
or auto_rate
, or alternatively save replicates as separate objects for further analysis.
Here, we use the inspect
object we saved earlier containing the whole dataset, to create new inspect
objects for each replicate. These can be treated like any other inspect
object, including being passed to print
and plot
.
# Create separate replicate data frames u_rep1 <- subset_data(urchin_int, from = 1, to = 1900, by = "time") u_rep2 <- subset_data(urchin_int, from = 2100, to = 3500, by = "time") u_rep3 <- subset_data(urchin_int, from = 3700, to = 4831, by = "time")
Now we can calculate a rate from each, showing the results from the third one here. Unlike calc_rate.int
, using this method you are not restricted to extracting the rate from the exact same region within each replicate. In addition, this approach allows you to use the by = "oxygen"
method.
u_rate1 <- calc_rate(u_rep1, from = 7.1, to = 6.7, by = "oxygen") u_rate2 <- calc_rate(u_rep2, from = 7.1, to = 6.8, by = "oxygen") u_rate3 <- calc_rate(u_rep3, from = 7.0, to = 6.8, by = "oxygen")
u_rate3 <- calc_rate(u_rep3, from = 7.0, to = 6.8, by = "oxygen")
Alternatively, pipe the result, which has the advantage of not filling your local environment with redundant objects and overall makes for a tidier workflow.
u_rate3 <- urchin_int |> subset_data(from = 3700, to = 4831, by = "time") |> calc_rate(from = 7.0, to = 6.8, by = "oxygen")
summary(u_rate3)
A number of approaches could be used to iterate respR
functions to analyse these types of experiment; this is merely an example to illustrate how respR
can be easily iterated over multiple replicates. For most purposes calc_rate.int
or auto_rate.int
are better options.
Here we will show a simple for
loop to subset each replicate from the zeb_intermittent.rd
data and run auto_rate(method = "linear")
on it. We use a 'wait' period of 2 minutes (120s), and a 'measure' period of 7 minutes (420s), leaving 2 minutes of flushing excluded.
For actual analyses it is highly recommended you examine the plot of each replicate, or at very least those used in determining a final rate. Here in the interests of speed we suppress it with plot = FALSE
. Note also this code will create a list
object containing an auto_rate
object for every replicate, which will be quite large (several MB).
zeb <- inspect(zeb_intermittent.rd)
# define wait and measure periods wait <- 120 # 2 mins wait measure <- 420 # 7 mins measure ## start rows for each rep using sequence function (from, to, by) reps <- seq(5840, 74480, 660) ## data starts - apply wait starts <- reps + wait ## data ends - apply wait and measure period ends <- reps + wait + measure ## Empty list for saving results zeb_rmr <- list() ## loop for(i in 1:105){ st <- starts[i] # start time et <- ends[i] # end time ## subset replicate and pipe the result into auto_rate zeb_rmr[[i]] <- subset_data(zeb, from = st, to = et, by = "time") |> auto_rate(method = "linear", plot = FALSE) }
We can extract and view the top-ranked rate result from each replicate using the sapply
function.
## extract rates rmr_rate <- sapply(zeb_rmr, function(z) z$rate[1]) plot(rmr_rate, ylim = rev(range(rmr_rate)))
Note, we plot on a reverse axis so higher rates are higher on the plot. We can see that rates are higher in the initial stages of the experiment, then are quite consistent after they stabilise.
This saves pre- and post-experiment background rates for use in the next step.
bg_pre <- zeb |> subset_data(from = 1, to = 4999, by = "row") |> calc_rate.bg() bg_post <- zeb |> subset_data(from = 75140, to = 79251, by = "row") |> calc_rate.bg()
Here we use lapply
to apply the adjustment to each element of the RMR results list of auto_rate
objects and return a new list of adjust_rate
objects.
zeb_rmr_adj <- lapply(zeb_rmr, function(z) adjust_rate(z, by = bg_pre, by2 = bg_post, method = "linear"))
Once again we will use lapply
to loop through the SMR list of adjust_rate
objects and convert the rates for each replicate.
zeb_rmr_conv <- lapply(zeb_rmr_adj, function(z) convert_rate(z, oxy.unit = "mg/L", time.unit = "secs", output.unit = "mg/h/g", volume = 0.12, mass = 0.0009))
We'll look at two examples. This is the top-ranked result from these two replicates, though the actual object will contain more.
summary(zeb_rmr_conv[[10]], pos = 1) summary(zeb_rmr_conv[[90]], pos = 1)
This is similar to the other operations above, in that we use an apply
function to extract the top ranked final converted rate from each replicate.
zeb_rmr_all <- sapply(zeb_rmr_conv, function(z) z$rate.output[1])
Now we can plot them. Again, we reverse the y-axis.
plot(zeb_rmr_all, ylim = rev(range(zeb_rmr_all)))
It depends on the experiment how we might want to define the final RMR. This is the routine metabolic rate, so we want a rate that represents routine behaviour. Here, rates are very consistent after number 20, apart from one obvious outlier in number 89.
zeb_rmr_all[88:90]
Therefore, we will not use this one, but take the mean of all others from 20 onwards. This is just one approach of many we could apply. See here.
zeb_rmr_final <- mean(zeb_rmr_all[c(20:88,90:105)]) zeb_rmr_final
This is our final RMR: -0.96 mg/h/g.
Thius is the same analysis as above but using exclusively the apply
family of functions.
# Import and inspect raw data --------------------------------------------- # Importing would normally be the first step, e.g. read.csv("path/to/file") zeb <- inspect(zeb_intermittent.rd) # Background -------------------------------------------------------------- bg_pre <- subset_data(zeb, from = 0, to = 4999, by = "time") |> calc_rate.bg() bg_post <- subset_data(zeb, from = 75140, to = 79251, by = "time") |> calc_rate.bg() # Replicate structure ----------------------------------------------------- wait <- 120 # 2 mins wait measure <- 420 # 7 mins measure reps <- seq(5840, 74480, 660) ## start rows starts <- reps + wait ## data starts ends <- reps + wait + measure ## data ends # Subset each replicate --------------------------------------------------- zeb_rmr_subsets <- apply(cbind(starts,ends), 1, function(z) subset_data(zeb, from = z[1], to = z[2], by = "time")) # auto_rate on each replicate --------------------------------------------- zeb_rmr <- lapply(zeb_rmr_subsets, function(z) auto_rate(z, method = "linear", plot = FALSE)) # Adjust ------------------------------------------------------------------ zeb_rmr_adj <- lapply(zeb_rmr, function(z) adjust_rate(z, by = bg_pre, by2 = bg_post, method = "linear")) # Convert ----------------------------------------------------------------- zeb_rmr_conv <- lapply(zeb_rmr_adj, function(z) convert_rate(z, oxy.unit = "mg/L", time.unit = "secs", output.unit = "mg/h/g", volume = 0.12, mass = 0.0009)) # Extract rates ----------------------------------------------------------- zeb_rmr_all <- sapply(zeb_rmr_conv, function(z) z$rate.output[1]) # Calculate final rmr ----------------------------------------------------- zeb_rmr_final <- mean(zeb_rmr_all[c(20:88,90:105)])
zeb_rmr_final
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.