Skip to content

Commit

Permalink
Merge pull request #66 from ropensci/feat/position-along-group-axis
Browse files Browse the repository at this point in the history
Feat/position along group axis
  • Loading branch information
robitalec authored Oct 31, 2024
2 parents 04e182c + 08871cc commit b00179e
Show file tree
Hide file tree
Showing 28 changed files with 528 additions and 40 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,6 @@ VignetteBuilder:
knitr
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.3.1
RoxygenNote: 7.3.2
SystemRequirements: GDAL (>= 2.0.1), GEOS (>= 3.4.0), PROJ (>= 4.8.0),
sqlite3
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ export(group_lines)
export(group_polys)
export(group_pts)
export(group_times)
export(leader_direction_group)
export(randomizations)
import(data.table)
6 changes: 3 additions & 3 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

New experimental functions:

* `direction_polarization`` function for calculating polarization of individual
* `direction_polarization` function for calculating polarization of individual
directions within spatiotemporal groups [PR 76](https://github.com/ropensci/spatsoc/pull/76)
* `direction_group`` function for calculating mean group direction
* `direction_group` function for calculating mean group direction
[PR 91](https://github.com/ropensci/spatsoc/pull/91)
* `direction_to_centroid`` function for calculating direction in radians from
* `direction_to_centroid` function for calculating direction in radians from
each individual's position in a spatiotemporal group and the group's centroid,
`distance_to_centroid` function for calculation the distance (and rank distance)
from each individual's position in a spatiotemporal group and the group's
Expand Down
2 changes: 1 addition & 1 deletion R/direction_group.R
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
#' @family Direction functions
#'
#' @references
#' See example of using mean group direction:
#' 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>
Expand Down
4 changes: 2 additions & 2 deletions R/direction_polarization.R
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@
#' @family Direction functions
#'
#' @references
#' See example of using polarization:
#' See examples of using polarization:
#' * <https://doi.org/10.1016/j.cub.2017.08.004>
#' * <10.1371/journal.pcbi.1009437>
#' * <https://doi.org/10.1371/journal.pcbi.1009437>
#' * <https://doi.org/10.7554/eLife.19505>
#'
#' @examples
Expand Down
4 changes: 2 additions & 2 deletions R/group_pts.R
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@
#' @param DT input data.table
#' @param threshold distance for grouping points, in the units of the
#' coordinates
#' @param id Character string of ID column name
#' @param coords Character vector of X coordinate and Y coordinate column names.
#' @param id character string of ID column name
#' @param coords character vector of X coordinate and Y coordinate column names.
#' Note: the order is assumed X followed by Y column names.
#' @param timegroup timegroup field in the DT within which the grouping will be
#' calculated
Expand Down
185 changes: 185 additions & 0 deletions R/leader_direction_group.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
#' Leadership along group direction
#'
#' Given the mean direction of a group of animals, \code{leader_direction_group}
#' shifts the coordinate system to a new origin at the group centroid and
#' rotates the coordinate system by the mean direction to return each
#' individual's position along the mean direction, representing leadership in
#' terms of the front-back position in each group's mean direction.
#'
#' The function accepts a \code{data.table} with relocation data appended with a
#' \code{group_direction} column from \code{direction_group} and group centroid
#' columns from \code{centroid_group}. Relocation data should be in two columns
#' representing the X and Y coordinates.
#'
#' 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{group_direction} argument expects the names of columns in \code{DT}
#' which correspond to the mean group direction generated by
#' \code{direction_group}. The mean group direction column is expected in units
#' of radians. The \code{coords} arguments expects the names of columns in
#' \code{DT} which correspond to the X and Y coordinate columns. The
#' \code{return_rank} argument controls if the rank of each individual's
#' distance to the group centroid is also returned. If \code{return_rank} is
#' TRUE, the \code{group} argument is required to specify the group column
#' generated by \code{group_pts}. The \code{ties.method} argument is passed to
#' \code{data.table::frank}, see details at
#' \code{\link[data.table:frank]{?data.table::frank}}.
#'
#' @return \code{leader_direction_group} returns the input \code{DT} appended
#' with a \code{position_group_direction} column indicating the position along
#' the group direction in the units of the projection and, optionally, a
#' \code{rank_position_group_direction} column indicating the
#' within group rank position along the group dirtection \code{return_rank =
#' TRUE}).
#'
#' A message is returned when \code{position_group_direction} or
#' \code{rank_position_group_direction} columns already exist in the input
#' \code{DT}, because they will be overwritten.
#'
#' @inheritParams direction_group
#' @inheritParams distance_to_centroid
#' @param group_direction group_direction column name generated using
#' \code{direction_group}, default 'group_direction'
#'
#' @export
#' @seealso \code{\link{direction_group}}, \code{\link{centroid_group}}
#' @family Leadership functions
#'
#' @references
#' See examples of measuring leadership along group direction (also called
#' forefront index):
#' * <https://doi.org/10.1371/journal.pone.0036567>
#' * <https://doi.org/10.1111/jfb.15315>
#' * <https://doi.org/10.1098/rspb.2021.0839>
#'
#' @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 centroid
#' centroid_group(DT, coords = c('X', 'Y'))
#'
#' # Calculate group direction
#' direction_group(DT)
#'
#' # Calculate leader in terms of position along group direction
#' leader_direction_group(DT, coords = c('X', 'Y'))
leader_direction_group <- function(
DT = NULL,
group_direction = 'group_direction',
coords = NULL,
group = NULL,
return_rank = FALSE,
ties.method = 'average') {
# Due to NSE notes
position_group_direction <- rank_position_group_direction <- NULL

if (is.null(DT)) {
stop('input DT required')
}

if (length(coords) != 2) {
stop('coords requires a vector of column names for coordinates X and Y')
}

xcol <- data.table::first(coords)
ycol <- data.table::last(coords)

centroid_xcol <- paste0('centroid_', gsub(' ', '', xcol))
centroid_ycol <- paste0('centroid_', gsub(' ', '', ycol))

check_cols <- c(coords, group_direction, centroid_xcol, centroid_ycol)

if (any(!(check_cols %in% colnames(DT)))) {
stop(paste0(
as.character(paste(setdiff(
check_cols,
colnames(DT)
), collapse = ', ')),
' field(s) provided are not present in input DT'
))
}

if (any(!(DT[, vapply(.SD, is.numeric, TRUE), .SDcols = coords]))) {
stop('coords must be numeric')
}

if (any(!(DT[, vapply(.SD, is.numeric, TRUE),
.SDcols = c(centroid_xcol, centroid_ycol)]))) {
stop('centroid coords must be numeric')
}

if (is.null(return_rank)) {
stop('return_rank required')
}

if ('position_group_direction' %in% colnames(DT)) {
message(
'position_group_direction column will be overwritten by this function'
)
data.table::set(DT, j = 'position_group_direction', value = NULL)
}

if (DT[, !inherits(.SD[[1]], 'units'), .SDcols = c(group_direction)] ||
DT[, units(.SD[[1]])$numerator != 'rad', .SDcols = c(group_direction)]) {
stop(
'units(DT$group_direction) is not radians, did you use direction_group?'
)
}

DT[, position_group_direction :=
cos(units::drop_units(.SD[[1]])) * (.SD[[2]] - .SD[[4]]) +
sin(units::drop_units(.SD[[1]])) * (.SD[[3]] - .SD[[5]]),
by = .I,
.SDcols = c(group_direction, xcol, ycol, centroid_xcol, centroid_ycol)]

if (return_rank) {
rank_col <- 'rank_position_group_direction'
if (rank_col %in% colnames(DT)) {
message(
paste0(rank_col, ' column will be overwritten by this function')
)
data.table::set(DT, j = 'rank_position_group_direction', value = NULL)
}

if (is.null(group)) {
stop('group column name required')
}

if (!group %in% colnames(DT)) {
stop('group column not present in input DT, did you run group_pts?')
}

DT[, rank_position_group_direction :=
data.table::frank(-position_group_direction,
ties.method = ties.method),
by = c(group)]
}

return(DT[])
}
2 changes: 1 addition & 1 deletion codemeta.json
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@
},
"SystemRequirements": "GDAL (>= 2.0.1), GEOS (>= 3.4.0), PROJ (>= 4.8.0),\n sqlite3"
},
"fileSize": "1979.472KB",
"fileSize": "1988.678KB",
"citation": [
{
"@type": "ScholarlyArticle",
Expand Down
4 changes: 2 additions & 2 deletions man/build_lines.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions man/build_polys.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions man/centroid_dyad.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions man/centroid_fusion.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/centroid_group.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/direction_group.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions man/direction_polarization.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions man/direction_step.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/direction_to_centroid.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/distance_to_centroid.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions man/edge_dist.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions man/edge_nn.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/get_gbi.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit b00179e

Please sign in to comment.