
Calculate combined probabilities of similarity or intersection metrics of tracks
Source:R/combined_prob.R
combined_prob.Rdcombined_prob() calculates the combined probabilities of similarity and intersection metrics
derived from different models. The function uses simulation data to extract p-values, providing insight into
the significance of combined metrics across various similarity assessments.
Usage
combined_prob(data, metrics = NULL, H1 = c("Higher", "Lower"))Arguments
- data
A
trackR object, which is a list consisting of two elements:Trajectories: A list of interpolated trajectories, where each trajectory is a series of midpoints between consecutive footprints.Footprints: A list of data frames containing footprint coordinates, metadata (e.g., image reference, ID), and a marker indicating whether the footprint is actual or inferred.
- metrics
A list of
track similarityand/ortrack intersectionR objects derived from different tests. All tests must be based on the same number of simulations.- H1
Alternative hypothesis for intersection metrics. One of
"Higher"or"Lower".
Value
A list containing:
- P_values
A matrix of raw p-values for the combined metrics across all trajectories (pairwise).
- P_values_BH
A matrix of BH-adjusted p-values for the combined metrics (pairwise).
- P_values_global
A single numeric value: the overall probability of observing the combined metrics across all pairs of trajectories.
Details
The combined_prob() function combines evidence from multiple trajectory-based
metrics, including distance-based similarity measures (e.g., DTW and Fréchet)
and intersection metrics, using simulation-based hypothesis testing.
For distance-based similarity metrics (such as DTW and Fréchet), smaller values indicate greater similarity between trajectories. Accordingly, pairwise p-values are computed using a lower-tail Monte Carlo test with the (+1) correction (Phipson & Smyth, 2010): $$p = (1 + \#\{D_{sim} \le D_{obs}\}) / (nsim + 1)$$ This tests whether the observed trajectories are at least as similar as expected under the null model of random movement.
For intersection metrics, the direction of the test depends on the alternative
hypothesis specified by H1. When H1 = "Lower", the test evaluates
whether the observed number of intersections is significantly lower than expected
under random simulations (e.g., coordinated or gregarious movement). When
H1 = "Higher", the test evaluates whether the observed number of intersections
is significantly higher than expected (e.g., chasing or predatory interactions).
Combined pairwise p-values are obtained by jointly evaluating all metrics across simulations, identifying those simulation replicates in which all metrics are simultaneously as extreme as the observed values, given their respective directions. A Monte Carlo test with the (+1) correction is used, and the resulting pairwise p-values are adjusted for multiple comparisons using the Benjamini–Hochberg (BH) procedure.
In addition, a global combined p-value is computed based on a single global statistic summarizing all pairwise comparisons, providing an overall assessment of whether the observed set of trajectories departs from random expectations across all metrics considered.
Author
Humberto G. Ferrón
humberto.ferron@uv.es
Macroevolution and Functional Morphology Research Group (www.macrofun.es)
Cavanilles Institute of Biodiversity and Evolutionary Biology
Calle Catedrático José Beltrán Martínez, nº 2
46980 Paterna - Valencia - Spain
Phone: +34 (9635) 44477
Examples
# Example 1: "Directed" model and similarity metrics.
s1 <- simulate_track(PaluxyRiver, nsim = 3, model = "Directed")
DTW1 <- simil_DTW_metric(PaluxyRiver, test = TRUE, sim = s1, superposition = "None")
#> 2026-04-04 16:16:42.925902 Iteration 1
#>
#> DTW metric
#> Track_1 Track_2
#> Track_1 NA 7.767709
#> Track_2 7.767709 NA
#> ------------------------------------
#> 2026-04-04 16:16:42.934478 Iteration 2
#>
#> DTW metric
#> Track_1 Track_2
#> Track_1 NA 10.91272
#> Track_2 10.91272 NA
#> ------------------------------------
#> 2026-04-04 16:16:42.943 Iteration 3
#>
#> DTW metric
#> Track_1 Track_2
#> Track_1 NA 9.99559
#> Track_2 9.99559 NA
#> ------------------------------------
#> ANALYSIS COMPLETED
#> ------------------------------------
#>
Frechet1 <- simil_Frechet_metric(PaluxyRiver, test = TRUE, sim = s1, superposition = "None")
#> 2026-04-04 16:16:43.486838 Iteration 1
#>
#> Frechet metric
#> Track_1 Track_2
#> Track_1 NA 0.7781548
#> Track_2 0.7781548 NA
#> ------------------------------------
#> 2026-04-04 16:16:43.728622 Iteration 2
#>
#> Frechet metric
#> Track_1 Track_2
#> Track_1 NA 0.7738161
#> Track_2 0.7738161 NA
#> ------------------------------------
#> 2026-04-04 16:16:43.974806 Iteration 3
#>
#> Frechet metric
#> Track_1 Track_2
#> Track_1 NA 0.7933628
#> Track_2 0.7933628 NA
#> ------------------------------------
#> ANALYSIS COMPLETED
#> ------------------------------------
#>
int1 <- track_intersection(PaluxyRiver, test = TRUE, H1 = "Lower", sim = s1,
origin.permutation = "None")
#> 2026-04-04 16:16:44.002182 Iteration 1
#>
#> Intersect metric
#> ------------------------------------
#> 2026-04-04 16:16:44.014334 Iteration 2
#>
#> Intersect metric
#> ------------------------------------
#> 2026-04-04 16:16:44.026613 Iteration 3
#>
#> Intersect metric
#> ------------------------------------
#> ANALYSIS COMPLETED
#> ------------------------------------
#>
combined_prob(PaluxyRiver, metrics = list(DTW1, Frechet1, int1), H1 = "Lower")
#> $P_values
#> Track_1 Track_2
#> Track_1 NA 0.5
#> Track_2 0.5 NA
#>
#> $P_values_BH
#> Track_1 Track_2
#> Track_1 NA 0.5
#> Track_2 0.5 NA
#>
#> $P_values_global
#> [1] 0.5
#>
# Example 2: "Constrained" model and similarity metrics.
s2 <- simulate_track(PaluxyRiver, nsim = 3, model = "Constrained")
DTW2 <- simil_DTW_metric(PaluxyRiver, test = TRUE, sim = s2,
superposition = "None")
#> 2026-04-04 16:16:44.057747 Iteration 1
#>
#> DTW metric
#> Track_1 Track_2
#> Track_1 NA 67.17671
#> Track_2 67.17671 NA
#> ------------------------------------
#> 2026-04-04 16:16:44.070761 Iteration 2
#>
#> DTW metric
#> Track_1 Track_2
#> Track_1 NA 34.32521
#> Track_2 34.32521 NA
#> ------------------------------------
#> 2026-04-04 16:16:44.08859 Iteration 3
#>
#> DTW metric
#> Track_1 Track_2
#> Track_1 NA 11.66344
#> Track_2 11.66344 NA
#> ------------------------------------
#> ANALYSIS COMPLETED
#> ------------------------------------
#>
Frechet2 <- simil_Frechet_metric(PaluxyRiver, test = TRUE, sim = s2,
superposition = "None")
#> 2026-04-04 16:16:44.501922 Iteration 1
#>
#> Frechet metric
#> Track_1 Track_2
#> Track_1 NA 3.765697
#> Track_2 3.765697 NA
#> ------------------------------------
#> 2026-04-04 16:16:44.727737 Iteration 2
#>
#> Frechet metric
#> Track_1 Track_2
#> Track_1 NA 3.752331
#> Track_2 3.752331 NA
#> ------------------------------------
#> 2026-04-04 16:16:44.995156 Iteration 3
#>
#> Frechet metric
#> Track_1 Track_2
#> Track_1 NA 0.9129333
#> Track_2 0.9129333 NA
#> ------------------------------------
#> ANALYSIS COMPLETED
#> ------------------------------------
#>
int2 <- track_intersection(PaluxyRiver, test = TRUE, H1 = "Lower", sim = s2,
origin.permutation = "Min.Box")
#> 2026-04-04 16:16:45.538649 Permutation 1
#>
#> Permutation of coordinates at origin using Min.Box
#> ------------------------------------
#> 2026-04-04 16:16:46.046699 Permutation 2
#>
#> Permutation of coordinates at origin using Min.Box
#> ------------------------------------
#> 2026-04-04 16:16:46.141823 Permutation 3
#>
#> Permutation of coordinates at origin using Min.Box
#> ------------------------------------
#> PERMUTATION COMPLETED
#> ------------------------------------
#>
#> 2026-04-04 16:16:46.163103 Iteration 1
#>
#> Intersect metric
#> ------------------------------------
#> 2026-04-04 16:16:46.180478 Iteration 2
#>
#> Intersect metric
#> ------------------------------------
#> 2026-04-04 16:16:46.192868 Iteration 3
#>
#> Intersect metric
#> ------------------------------------
#> ANALYSIS COMPLETED
#> ------------------------------------
#>
combined_prob(PaluxyRiver, metrics = list(DTW2, Frechet2, int2), H1 = "Lower")
#> $P_values
#> Track_1 Track_2
#> Track_1 NA 0.25
#> Track_2 0.25 NA
#>
#> $P_values_BH
#> Track_1 Track_2
#> Track_1 NA 0.25
#> Track_2 0.25 NA
#>
#> $P_values_global
#> [1] 0.25
#>
# Example 3: "Unconstrained" model and similarity metrics.
s3 <- simulate_track(PaluxyRiver, nsim = 3, model = "Unconstrained")
DTW3 <- simil_DTW_metric(PaluxyRiver, test = TRUE, sim = s3,
superposition = "None")
#> 2026-04-04 16:16:46.234676 Iteration 1
#>
#> DTW metric
#> Track_1 Track_2
#> Track_1 NA 27.66064
#> Track_2 27.66064 NA
#> ------------------------------------
#> 2026-04-04 16:16:46.248598 Iteration 2
#>
#> DTW metric
#> Track_1 Track_2
#> Track_1 NA 300.0043
#> Track_2 300.0043 NA
#> ------------------------------------
#> 2026-04-04 16:16:46.261459 Iteration 3
#>
#> DTW metric
#> Track_1 Track_2
#> Track_1 NA 109.3543
#> Track_2 109.3543 NA
#> ------------------------------------
#> ANALYSIS COMPLETED
#> ------------------------------------
#>
Frechet3 <- simil_Frechet_metric(PaluxyRiver, test = TRUE, sim = s3,
superposition = "None")
#> 2026-04-04 16:16:46.761032 Iteration 1
#>
#> Frechet metric
#> Track_1 Track_2
#> Track_1 NA 1.54771
#> Track_2 1.54771 NA
#> ------------------------------------
#> 2026-04-04 16:16:46.784996 Iteration 2
#>
#> Frechet metric
#> Track_1 Track_2
#> Track_1 NA -1
#> Track_2 -1 NA
#> ------------------------------------
#> 2026-04-04 16:16:46.986209 Iteration 3
#>
#> Frechet metric
#> Track_1 Track_2
#> Track_1 NA 9.937678
#> Track_2 9.937678 NA
#> ------------------------------------
#> ANALYSIS COMPLETED
#> ------------------------------------
#>
int3 <- track_intersection(PaluxyRiver, test = TRUE, H1 = "Lower", sim = s3,
origin.permutation = "Conv.Hull")
#> 2026-04-04 16:16:47.148365 Permutation 1
#>
#> Permutation of coordinates at origin using Conv.Hull
#> ------------------------------------
#> 2026-04-04 16:16:47.269573 Permutation 2
#>
#> Permutation of coordinates at origin using Conv.Hull
#> ------------------------------------
#> 2026-04-04 16:16:47.358233 Permutation 3
#>
#> Permutation of coordinates at origin using Conv.Hull
#> ------------------------------------
#> PERMUTATION COMPLETED
#> ------------------------------------
#>
#> 2026-04-04 16:16:47.372714 Iteration 1
#>
#> Intersect metric
#> ------------------------------------
#> 2026-04-04 16:16:47.384526 Iteration 2
#>
#> Intersect metric
#> ------------------------------------
#> 2026-04-04 16:16:47.396372 Iteration 3
#>
#> Intersect metric
#> ------------------------------------
#> ANALYSIS COMPLETED
#> ------------------------------------
#>
combined_prob(PaluxyRiver, metrics = list(DTW3, Frechet3, int3), H1 = "Lower")
#> $P_values
#> Track_1 Track_2
#> Track_1 NA 0.25
#> Track_2 0.25 NA
#>
#> $P_values_BH
#> Track_1 Track_2
#> Track_1 NA 0.25
#> Track_2 0.25 NA
#>
#> $P_values_global
#> [1] 0.25
#>
