#' Group mean direction
#'
#' \code{direction_group} calculates the mean direction of all individuals in
#' each spatiotemporal group identified by \code{group_pts}. The function
#' accepts a \code{data.table} with relocation data appended with a
#' \code{direction} column from \code{direction_step} and a \code{group} column
#' from \code{group_pts}.
#'
#' The \code{DT} must be a \code{data.table}. If your data is a
#' \code{data.frame}, you can convert it by reference using
#' \code{\link[data.table:setDT]{data.table::setDT}} or by reassigning using
#' \code{\link[data.table:data.table]{data.table::data.table}}.
#'
#' The \code{direction} and \code{group} arguments expect the names of columns
#' in \code{DT} which correspond to the direction and group columns. The
#' direction column is expected in units of radians and the mean calculated with
#' [CircStats::circ.mean()].
#'
#' @param DT input data.table with direction column generated by
#' \code{direction_step} and group column generated with \code{group_pts}
#' @param direction character string of direction column name, default
#' "direction"
#' @param group character string of group column name, default "group"
#'
#' @return \code{direction_group} returns the input \code{DT} appended with a
#' \code{group_direction} column representing the mean direction of
#' all individuals in each spatiotemporal group.
#'
#' The mean direction is calculated using [CircStats::circ.mean()]
#' which expects units of radians.
#'
#' A message is returned when the \code{group_direction} columns already
#' exists in the input \code{DT}, because it will be overwritten.
#'
#' @export
#' @seealso \code{\link{direction_step}}, \code{\link{group_pts}},
#' [CircStats::circ.mean()]
#' @family Direction functions
#'
#' @references
#' See examples of using mean group direction:
#' * <https://doi.org/10.1098/rsos.170148>
#' * <https://doi.org/10.1098/rsos.201128>
#' * <https://doi.org/10.1016/j.beproc.2018.01.013>
#'
#' @examples
#' # Load data.table
#' library(data.table)
#' \dontshow{data.table::setDTthreads(1)}
#'
#' # Read example data
#' DT <- fread(system.file("extdata", "DT.csv", package = "spatsoc"))
#'
#' # Cast the character column to POSIXct
#' DT[, datetime := as.POSIXct(datetime, tz = 'UTC')]
#'
#' # Temporal grouping
#' group_times(DT, datetime = 'datetime', threshold = '20 minutes')
#'
#' # Spatial grouping with timegroup
#' group_pts(DT, threshold = 50, id = 'ID',
#' coords = c('X', 'Y'), timegroup = 'timegroup')
#'
#' # Calculate direction at each step
#' direction_step(
#' DT = DT,
#' id = 'ID',
#' coords = c('X', 'Y'),
#' projection = 32736
#' )
#'
#' # Calculate group direction
#' direction_group(DT)
direction_group <- function(
DT,
direction = 'direction',
group = 'group') {
if (is.null(DT)) {
stop('input DT required')
}
if (is.null(direction)) {
stop('direction column name required')
}
if (is.null(group)) {
stop('group column name required')
}
if (any(!(
c(direction, group) %in% colnames(DT)
))) {
stop(paste0(
as.character(paste(setdiff(
c(direction, group),
colnames(DT)
), collapse = ', ')),
' field(s) provided are not present in input DT'
))
}
if (any(!(DT[, vapply(.SD, is.numeric, TRUE), .SDcols = c(direction)]))) {
stop('direction must be numeric')
}
out_mean <- 'group_direction'
if (out_mean %in% colnames(DT)) {
message(paste(out_mean, 'column will be overwritten by this function'))
data.table::set(DT, j = out_mean, value = NULL)
}
if (DT[, !inherits(.SD[[1]], 'units'), .SDcols = c(direction)] ||
DT[, units(.SD[[1]])$numerator != 'rad', .SDcols = c(direction)]) {
stop('units(DT$direction) is not radians, did you use direction_step?')
}
DT[, c(out_mean) := units::as_units(
CircStats::circ.mean(units::drop_units(.SD)),
'rad'),
by = c(group),
.SDcols = c(direction)]
return(DT[])
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.