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
)

Arguments

.map

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());

.acoustics, .moorings

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.

.delta_t

The time interval over which to calculate COAs. This can be specified in any way understood by lubridate::floor_date() (see the unit argument).

.split

(optional) A character that defines the name of the grouping factor in .acoustics (e.g., individual_id for dat_acoustics).

.plot_weights, ..., .one_page

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.

Value

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.

Details

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.

See also

  • 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());

Author

Edward Lavender

Examples

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