This function calculates centres of activity (COAs) from detections at acoustic receivers.
coa(
.map,
.acoustics,
.moorings = NULL,
.delta_t,
.split = NULL,
.plot_weights = TRUE,
...,
.one_page = TRUE
)
A SpatRaster
that defines the study area (see glossary
). Here, .map
is used to:
Extract map_value
at centres of activity, for consistency with other routines (such as pf_filter()
);
Acoustic detection data.table
.
.acoustics
is a data.table
of acoustic detections, with the following columns: receiver_id
(or sensor_id
), timestamp
and (optionally) receiver_x
and receiver_y
columns;
(optional) .moorings
is a data.table
of receiver coordinates, which should be provided if unavailable in .acoustics
, with receiver_id
, receiver_x
and receiver_y
columns;
Receiver coordinates must be planar.
The time interval over which to calculate COAs. This can be specified in any way understood by lubridate::floor_date()
(see the unit
argument).
(optional) A character
that defines the name of the grouping factor in .acoustics
(e.g., individual_id
for dat_acoustics
).
Plot arguments.
.plot_weights
is a logical
variable that defines whether or not to plot the frequency distribution of weights for each .split
value (i.e., the frequency distribution of the number of detections at each receiver in each time interval, excluding time intervals without detections).
...
is a placeholder for arguments passed to graphics::hist()
, excluding main
.
.one_page
A logical
variable that defines whether or not to plot all histograms on one page.
The function returns a data.table
with the following columns:
{.split}
---a character
vector that distinguishes groups, if applicable;
timestep
---an integer
vector of time steps;
timestamp
---a POSIXt
vector of time stamps;
map_value
, x
, y
---the value of .map
at COAs and their coordinates;
Data are arranged by .split
and timestamp
.
COAs are calculated as a weighted mean of the locations of receivers at which individuals are detected over consecutive time intervals, weighted by the frequency of detections at each of those receivers. COAs are calculated via stats::weighted.mean()
, which assumes planar coordinates, for consistency with other patter
routines. To handle longitude/latitude coordinates, use geosphere::geomean()
.
This function replaces flapper::coa()
. See flapper::coa_setup_delta_t()
to evaluate alternative time internals.
To derive location samples from a particle filtering algorithm, see pf_filter()
and associates;
For mapping utilisation distributions from coordinates, see map_*()
functions (i.e., map_pou()
and map_dens()
);
library(data.table)
#### Set up example
map <- dat_gebco()
acoustics <- dat_acoustics
moorings <- dat_moorings
#### Example (1): Calculate COAs for an example individual
id <- dat_acoustics$individual_id[1]
acc <- dat_acoustics[individual_id == id, ]
coa(.map = map, .acoustics = acc, .moorings = moorings,
.delta_t = "2 hours")
#> timestep timestamp map_value x y
#> <int> <POSc> <num> <num> <num>
#> 1: 1 2016-03-17 00:00:00 58.17422 709242.1 6253107
#> 2: 2 2016-03-17 02:00:00 58.24497 708992.1 6252957
#> 3: 3 2016-03-17 04:00:00 58.17422 709255.3 6253107
#> 4: 4 2016-03-17 08:00:00 49.72233 709398.4 6253169
#> 5: 5 2016-03-21 20:00:00 58.17422 709242.1 6253107
#> ---
#> 763: 763 2017-05-31 20:00:00 56.08996 702980.1 6266245
#> 764: 764 2017-05-31 22:00:00 56.08996 702975.5 6266240
#> 765: 765 2017-06-01 00:00:00 68.36060 703042.1 6266307
#> 766: 766 2017-06-01 02:00:00 68.36060 703042.1 6266307
#> 767: 767 2017-06-01 04:00:00 68.36060 703042.1 6266307
#### Example (2): Customise the time interval via `.delta_t`
coa(.map = map, .acoustics = acc, .moorings = moorings,
.delta_t = "4 hours")
#> timestep timestamp map_value x y
#> <int> <POSc> <num> <num> <num>
#> 1: 1 2016-03-17 00:00:00 66.55176 709013.0 6252969
#> 2: 2 2016-03-17 04:00:00 58.17422 709255.3 6253107
#> 3: 3 2016-03-17 08:00:00 49.72233 709398.4 6253169
#> 4: 4 2016-03-21 20:00:00 58.17422 709242.1 6253107
#> 5: 5 2016-03-22 04:00:00 58.17422 709242.1 6253107
#> ---
#> 549: 549 2017-05-30 20:00:00 34.53219 702839.2 6266053
#> 550: 550 2017-05-31 16:00:00 56.08996 702974.0 6266239
#> 551: 551 2017-05-31 20:00:00 56.08996 702977.1 6266242
#> 552: 552 2017-06-01 00:00:00 68.36060 703042.1 6266307
#> 553: 553 2017-06-01 04:00:00 68.36060 703042.1 6266307
#### Example (3): Calculate COAs for multiple individuals via `.split`
# Calculate COAs
coa(.map = map, .acoustics = acc, .moorings = moorings,
.delta_t = "6 hours", .split = "individual_id")
#> individual_id timestep timestamp map_value x y
#> <int> <int> <POSc> <num> <num> <num>
#> 1: 25 1 2016-03-17 00:00:00 59.76520 709120.1 6253030
#> 2: 25 2 2016-03-17 06:00:00 49.72233 709398.4 6253169
#> 3: 25 3 2016-03-21 18:00:00 58.17422 709242.1 6253107
#> 4: 25 4 2016-03-22 00:00:00 58.17422 709242.1 6253107
#> 5: 25 5 2016-03-22 06:00:00 58.17422 709242.1 6253107
#> ---
#> 469: 25 469 2017-05-30 00:00:00 56.08996 702939.6 6266204
#> 470: 25 470 2017-05-30 06:00:00 68.36060 703042.1 6266307
#> 471: 25 471 2017-05-30 18:00:00 34.53219 702839.2 6266053
#> 472: 25 472 2017-05-31 18:00:00 56.08996 702976.4 6266241
#> 473: 25 473 2017-06-01 00:00:00 68.36060 703042.1 6266307
# Use one page for plots via `.one_page = TRUE`
coa(.map = map, .acoustics = acc, .moorings = moorings,
.delta_t = "6 hours", .split = "individual_id",
.one_page = FALSE)
#> individual_id timestep timestamp map_value x y
#> <int> <int> <POSc> <num> <num> <num>
#> 1: 25 1 2016-03-17 00:00:00 59.76520 709120.1 6253030
#> 2: 25 2 2016-03-17 06:00:00 49.72233 709398.4 6253169
#> 3: 25 3 2016-03-21 18:00:00 58.17422 709242.1 6253107
#> 4: 25 4 2016-03-22 00:00:00 58.17422 709242.1 6253107
#> 5: 25 5 2016-03-22 06:00:00 58.17422 709242.1 6253107
#> ---
#> 469: 25 469 2017-05-30 00:00:00 56.08996 702939.6 6266204
#> 470: 25 470 2017-05-30 06:00:00 68.36060 703042.1 6266307
#> 471: 25 471 2017-05-30 18:00:00 34.53219 702839.2 6266053
#> 472: 25 472 2017-05-31 18:00:00 56.08996 702976.4 6266241
#> 473: 25 473 2017-06-01 00:00:00 68.36060 703042.1 6266307
# Suppress plots via `.plot = FALSE`
coa(.map = map, .acoustics = acc, .moorings = moorings,
.delta_t = "6 hours", .split = "individual_id",
.one_page = TRUE)
#> individual_id timestep timestamp map_value x y
#> <int> <int> <POSc> <num> <num> <num>
#> 1: 25 1 2016-03-17 00:00:00 59.76520 709120.1 6253030
#> 2: 25 2 2016-03-17 06:00:00 49.72233 709398.4 6253169
#> 3: 25 3 2016-03-21 18:00:00 58.17422 709242.1 6253107
#> 4: 25 4 2016-03-22 00:00:00 58.17422 709242.1 6253107
#> 5: 25 5 2016-03-22 06:00:00 58.17422 709242.1 6253107
#> ---
#> 469: 25 469 2017-05-30 00:00:00 56.08996 702939.6 6266204
#> 470: 25 470 2017-05-30 06:00:00 68.36060 703042.1 6266307
#> 471: 25 471 2017-05-30 18:00:00 34.53219 702839.2 6266053
#> 472: 25 472 2017-05-31 18:00:00 56.08996 702976.4 6266241
#> 473: 25 473 2017-06-01 00:00:00 68.36060 703042.1 6266307
#### Example (4): Specify `.acoustics` only
# `.moorings` is not required if `.acoustics` contains receiver coordinates
coa(.map = map,
.acoustics =
acoustics |>
merge(moorings, by = "receiver_id"),
.delta_t = "6 hours", .split = "individual_id")
#> individual_id timestep timestamp map_value x y
#> <int> <int> <POSc> <num> <num> <num>
#> 1: 25 1 2016-03-17 00:00:00 59.76520 709120.1 6253030
#> 2: 25 2 2016-03-17 06:00:00 49.72233 709398.4 6253169
#> 3: 25 3 2016-03-21 18:00:00 58.17422 709242.1 6253107
#> 4: 25 4 2016-03-22 00:00:00 58.17422 709242.1 6253107
#> 5: 25 5 2016-03-22 06:00:00 58.17422 709242.1 6253107
#> ---
#> 1204: 35 402 2017-04-10 18:00:00 99.90396 709048.8 6253427
#> 1205: 35 403 2017-04-11 18:00:00 49.51562 706342.1 6254307
#> 1206: 35 404 2017-04-12 00:00:00 117.36553 707042.1 6253840
#> 1207: 35 405 2017-04-12 18:00:00 113.60658 708771.2 6253210
#> 1208: 35 406 2017-04-19 18:00:00 129.77667 707242.1 6253707