Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HLCtools

HLCtools calculates Herd Lying Concordance (HLC) metrics from individual animal lying-behaviour data.

HLC is a framework for quantifying group-level behavioural cohesion. It uses the distribution of individual lying behaviour within each observation interval to estimate how similarly animals are behaving as a group.

Author, affiliation, and citation

HLCtools is developed by Guilherme Amorim Franchi at Aarhus University.

The package provides tools for calculating Herd Lying Concordance metrics from individual animal lying-behaviour data. HLC is intended as a flexible framework for quantifying group-level behavioural cohesion from sensor-derived activity records.

If you use HLCtools, please cite the package:

citation("HLCtools")
#> To cite package 'HLCtools' in publications use:
#> 
#>   Amorim Franchi G (2026). _HLCtools: Calculate Herd Lying Concordance
#>   Metrics_. R package version 0.1.0. Developed at Aarhus University.,
#>   <https://github.com/guilhermefranchi/HLCtools>.
#> 
#> A BibTeX entry for LaTeX users is
#> 
#>   @Manual{,
#>     title = {HLCtools: Calculate Herd Lying Concordance Metrics},
#>     author = {Guilherme {Amorim Franchi}},
#>     year = {2026},
#>     note = {R package version 0.1.0. Developed at Aarhus University.},
#>     institution = {Aarhus University},
#>     url = {https://github.com/guilhermefranchi/HLCtools},
#>   }

Concept

Traditional threshold-based synchrony metrics classify an interval as synchronous when a fixed proportion of animals are lying, for example 70%. HLC takes a different approach: it calculates group cohesion continuously from between-animal dispersion.

The package currently supports:

  • HLC_SD: standard-deviation-based HLC
  • HLC_MAD: mean-absolute-deviation-based HLC
  • HLC_IQR: interquartile-range-based HLC
  • HLC_ENT: entropy-based HLC

The package also calculates lying-weighted HLC, which combines group cohesion with the proportion of the interval spent lying.

Installation

# Development version
# install.packages("remotes")
# remotes::install_github("your-github-username/HLCtools")

Example data

data(example_lies)

example_lies
#>    group day week  time  cow lying
#> 1      A   1    1 00:00 cow1    15
#> 2      A   1    1 00:15 cow2    15
#> 3      A   1    1 00:00 cow3    15
#> 4      A   1    1 00:15 cow4    15
#> 5      A   1    1 00:00 cow5    15
#> 6      A   1    1 00:15 cow1     0
#> 7      A   1    1 00:00 cow2     0
#> 8      A   1    1 00:15 cow3     0
#> 9      A   1    1 00:00 cow4     0
#> 10     A   1    1 00:15 cow5     0
#> 11     A   2    1 00:00 cow1    15
#> 12     A   2    1 00:15 cow2    15
#> 13     A   2    1 00:00 cow3    15
#> 14     A   2    1 00:15 cow4     0
#> 15     A   2    1 00:00 cow5     0
#> 16     A   2    1 00:15 cow1    15
#> 17     A   2    1 00:00 cow2     0
#> 18     A   2    1 00:15 cow3    15
#> 19     A   2    1 00:00 cow4     0
#> 20     A   2    1 00:15 cow5    15
#> 21     B   1    1 00:00 cow1    15
#> 22     B   1    1 00:15 cow2    15
#> 23     B   1    1 00:00 cow3    10
#> 24     B   1    1 00:15 cow4    10
#> 25     B   1    1 00:00 cow5    15
#> 26     B   1    1 00:15 cow1    15
#> 27     B   1    1 00:00 cow2    12
#> 28     B   1    1 00:15 cow3    15
#> 29     B   1    1 00:00 cow4     8
#> 30     B   1    1 00:15 cow5    15
#> 31     B   2    1 00:00 cow1     0
#> 32     B   2    1 00:15 cow2     0
#> 33     B   2    1 00:00 cow3     5
#> 34     B   2    1 00:15 cow4     0
#> 35     B   2    1 00:00 cow5     0
#> 36     B   2    1 00:15 cow1     0
#> 37     B   2    1 00:00 cow2    15
#> 38     B   2    1 00:15 cow3     0
#> 39     B   2    1 00:00 cow4    15
#> 40     B   2    1 00:15 cow5     0

Calculate interval-level HLC

hlc_intervals <- calculate_hlc(
  data = example_lies,
  group = group,
  animal = cow,
  day = day,
  period = week,
  interval = time,
  lying = lying,
  interval_min = 15,
  methods = c("sd", "mad", "iqr", "entropy"),
  sync_thresholds = c(0.6, 0.7, 0.8, 0.9),
  add_lying_weighted = TRUE
)

hlc_intervals
#> # A tibble: 8 × 24
#>   group   day  week time  n_animals mean_lying lying_prop sd_lying mad_lying
#>   <chr> <int> <dbl> <chr>     <int>      <dbl>      <dbl>    <dbl>     <dbl>
#> 1 A         1     1 00:00         5          9      0.6       7.35       7.2
#> 2 A         1     1 00:15         5          6      0.4       7.35       7.2
#> 3 A         2     1 00:00         5          6      0.4       7.35       7.2
#> 4 A         2     1 00:15         5         12      0.8       6          4.8
#> 5 B         1     1 00:00         5         12      0.8       2.76       2.4
#> 6 B         1     1 00:15         5         14      0.933     2          1.6
#> 7 B         2     1 00:00         5          7      0.467     6.78       6.4
#> 8 B         2     1 00:15         5          0      0         0          0  
#> # ℹ 15 more variables: iqr_lying <dbl>, p_lying <dbl>, HLC_SD <dbl>,
#> #   HLC_MAD <dbl>, HLC_IQR <dbl>, entropy_raw <dbl>, HLC_ENT <dbl>,
#> #   sync60 <int>, sync70 <int>, sync80 <int>, sync90 <int>, HLC_SD_LYING <dbl>,
#> #   HLC_MAD_LYING <dbl>, HLC_IQR_LYING <dbl>, HLC_ENT_LYING <dbl>

Summarise HLC by day

hlc_daily <- summarise_hlc_daily(
  data = hlc_intervals,
  group = group,
  day = day,
  period = week,
  interval_min = 15
)

hlc_daily
#> # A tibble: 4 × 19
#>   group   day  week mean_HLC_SD mean_HLC_MAD mean_HLC_IQR mean_HLC_ENT
#>   <chr> <int> <dbl>       <dbl>        <dbl>        <dbl>        <dbl>
#> 1 A         1     1      0.0202       0.0400        0           0.0290
#> 2 A         2     1      0.110        0.2           0.5         0.154 
#> 3 B         1     1      0.683        0.733         0.833       1     
#> 4 B         2     1      0.548        0.573         0.5         0.515 
#> # ℹ 12 more variables: mean_HLC_SD_LYING <dbl>, mean_HLC_MAD_LYING <dbl>,
#> #   mean_HLC_IQR_LYING <dbl>, mean_HLC_ENT_LYING <dbl>, sync60_time_min <dbl>,
#> #   sync70_time_min <dbl>, sync80_time_min <dbl>, sync90_time_min <dbl>,
#> #   mean_lying_min_interval <dbl>, mean_lying_prop <dbl>, n_intervals <int>,
#> #   mean_n_animals <dbl>

Rank HLC methods for a dataset

Different datasets may favour different HLC implementations. HLCtools therefore provides a descriptive ranking helper.

rank_hlc_methods(
  data = hlc_daily,
  group = group,
  period = week,
  lying_prop = mean_lying_prop
)
#>    method metric_column n_total n_non_missing pct_missing      mean        sd
#> 1  HLC_SD   mean_HLC_SD       4             4           0 0.3402575 0.3244934
#> 2 HLC_MAD  mean_HLC_MAD       4             4           0 0.3866667 0.3214781
#> 3 HLC_ENT  mean_HLC_ENT       4             4           0 0.4242837 0.4355433
#> 4 HLC_IQR  mean_HLC_IQR       4             4           0 0.4583333 0.3435921
#>      median        min       max n_unique pct_boundary zero_variance
#> 1 0.3289734 0.02020410 0.6828793        4            0         FALSE
#> 2 0.3866667 0.04000000 0.7333333        4            0         FALSE
#> 3 0.3340427 0.02904941 1.0000000        4           25         FALSE
#> 4 0.5000000 0.00000000 0.8333333        3           25         FALSE
#>   high_boundary_collapse degeneracy_score detectability_F detectability_p
#> 1                  FALSE                0       46.014560      0.02104854
#> 2                  FALSE                0       22.222222      0.04217371
#> 3                  FALSE                0        7.062389      0.11721597
#> 4                  FALSE                0        1.923077      0.29985996
#>    delta_AIC temporal_sd outlier_sensitivity outlier_distance_from_1
#> 1 10.7134285         NaN           0.8296094               0.1703906
#> 2  7.9764932         NaN           0.8131274               0.1868726
#> 3  4.0439423         NaN           1.2102363               0.2102363
#> 4  0.6949164         NaN           1.3904983               0.3904983
#>   lying_prop_spearman rank_detectability rank_temporal_stability
#> 1           0.4000000                  1                      NA
#> 2           0.4000000                  2                      NA
#> 3           0.4000000                  3                      NA
#> 4           0.6324555                  4                      NA
#>   rank_outlier_robustness rank_boundary rank_missingness rank_degeneracy
#> 1                       1           1.5              2.5             2.5
#> 2                       2           1.5              2.5             2.5
#> 3                       3           3.5              2.5             2.5
#> 4                       4           3.5              2.5             2.5
#>   n_ranked_criteria weighted_rank_score selected
#> 1                 5                 1.7     TRUE
#> 2                 5                 2.1    FALSE
#> 3                 5                 2.9    FALSE
#> 4                 5                 3.3    FALSE
#>                         recommendation_note
#> 1 Selected/ranked under available criteria.
#> 2 Selected/ranked under available criteria.
#> 3 Selected/ranked under available criteria.
#> 4 Selected/ranked under available criteria.

The ranking is based on available criteria such as group detectability, temporal stability, outlier robustness, boundary values, and missingness. The result should support transparent method selection, not replace biological interpretation.

Available methods

hlc_methods()
#> [1] "sd"      "mad"     "iqr"     "entropy"

Interpretation

Unweighted HLC describes group-level behavioural cohesion. It can be high when animals are uniformly lying or uniformly standing.

Lying-weighted HLC describes cohesive lying specifically. It is calculated by multiplying interval-level HLC by the mean lying proportion in that interval.

Thus:

  • high HLC + high lying-weighted HLC = cohesive collective lying;
  • high HLC + low lying-weighted HLC = cohesive behaviour, but not mainly lying;
  • low HLC = fragmented group behaviour.

Current scope

HLCtools computes HLC metrics. It does not automatically decide which dispersion basis is universally best. The choice of SD, MAD, IQR, entropy, or another implementation should depend on the dataset, biological question, group size, sampling interval, and intended application.

About

❗ This is a read-only mirror of the CRAN R package repository. HLCtools — Calculate Herd Lying Concordance Metrics. Homepage: https://github.com/guilhermefranchi/HLCtools Report bugs for this package: https://github.com/guilhermefranchi/HLCtools/issues

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages