R/CalculateBioDensity.R

#' @title Function for calculating biological mass density of MMR tubes.
#'
#' @description
#'
#' This function takes a specific kind of input dataframe and outputs a dataframe
#' with mass density at the specified scale. It's partly-generalized, check
#' the analysis `.Rmd`s for information on which parameters were passed for
#' the final analysis.
#'
#' @param data           Input dataframe. See 'details'.
#' @param frame.size     Size of MMR picture frame. See 'details'.
#' @param scale          Scale of return data.
#' @param tube.length    Length of tube, in meters? Probably?
#' @param max.frames     Maximum number of frames possible from equipment.
#'
#' @return
#'
#' Returns a dataframe.
#'
#' @details
#'
#' \code{data} currently requires several columns:
#'
#' \code{veg_type} is one of 'shrub', 'tree', or 'grass', and used in biovolume
#'       to biomass conversions.
#'
#' \code{plot} is the first-order spatial organization - must be a factor.
#'
#' \code{date} is the date of the measurement, must be class "Date" or coercible.
#'
#' \code{frame.size} is a length-3 (or 2) numeric vector describing the [1]== height,
#' [2]== width, and [3]==depth of the MMR pictures. If length 2, depth will default
#' to the radius of the largest root in the dataset. Note that 'height' here is referring
#' to the dimension that runs the length of the MMR tube.
#'
#' @author Brandon McNellis
#' @export
#' @examples
#' CalculateBioDensity(data = df, frame.size = c(1, 2, 3))
CalculateBioDensity <- function(data, frame.size, scale = "tube") {
  # Input check section ####
  stopifnot(
    class(data) == "data.frame",
    "tube" %in% colnames(data),
    "length" %in% colnames(data),
    "diameter" %in% colnames(data),
    "veg_type" %in% colnames(data),
    "plot" %in% colnames(data),
    "date" %in% colnames(data),
    length(frame.size) == 2 | length(frame.size) == 3,
    class(frame.size) == "numeric"
  )
  if (length(frame.size) < 3) {
    stop("Need a frame size of 3.")
  }
  # Biovolume to biomass conversion factors -
  # c(0.21, 0.22, 0.31) for grass/shrub/tree are as per Jackson, Mooney & Schulze 1999
  biomass.convert <- c(0.21, 0.22, 0.31)
  names(biomass.convert) <- c("grass", "shrub", "tree")
  message("Calculating biomass, assuming input units in millimeters...")

  # Calculation section ####
  # Converts root diameter to biovolume (volume of cylinder)
  biovolume <- (pi * ((data$diameter / 2) ^ 2)) * data$length # Units in mm^3
  biovolume <- biovolume / 1000 # Convert mm^3 to cm^3
  # Converts biovolume to biomass using Jackon et al. (1999) conversion factor.
  biomass <- biovolume * biomass.convert[data[["veg_type"]]]
  # This will convert units to grams of biomass, conversion factor is g/cm^3
  data <- data.frame(data, biovolume, biomass)
  if (scale == "root") {
    message("Returning root-scale data... Done")
    return(data)
    # Returns GRAMS OF BIOMASS
  }
  # Below here is conversion from biomass in a tube to biodensity
  # in a tube using the tube window. There's another method to do
  # it in 'SDEF_roots_post_aggregation.Rmd' using the depth_bins.
  biodensity <- data.frame(matrix(ncol = 6, nrow = 0))
  colnames(biodensity) <- c("tube", "date", "sum_biovolume",
                            "sum_biomass", "mean_depth",
                            "tube_biodensity")
  for (i in unique(data[["tube"]])) {
    data.sub <- data[which(data[["tube"]] == i), ]
    data.sub <- data.sub[order(data.sub[["date"]]), ]
    date <- unique(data.sub[["date"]])
    tube <- rep(x=i, times=length(date))
    # Biovolume:
    biovolume <- data.frame(data.sub[["biovolume"]], data.sub[["date"]])
    colnames(biovolume) <- c("biovolume", "date")
    biovolume <- aggregate(x = biovolume[["biovolume"]],
                           by = list(biovolume[["date"]]),
                           FUN = sum)
    sum_biovolume <- biovolume[["x"]]
    # Biomass:
    biomass <- data.frame(data.sub[["biomass"]], data.sub[["date"]])
    colnames(biomass) <- c("biomass", "date")
    biomass <- aggregate(x = biomass[["biomass"]],
                         by = list(biomass[["date"]]),
                         FUN = sum)
    sum_biomass <- biomass[["x"]]
    # Real depth:
    depth <- data.frame(data.sub[["real_depth"]], data.sub[["date"]])
    colnames(depth) <- c("depth", "date")
    depth <- aggregate(x = depth[["depth"]],
                       by = list(depth[["date"]]),
                       FUN = mean)
    mean_depth <- depth[["x"]]
    # Biodensity:
    nframes <- length(unique(data.sub[["frame"]]))
    view.volume <- ((frame.size[1] * nframes) * frame.size[2] * frame.size[3])
    view.volume <- view.volume / 1000 # Converts mm3 to cm3
    tube_biodensity <- sum_biomass / view.volume
    sub.frame <- data.frame(tube, date, sum_biovolume, sum_biomass, mean_depth,
                            tube_biodensity)
    biodensity <- rbind(biodensity, sub.frame)
  }
  if (scale == "tube") {
    message("Returning tube-scale data... Done")
    return(biodensity)
  }
}
bmcnellis/SDEF.analysis documentation built on June 4, 2019, 10 a.m.