Skip to contents

combined_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 track R 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 similarity and/or track intersection R 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
#>