testNM | R Documentation |
The functions NMs.*
allow to define "single null models" (see
details). The function NMs2NMm
can be used on an object of
class "NMs"
to define "multiple null models". The function
testNM
can be used to simulate the defined null models.
NMs.randomCRW(ltraj, rangles = TRUE, rdist = TRUE, fixedStart = TRUE,
x0 = NULL, rx = NULL, ry = NULL, treatment.func = NULL,
treatment.par = NULL, constraint.func = NULL,
constraint.par = NULL, nrep = 999)
NMs.randomShiftRotation(ltraj, rshift = TRUE, rrot = TRUE,
rx = NULL, ry = NULL, treatment.func = NULL,
treatment.par = NULL, constraint.func = NULL,
constraint.par = NULL, nrep = 999)
NMs.CRW(N = 1, nlocs = 100, rho = 0, h = 1, x0 = c(0,0),
treatment.func = NULL,
treatment.par = NULL, constraint.func = NULL,
constraint.par = NULL, nrep = 999)
NMs.randomCs(ltraj, Cs = NULL, rDistCs = TRUE,
rAngleCs = TRUE,
rCentroidAngle = TRUE, rCs = TRUE,
newCs = NULL, newDistances = NULL,
treatment.func = NULL, treatment.par = NULL,
constraint.func = NULL, constraint.par = NULL,
nrep=999)
NMs2NMm(NMs, treatment.func = NULL,
treatment.par = NULL, constraint.func = NULL,
constraint.par = NULL, nrep = 999)
## S3 method for class 'NMm'
print(x, ...)
## S3 method for class 'NMs'
print(x, ...)
testNM(NM, count = TRUE)
ltraj |
an object of class |
rangles |
logical. Whether the turning angles should be randomized. |
rdist |
logical. Whether the distances between successive relocations should be randomized. |
fixedStart |
logical. If |
x0 |
a vector of length 2 giving the x and y coordinates of the
first relocations. If |
rx |
a vector of length 2 giving the x coordinates of the bounding box where the first location of the trajectory should be sampled |
ry |
a vector of length 2 giving the range (min, max) of the y coordinates of the bounding box where the first location of the trajectory should be sampled |
treatment.func |
any function taking two arguments |
treatment.par |
the R object that will be passed as
an argument to the parameter |
constraint.func |
any function taking two arguments |
constraint.par |
The R object that will be passed as an argument
to the parameter |
nrep |
The number of repetitions of the null model |
rshift |
logical. Whether the trajectory should be shifted over the study area. |
rrot |
logical. Whether the trajectory should be rotated around its barycentre. |
N |
The number of animals to simulate. |
nlocs |
The number of relocations building up each trajectory |
rho |
The concentration parameter for wrapped normal distribution
of turning angles (see |
h |
the scaling parameter for the movement length (see
|
Cs |
a list of vectors of length 2. Each vector should contain
the x and y coordinates of the capture sites of the animals in
|
rDistCs |
logical. Whether the distances between the barycentre of the trajectories and the corresponding capture sites should be randomized among trajectories |
rAngleCs |
logical. Whether the angle between the east direction and the line connecting the capture site and the barycentre of the trajectory should be drawn from an uniform distribution. |
rCentroidAngle |
logical. Whether the trajectory should be randomly rotated around its barycentre. |
rCs |
logical. Whether the trajectory should be randomly associated to a new capture site. |
newCs |
a list of vectors of length 2. Each vector should contain
the x and y coordinates of new capture sites. If |
newDistances |
a vector of new distances that will be used to
define the distances between capture sites and centroid of simulated
trajectories if |
NM , x |
a null model of class |
NMs |
a null model of class |
count |
whether the iterations should be displayed |
... |
additionnal arguments to be passed to or from other methods |
The null model approach has been considered as a useful approach in many fields of ecology to study biological processes. According to Gotelli and Graves (1996), "A null model is a pattern-generating model that is based on randomization of ecological data or random sampling from a known or imagined distribution. The null model is designed with respect to some ecological or evolutionary process of interest. Certain elements of the data are held constant, and others are allowed to vary stochastically to create new assemblage patterns. The randomization is designed to produce a pattern that would be expected in the absence of a particular ecological mechanism".
This approach can be very useful to test hypotheses related to animal
movements. The package adehabitatLT propose several general null
models that can be used to test biological hypotheses. For example,
imagine that we want to test the hypothesis that no habitat selection
occurs when the animal moves. The shape of the trajectory, under this
hypothesis would be the pure result of changing activity (moving,
foraging, resting). Therefore, a possible approach to test whether
habitat selection actually occurs would be to randomly rotate the
trajectory around its barycentre and shifting it over the study area.
The function NMs.randomShiftRotation
can be used to define such
a model. It is possible to constrain the randomization by defining a
"constraint function" (e.g. to keep only the randomized trajectories
satisfying a given criterion). It is required to specify a "treatment
function" (i.e., a function that will be applied to each randomized
trajectory). Once the null model has been defined, it is then possible
to perform the randomizations using the function testNM
. We
give below the details concerning the available null models, as well
as the constraint and the treatment functions.
First, two types of null models can be defined: single (NMs) and
multiple (NMm) null models. Consider an object of class
"ltraj"
containing N
bursts. With NMs, the treatment
function will be applied to each randomized burst of relocations. Thus,
for example, if nrep
repetitions of the null model are
required, nrep
repetitions of the null models will be carried
out for each burst separately. The treatment function will be applied
on each randomized burst. With NMm, for each repetition, N
randomized bursts of relocations are generated. The treatment is then
applied, for each repetition, to the whole set of N
randomized
bursts. Thus, NMs
are useful to test hypothesis on each
trajectory separately (e.g. individual habitat selection), whereas
NMm
are useful to test hypotheses relative to the whole set of
animals stored in an object of class ltraj
(e.g. interactions
between animals). The only current way to define an object of class
NMm
is to first define an object of class NMs
and then
use the function NMs2NMm
to indicate the treatment function
that should be applied on the whole set of trajectories.
The constraint function should be user-defined. It should return a
logical value indicating whether the constraint is satisfied. With
NMs
, this function should take only two parameters: x
and par
. The argument x
is a data frame with three
columns describing a trajectory (the X and Y coordinates, and the date
as a vector of class "POSIXct"
), and the argument par
can be any R object required by the constraint function (e.g. if the
constraint to keep 80% of the relocations of the randomized
trajectories within a given habitat type, the parameter par
can be a raster map, or a list of raster maps). With
NMm
, this function should also take only the two parameters
x
and par
. The argument par
can be any R object
required by the constraint function. However, when "NMm"
are
defined, the argument x
of the constraint function should be an
object of class "ltraj"
. If the function NMs2NMm
is
used to define the object of class "NMm"
, two types of
constraint can therefore be defined: at the individual level (in the
function NMs.*
) and for the whole set of animals (in the
function NMs2NMm
). In this case, some constraints will be
satisfied at the individual level, and others at the scale of the
whole set of animals. If no constraint function is defined by the
user, a constraint function always returning TRUE
is
automatically defined internally.
The treatment function can be any function defined by the user, but
should take two arguments x
and par
, identical to those
passed to the constraint function (i.e., x
should be a data
frame with three columns for NMs
and an object of class
"ltraj"
for NMm
. Note that only one treatment function
can be applied to the randomization: if NMs2NMm
is used to
define an object of class NMm
, the treatment function defined
in the function NMs.*
will be ignored, and only the treatment
function defined in the function NMs2NMm
will be taken into
account. If no treatment function is defined by the user, a treatment
function will be defined internally, simply returning the randomized
trajectory (i.e. a data.frame with three columns for NMs
, and
an object of class ltraj
for NMm
).
We now describe the list of available null models:
NMs.CRW
: this model is a purely parametric model. It
simulates a correlated random walk with specified parameters (see
?simm.crw
for a complete description of this model).
NMs.randomCRW
: this model also simulates a correlated
random walk, but the distributions of the turning angles and/or
distances between successive relocations are derived from the
trajectories passed as arguments. It is possible to randomize the
turning angles, the distances between successive relocations, or
both (default).
NMs.randomShiftRotation
: this model randomly rotates the
trajectory around its barycentre and randomly shifts it over the study
area (but does not change its shape). The function allows for a
random rotation, a random shift or both operations (default).
NMs.randomCs
: this model is similar to the previous one:
it keeps the shape of the trajectory unchanged. However, it
randomizes the position of the trajectories with respect to a set of
capture sites (it can be
used to take into account the fact that a the home range of a
sedentary animal captured at a given place is likely to be close to
this place). First a
capture site may be randomly drawn from a list of capture sites
(either the actual capture sites or a list passed by the user). Then,
the angle between the east direction and the line connecting the
capture site of the animal and the barycentre of its trajectory is
randomly drawn from a uniform distribution. Then, the distance
between this barycentre and the capture site is randomly drawn from
the observed distribution of distances between capture sites and
trajectory barycentre (or from a set of distances passed as
argument). Finally, the trajectory is randomly rotated around its
barycentre.
For objects of class "NMs"
a list of N
elements (where
N
is the number of trajectories in the object of class
"ltraj"
passed as argument, with each element is a list storing
the nrep
results of the treatment function applied to each randomized
trajectory.
For objects of class "NMm"
, a list of nrep
elements,
each element storing the result of the treatment function applied to
each set of N
randomized trajectories.
Clement Calenge clement.calenge@ofb.gouv.fr
Gotelli, N. and Graves, G. (1996) Null models in Ecology. Smithsonian Institution Press.
Richard, E., Calenge, C., Said, S., Hamann, J.L. and Gaillard, J.M. (2012) Studying spatial interactions between sympatric populations of large herbivores: a null model approach. Ecography, in press.
as.ltraj
for additional information about objects of
class "ltraj"
## Not run:
########################################
##
## example using NMs.randomShiftRotation
## first load the data:
data(puechcirc)
data(puechabonsp)
map <- puechabonsp$map
## Consider the first animal
## on an elevation map
anim1 <- puechcirc[1]
plot(anim1, spixdf=map[,1])
## We define a very simple treatment function
## for a NMs model: it just plots the randomized trajectory
## over the study area
## As required, the function takes two arguments:
## x is a data.frame storing a randomized trajectory (three
## columns: the x, y coordinates and the date)
## par contains the map of the study area
myfunc <- function(x, par)
{
par(mar = c(0,0,0,0))
## first plot the map
image(par)
## then add the trajectory
lines(x[,1], x[,2], lwd=2)
}
## Then we define the null model
##
## We define the range of the study area where the trajectory
## will be shifted:
rxy <- apply(coordinates(map),2,range)
rxy
## We define the null model with 9 repetitions
nmo <- NMs.randomShiftRotation(na.omit(anim1), rshift = TRUE, rrot = TRUE,
rx = rxy[,1], ry = rxy[,2], treatment.func = myfunc,
treatment.par = map, nrep=9)
## Then apply the null model
par(mfrow = c(3,3))
tmp <- testNM(nmo)
## You may try variations, by setting rshift or rrot to FALSE, to see
## the differences
## Note that some of the randomized trajectories are located outside the
## study area, although all barycentres are located within the X and Y
## limits of this study area.
## We may define a constraint function returning TRUE only if all
## relocations are located within the study area
## again, note that the two parameters are x and par
consfun <- function(x, par)
{
## first convert x to the class SpatialPointsDataFrame
coordinates(x) <- x[,1:2]
## then use the function over from the package sp
## to check whether all points in x are located inside
## the study area
ov <- over(x, geometry(map))
return(all(!is.na(ov)))
}
## Now fit again the null model under these constraints:
nmo2 <- NMs.randomShiftRotation(na.omit(anim1), rshift = TRUE, rrot = TRUE,
rx = rxy[,1], ry = rxy[,2], treatment.func = myfunc,
treatment.par = map,
constraint.func = consfun,
constraint.par = map, nrep=9)
## Then apply the null model
par(mfrow = c(3,3))
tmp <- testNM(nmo2)
## all the relocations are now inside the study area.
########################################
##
## example using NMs.randomCRW
## We generate correlated random walks with the same starting
## point as the original trajectory, the same turning angle
## distribution, and the same distance between relocation
## distribution. We use the same constraint function as previously
## (all relocations falling within the study area), and we
## use the same treatment function as previously (just plot
## the result).
mo <- NMs.randomCRW(na.omit(anim1), rangles=TRUE, rdist=TRUE,
treatment.func = myfunc,
treatment.par = map, constraint.func=consfun,
constraint.par = map, nrep=9)
par(mfrow = c(3,3))
tmp <- testNM(mo)
## Now, try a different treatment function: e.g. measure
## the distance between the first and last relocation,
## to test whether the animal is performing a return trip
myfunc2 <- function(x, par)
{
sqrt(sum(unlist(x[1,1:2] - x[nrow(x),1:2])^2))
}
## Now fit again the null model with this new treatment and 499 repetitions:
mo2 <- NMs.randomCRW(na.omit(anim1), rangles=TRUE, rdist=TRUE,
treatment.func = myfunc2,
treatment.par = map, constraint.func=consfun,
constraint.par = map, nrep=499)
## Then apply the null model
suppressWarnings(RNGversion("3.5.0"))
set.seed(298) ## to make the calculation reproducible
rand <- testNM(mo2)
## rand is a list with one element (there is one trajectory in anim1).
length(rand[[1]])
## The first element of rand is a list of length 499 (there are 499
## randomizations).
head(rand[[1]])
## unlist this list:
rand2 <- unlist(rand[[1]])
## calculate the observed average elevation:
obs <- myfunc2(na.omit(anim1)[[1]][,1:3], map)
## and performs a randomization test:
(rt <- as.randtest(rand2, obs, alter="less"))
plot(rt)
## Comparing to a model where the animal is moving randomly, and based
## on the chosen criterion (distance between the first and last
## relocation), we can see that the distance between the first and last
## relocation is rarely observed. It seems to indicate that the animal
## tends to perform a loop.
########################################
##
## example using NMs2NMm
## Given the previous results, we may try to see if all
## the trajectories in puechcirc are characterized by return
## trips
## We need a NMm approach. Because we have 3 burst in puechcirc
## we need a summary criterion. For example, the mean
## distance between the first and last relocation.
## We program a treatment function: it also takes two arguments, but x
## is now an object of class "ltraj" !
## par is needed, but will not be used in the function
myfunm <- function(x, par)
{
di <- unlist(lapply(x, function(y) {
sqrt(sum(unlist(y[1,1:2] - y[nrow(y),1:2])^2))
}))
return(mean(di))
}
## Now, prepare the NMs object: we do not indicate any treatment
## function (it would not be taken into account when NMs would be
## transformed to NMm). However, we keep the constraint function
## the simulated trajectories should fall within the study area
mo2s <- NMs.randomCRW(na.omit(puechcirc), constraint.func=consfun,
constraint.par = map)
## We convert this object to NMm, and we pass the treatment function
mo2m <- NMs2NMm(mo2s, treatment.func = myfunm, nrep=499)
## and we fit the model
suppressWarnings(RNGversion("3.5.0"))
set.seed(908)
resu <- testNM(mo2m)
## We calculate the observed mean distance between the
## first and last relocation
obs <- myfunm(na.omit(puechcirc))
## and performs a randomization test:
(rt <- as.randtest(unlist(resu), obs, alter="less"))
plot(rt)
## The test is no longer significant
########################################
##
## example using NMs.randomCs
## Consider this sample of 5 capture sites:
cs <- list(c(701184, 3161020), c(700164, 3160473),
c(698797, 3159908), c(699034, 3158559),
c(701020, 3159489))
image(map)
lapply(cs, function(x) points(x[1], x[2], pch=16))
## Consider this sample of distances:
dist <- c(100, 200, 150)
## change the treatment function so that the capture sites are showed as
## well. Now, par is a list with two elements: the first one is the map
## and the second one is the list of capture sites
myfunc <- function(x, par)
{
par(mar = c(0,0,0,0))
## first plot the map
image(par[[1]])
lapply(par[[2]], function(x) points(x[1], x[2], pch=16))
## then add the trajectory
lines(x[,1], x[,2], lwd=2)
}
## Now define the null model, with the same constraints
## and treatment as before
mod <- NMs.randomCs(na.omit(anim1), newCs=cs, newDistances=dist,
treatment.func=myfunc, treatment.par=list(map, cs),
constraint.func=consfun, constraint.par=map,
nrep=9)
## apply the null model
par(mfrow = c(3,3))
tmp <- testNM(mod)
## End(Not run)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.