EMF-CREAF, VivArmor Nature, LEMAR
What is Ecological Trajectory Analysis?
Ecological Trajectory Analysis (ETA) is a framework to analyze the dynamics of ecological entities (e.g. communities or ecosystems).
History of ETA
In 2019, De Cáceres et al, presented Community Trajectory Analysis (CTA) as a framework for trajectory analysis in community ecology.
The initial framework was extended with new metrics and visualisation modes in Sturbois et al. (2021a).
The same framework was applied to stable isotope data in Sturbois et al. (2021b), referring to it as Stable Isotope Trajectory Analysis (SITA).
Recently, the framework has been extended to cyclical data (Djeghri et al. in prep.), under the name of Cyclical Ecological Trajectory Analysis (CETA).
Flexibility
Since it can be applied to multiple target entities and multivariate spaces, we collectively refer to the framework as Ecological Trajectory Analysis (ETA).
The ETA framework is implemented in package ecotraj:
Installation
Package ecotraj (ver. 1.1.0) is distributed from CRAN and can be installed using:
More frequent updates can be obtained if installing from GitHub (compilation tools are required):
Documentation
Although the package comes with function documentation, the complete function reference and articles explaining how to use the package can be found at https://emf-creaf.github.io/ecotraj/.
The most important conceptual elements of ETA are:
Element | Notation | Description |
---|---|---|
Target entity | The ecological entity whose dynamics are of interest. It can be an individual, a population, a community or an entire ecosystem | |
Ecological observation | \(\mathbf{o}\) | The assessment of the state of a target entity, normally implying multiple attributes, at a given point in time. We also use the word observation to refer to the pair including the ecological state and time of assessment. |
Survey | An indication of the order of ecological observations (e.g. first, second, …), sometimes taken as a surrogate of linear time. | |
Ecological state | \(\mathbf{x}\) | The feature values of a target entity when assessed at given point in time. In practice, it corresponds to an (implicit or explicit) position in \(\Omega_0\). |
Multivariate state space | \(\Omega_0\) | The multidimensional space of ecological states. While \(\Omega_0\) could be defined by explicit orthogonal axes, in ETA it is defined by calculating the dissimilarity (\(d\)) between all pairs of states. |
Time | \(t\) | The position of a given ecological observation in a (linear) temporal axis (i.e. ‘when’ the assessment act occurred). |
Note
Recurrent or cyclical time is another conceptual element in Cyclical Ecological Trajectory Analysis (CETA).
The most important geometric elements of ETA are:
Element | Notation | Description |
---|---|---|
Ecological state | \(\mathbf{x}\) | The position of an observation in space \(\Omega_0\). |
Directed segment | \(\mathbf{s}\) | A pair of time-ordered ecological states. |
Ecological observation | \(\mathbf{o}\) | A pair including the ecological state \(\mathbf{x}\) and the assessment time \(t\), i.e. \(\mathbf{o} = \{ \mathbf{x}, t \}\). |
Ecological trajectory | \(\mathbf{T}\) | A trajectory of size \(n\) is defined as the set of \(n\) time-ordered ecological observations. Alternatively, \(\mathbf{T}\) can be defined as a set of \(n - 1\) directed segments. |
Trajectory path | A continuous function \(f_T: [0,1]\) into \(\Omega_0\), defining all points of the trajectory \(\mathbf{T}\) from \(f_T(0) = x_1\) to \(f_T(1) = x_n\). The path includes the ecological states derived from ecological observations as well as intermediate states. | |
Ecological sub-trajectory | A trajectory derived from a time-ordered subset of the observations of its parent trajectory. | |
Trajectory section | A trajectory describing a subset of its parent trajectory path. |
Note
Other geometry elements are defined in Cyclical Ecological Trajectory Analysis (CETA).
Trajectory data inputs for ETA are:
Metadata
In this session we will primarily use a small data set where three entities have been observed four times:
Distance matrix
We will assume that ecological states can be compared using the Euclidean distance and only two variables have been measured:
Dynamic information is contained in objects of class trajectories
.
To build them, we need to combine the distance matrix (\(\mathbf{D}\)) and the entity/survey information in a single object using function defineTrajectories()
:
The function returns an object (a list) of class trajectories
that contains all the information for analysis:
Note that x
does not contain observation times (they are assumed to be equal to surveys).
In our examples we will also use another object where we include observation times:
sites surveys times
1 1 1 1.00
2 1 2 2.00
3 1 3 3.00
4 1 4 4.00
5 2 1 1.00
6 2 2 1.75
7 2 3 2.50
8 2 4 3.25
9 3 1 1.00
10 3 2 1.50
11 3 3 2.00
12 3 4 2.50
One particularity of this second trajectory object xt
is that trajectories are not synchronous (observation times are not the same across trajectories):
At some point in the ETA, one may desire to focus on particular trajectories or surveys. Function subsetTrajectory()
allows subsetting objects of class trajectories
, For example, we can decide to work with the trajectories of the second and third entities (sites):
$d
1 2 3 4 5 6 7
2 1.0000000
3 1.5206906 0.5590170
4 2.1360009 1.2500000 0.7071068
5 0.2500000 1.0307764 1.5000000 2.0615528
6 1.0307764 0.2500000 0.5000000 1.1180340 1.0000000
7 1.4577380 0.7905694 0.5590170 0.7500000 1.3462912 0.5590170
8 1.6007811 1.2500000 1.1180340 1.1180340 1.4142136 1.0000000 0.5590170
$metadata
sites surveys times
1 2 1 1.00
2 2 2 1.75
3 2 3 2.50
4 2 4 3.25
5 3 1 1.00
6 3 2 1.50
7 3 3 2.00
8 3 4 2.50
attr(,"class")
[1] "trajectories" "list"
To begin our analysis of the three trajectories, we display them in an ordination space, using function trajectoryPCoA()
:
Since \(\Omega_0\) has only two dimensions in this example, the Principal Coordinates Analysis (PCoA) on matrix \(\mathbf{D}\) displays the complete space.
Metric | Description |
---|---|
Segment length | The length of a segment \(\mathbf{s}\) is given by the distance between its two endpoints. |
Total path length | The total path length of a trajectory \(\mathbf{T}\) is the sum of the lengths of its directed segments. |
Segment speed | When associated to explicit time coordinates \(t_{start}\) and \(t_{end}\), the speed of change of a segment \(\mathbf{s}\) is defined as the length divided by its duration. |
Trajectory speed | The average speed of change in trajectory \(\mathbf{T}\) is estimated as the total path length divided by its duration. |
Net change | For any state \(\mathbf{x}_i\) of a trajectory \(\mathbf{T}\), the net change is defined as the distance with respect to the initial (reference) state \(\mathbf{x}_1\), i.e. \(NC(\mathbf{x}_i) = d(\mathbf{x}_i, \mathbf{x}_1)\). |
Trajectory sum of squares | The sum of squares of the internal variation in the ecological states that conform trajectory \(\mathbf{T}\). |
Trajectory internal variation | An unbiased estimator of the internal variance in the ecological states that conform trajectory \(\mathbf{T}\). |
Contribution of states to internal variation | The absolute (sum of squares) or relative contributions of individual ecological states to the temporal variation in trajectory \(\mathbf{T}\). |
Note
Combinations of these metrics can be used to estimate other metrics presented in Sturbois et al. (2021a), such as the Net change ratio or Recovering or departing trajectory.
Segment/trajectory length or speed metrics are useful, for example, to determine which entity is evolving faster than others or to identify periods of faster changes within the dynamics of a single entity.
One can obtain the length of trajectory segments and the total path length:
In addition to segment lengths, one can also calculate the distance (i.e. the Net change) between all states and the initial, which is taken as reference:
When observation times are available, it may be of interest to calculate segment or trajectory speeds using:
Finally, one may calculate the internal variation of states within each trajectory using:
ss_1 ss_2 ss_3 ss_4 internal_ss internal_variance
1 2.2500000 0.2500000 0.2500000 2.2500000 5.000000 1.6666667
2 1.3281250 0.0781250 0.1406250 1.0156250 2.562500 0.8541667
3 0.8007812 0.1757812 0.2070312 0.4257813 1.609375 0.5364583
Since space \(\Omega_0\) can include multiple dimensions, angles cannot be calculated with respect to a single plane. Instead, each angle is measured on the plane defined by a triplet of points.
Zero angles indicate that the three points (e.g. the two consecutive segments) are in a straight line. The larger the angle value, the more is trajectory changing in direction.
Function trajectoryAngles()
allows calculating the angles between consecutive segments:
S1-S2 S2-S3 mean sd rho
1 0.00000 0.00000 0.00000 0.00000000 1.0000000
2 26.56505 18.43495 22.50000 0.07097832 0.9974842
3 63.43495 53.13010 58.28253 0.08998746 0.9959593
Mean and standard deviation statistics of angles are calculated according to circular statistics.
We can use the same function to calculate angles relative to the initial state:
It is possible to assess multiple trajectory metrics in one function call to trajectoryMetrics()
. This will only provide metrics that apply to the whole trajectory:
trajectory n t_start t_end duration length mean_speed mean_angle
1 1 4 1 4.00 3.00 3.000000 1.000000 0.00000
2 2 4 1 3.25 2.25 2.266124 1.007166 22.50000
3 3 4 1 2.50 1.50 2.118034 1.412023 58.28253
directionality internal_ss internal_variance
1 1.0000000 5.000000 1.6666667
2 0.8274026 2.562500 0.8541667
3 0.5620859 1.609375 0.5364583
Another function, called trajectoryWindowMetrics()
calculates trajectory metrics on moving windows over trajectories, but will not be illustrated here.
Ecological states occupy a relative position within their trajectory that depends on the total path length of the trajectory.
Function trajectoryProjection()
allows obtaining the relative position of each ecological state of a trajectory:
The same function can also be used to perform an orthogonal projection of arbitrary ecological states onto a given reference trajectory.
For example we can study the projection of third state of the trajectory of entity ‘2’ (i.e. state 7) onto the trajectory of entity ‘1’ (i.e. states 1 to 4), which happens to be in the half of the trajectory:
distanceToTrajectory segment relativeSegmentPosition
7 0.5 2 0.5
relativeTrajectoryPosition
7 0.5
Sometimes different ecosystems follow the same or similar path but with different speeds, or with an observations starting at a different point in the dynamic sequence.
We can quantify those differences using function trajectoryShifts()
, which internally uses orthogonal projection.
To illustrate this function, we will use a small data set of two parallel trajectories, but where the second is shifted:
entities3 <- c("1","1","1","1","2","2","2","2")
times3 <- c(1,2,3,4,1,2,3,4)
xy3<-matrix(0, nrow=8, ncol=2)
xy3[2,2]<-1
xy3[3,2]<-2
xy3[4,2]<-3
xy3[5:8,1] <- 0.25
xy3[5:8,2] <- xy3[1:4,2] + 0.5 # States are all shifted with respect to entity "1"
x_shift <- defineTrajectories(dist(xy3), entities3, times = times3)
We can see the differences graphically:
Function trajectoryShifts()
allows comparing different observations to a reference trajectory:
reference site survey time timeRef shift
1 1 2 1 1 1.5 0.5
2 1 2 2 2 2.5 0.5
3 1 2 3 3 3.5 0.5
4 1 2 4 4 NA NA
5 2 1 1 1 NA NA
6 2 1 2 2 1.5 -0.5
7 2 1 3 3 2.5 -0.5
8 2 1 4 4 3.5 -0.5
We see that the observations of trajectory “2” correspond to states of trajectory “1” at 0.5 time units later in time. Surveys with missing values indicate that the projection of the target state cannot be determined (because the reference trajectory is too short).
The study of the convergence or divergence between a pair of trajectories can be done in different ways, corresponding to different ecological questions.
If the trajectories are synchronous (i.e., their observations where done at the same times), one can analyze the sequence of distances between consecutive observations and address the question of whether the states of the two trajectories become closer/farther over time using a statistical test:
Note that this test can be straightforwardly generalized to multiple trajectories:
Finally, trajectory convergence/divergence can also be studied in non-synchronous trajectories. In this case, the question addressed is whether the states of the target trajectory become closer/farther to the reference trajectory over time.
Calculating the dissimilarity between a pair of trajectories allows quantifying the resemblance in dynamics of the corresponding pair of ecological entities.
There are multiple ways of assessing the dissimilarity in dynamics, e.g.:
Coefficient | Differences included |
---|---|
Segment path distance (SPD) | Position, shape. |
Directed segment path distance (DSPD) | Position, shape, direction. |
Time-sensitive path distance (TSPD) | Position, shape, direction, speed. |
Function trajectoryDistances()
allows calculating several of them, and returns a distance matrix containing the dissimilarity between pairs of trajectories:
Note
A detailed comparison of trajectory dissimilarity indices can be found in article Distance metrics for trajectory resemblance.
One may be interested in knowing how much diverse are a set of trajectories, and which entities follow dynamics more distinct from others. We refer to the diversity of trajectories as dynamic variation., and these questions can be addressed using:
$dynamic_ss
[1] 0.7114251
$dynamic_variance
[1] 0.3557125
$relative_contributions
1 2 3
0.51366204 0.06351261 0.42282535
Analogously to trajectoryInternalVariation()
, function dynamicVariation()
returns the sum of squares of dynamic variation, an unbiased dynamic variance estimator and the relative contribution of individual trajectories to the overall sum of squares.
Function dynamicVariation()
, makes internal calls to trajectoryDistances()
, which means that we may get slightly different results if we change the trajectory dissimilarity coefficient:
$dynamic_ss
[1] 0.7717349
$dynamic_variance
[1] 0.3858674
$relative_contributions
1 2 3
0.46561876 0.03786032 0.49652092
Sometimes the available trajectory data is non-synchronous, due to missing observations or observation times that do not match across trajectories.
Trajectory interpolation allows recalculating positions along trajectory pathways so that observation times are the same across all trajectories, hence obtaining a synchronous data set.
For example, here we interpolate trajectories in xt
to times c(1, 1.5, 2, 2.5)
(the observation times of entity ‘3’) to obtain a synchronous data set:
The following trajectory plots show the effect of interpolation visually:
Trajectory centering removes differences in (e.g. initial or overall) position between trajectories, without changing their shape, to focus on the direction of temporal changes.
The following trajectory plots show the effect of centering visually:
Trajectories may contain variation that is considered noise, for whatever reason (e.g. measurement error). Similarly to univariate smoothing of temporal series, noise can be smoothed out in trajectory data.
Temporal smoothing of trajectories done using function smoothTrajectories()
, which applies a multivariate moving average over each trajectory and uses a Gaussian kernel to specify average weights.
The following plots illustrate the effect of smoothing:
M.C. Escher - Waterfall, 1961