sim_path_sa | R Documentation |
This function simulates movement paths from step lengths and turning angles. To implement the function, the number of time steps (n
) needs to be specified and, if applicable, the area within which movement should occur. For example, in marine environments, the inclusion of the sea as a spatial or raster
layer would restrict movement within the sea*. The starting location (p_1
) can be provided or simulated. At each time step, user-defined functions are used to simulate step lengths and turning angles, which can depend previous values of those variables via a lag
parameter, from which the next position is calculated. This implementation enables movement paths to be simulated under a variety of movement models, including random walks and correlated random walks, providing that they are conceptualised in terms of step lengths and turning angles. The function returns a list of outputs that includes the simulated path and, if requested, produces a plot of the simulated path.
sim_path_sa(
n = 10,
area = NULL,
p_1 = NULL,
sim_angle = sim_angles,
sim_step = sim_steps,
lag = 0L,
plot = TRUE,
add_points = list(pch = 21, bg = "darkgreen"),
add_path = list(length = 0.05, col = viridis::viridis(n)),
add_area = if (is.null(area)) NULL else list(),
seed = NULL,
verbose = TRUE,
...
)
sim_steps(...)
sim_angles(...)
n |
An integer that defines the number of time steps in the simulation. |
area |
(optional) A |
p_1 |
(optional) A matrix with one row and two columns that defines the starting location (x, y). If |
sim_angle |
A function that is used to simulate turning angles. This must accept a single number that represents some previous turning angle (degrees), even if this is simply ignored (see |
sim_step |
A function that is used to simulate step lengths. This follows the same rules as for |
lag |
If |
plot |
A logical variable that defines whether or not to produce a plot of the area (if provided) and the simulated movement path. |
add_area , add_points , add_path |
(optional) Named lists of arguments that are used to customise the appearance of the area, points (the starting location) and the path on the map, passed to the |
seed |
(optional) An integer that defines the seed (for reproducible simulations: see |
verbose |
A logical variable that defines whether or not to print messages to the console that relay function progress. |
... |
Additional arguments. For |
*Strictly speaking, only sequential positions are restricted to be within the allowed area. Yet since steps in the current implementation of the function are linear, the simulation of relatively large step lengths in an area with complex barriers to movement (e.g., convoluted coastlines), may lead to movement over inappropriate areas (e.g., over a peninsula) even through sequential positions are within the allowed area (e.g., either side of a peninsula). This problem can be mitigated by simulating time series for which sequential observations are closer in time (and thus for which step lengths are more constrained). For longer time series for which short time steps are undesirable, least-cost paths (e.g., see lcp_over_surface
) may be implemented to ensure biologically meaningful movements in future (but this is more computationally demanding for rapid simulations).
For coupled simulation–analysis workflows (such as sim_array
, sim_path_sa
and sim_detections
plus ac
, dc
, acdc
and pf
) note that the representation of the area
as SpatialPolygons-class
or SpatialPolygonsDataFrame-class
objects by the sim_*
functions, rather than a raster
grid, may be problematic at the land–sea interface if the Spatial* data used for the simulation do not agree precisely with the raster
data used to reconstruct movements: locations that are ‘allowed’ from the perspective of the Spatial* data may not be allowed by the raster
data (and vice versa). Furthermore, distances in the Spatial* data may differ from distances in the raster
data depending on grid resolution. At the time of writing, this can be resolved in two ways. (A) Check simulated movements in relation to the grid across which movements are reconstructed. Animal locations should also be translated onto the raster
before simulating detections (see sim_detections
). Movement distances should remain admissible under the movement model. (B) For this function, you can now use a raster
to simulate receiver locations (see also acs_setup_containers
).
This function requires the circular
package.
The function returns a named list of arguments that defines the simulated path (‘xy_mat’, ‘angle_mat’, ‘step_mat’ and ‘path’) and a named list of arguments that were used to generate the path (‘args’). ‘xy_mat’ is an n-row, two-column matrix that defines the simulated position (x, y) at each time step; ‘angle_mat’ and ‘step_mat’ are n-row, one-column matrices that define the simulated turning angle (degrees) and step length (in map units) at each time step; and ‘path’ is a SpatialLines
representation of the movement path.
Edward Lavender
For movement simulations, see sim_path_*
for the full list of functions currently implemented in flapper
. For example, sim_path_ou_1
simulates a movement path based on past locations according to an Ornstein-Uhlenbeck process (which is not based on step lengths and turning angles). More broadly, sim_array
, sim_path_*
and sim_detections
provide an integrated workflow for simulating acoustic arrays, movement paths in these areas and detections at receivers arising from movement.
#### Example (1): Simulate movement path under default parameters
# Simulate path
path <- sim_path_sa()
# The function returns a list of parameters that define the array and a plot
summary(path)
#### Example (2): Change the number of time steps
path <- sim_path_sa(n = 100)
#### Example (3): Change the characteristics of the study area
# .. and define the starting location of the individual
sea <- invert_poly(dat_coast)
path <- sim_path_sa(
n = 100,
area = sea,
p_1 = matrix(c(706529.1, 6262293), ncol = 2),
add_area = list(x = sea, col = "skyblue")
)
#### Example (4): Change the movement model(s) to use alternative distributions/parameters
## Step lengths
# Define new function to simulate step lengths
sim_step_lengths <- function(...) stats::rgamma(1, shape = 10, scale = 1)
# Check outputs suitable values
prettyGraphics::pretty_hist(replicate(n = 1000, expr = sim_step_lengths()))
# Implement simulation
path <- sim_path_sa(n = 100, sim_step = sim_step_lengths)
prettyGraphics::pretty_hist(as.numeric(path$step_mat))
## Turning angles
# E.g., Random walk: draw turning angle from von Mises distribution
sim_angles_vmd <- function(...) {
angle <- circular::rvonmises(
n = 1,
mu = circular::circular(0),
kappa = 0,
control.circular = list(units = "degrees")
)
return(as.numeric(angle))
}
path <- sim_path_sa(n = 100, sim_angle = sim_angles_vmd)
# E.g., Correlated random walk: draw turning angle from wrapped normal distribution
sim_angles_rwn <- function(...) {
angle <- circular::rwrappednormal(
n = 1,
mu = circular::circular(0),
rho = 0.999,
sd = 0,
control.circular = list(units = "degrees")
)
return(as.numeric(angle))
}
path <- sim_path_sa(n = 100, sim_angle = sim_angles_rwn)
#### Example (5) Change the movement models to depend on some lagged value
# ... of the variable in question
# Define a sim_angle function that depends on some previous angle
# While the time step is less than the lag, the function needs to be
# ... able to handle missing angles and return sensible values in these
# ... cases e.g., via an 'is.null' structure:
sim_angles_wrn_with_lag <- function(angle = NULL, ...) {
if (is.null(angle)) {
cat("\n... ... method (1) activated...\n") # useful check
angle_out <- circular::circular(0)
} else {
angle_out <- circular::rwrappednormal(
n = 1,
mu = circular::circular(angle, units = "degrees"),
rho = 0.9,
sd = 0.1,
control.circular = list(units = "degrees")
)
}
return(as.numeric(angle_out))
}
# Check function
sim_angles_wrn_with_lag(NULL)
sim_angles_wrn_with_lag(1)
# Implement algorithm
path <- sim_path_sa(sim_angle = sim_angles_wrn_with_lag, lag = 1)
path <- sim_path_sa(sim_angle = sim_angles_wrn_with_lag, lag = 2)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.