The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Guide for AI agents

This guide is written for an AI agent asked to analyse directional data with radiatR, and for the person checking its work. It states the conventions the package uses, how it fails, and the mistakes that are easy to make. Every code chunk below is run when the package is built.

Two ways in

Start from trajectories when you have tracking output (x/y positions over time) and need one heading per track, or from a table of angles when the headings have already been measured.

sim <- as.data.frame(simulate_tracks(seed = 1, n_points = 50))
path <- tempfile(fileext = ".csv")
write.csv(sim, path, row.names = FALSE)

ts <- read_tracks(
  path,
  mapping   = list(id = "trial_id", time = "frame", x = "abs_x", y = "abs_y"),
  time_type = "frames",
  fps       = 30,
  keep      = "condition"
)
hd <- derive_headings(ts, rule = "distal", carry = "condition")
head(hd, 3)
#> # A tibble: 3 × 4
#>   id           time heading condition
#>   <chr>       <dbl>   <dbl> <chr>    
#> 1 control_001    50    5.90 control  
#> 2 control_002    50    5.80 control  
#> 3 control_003    49    5.84 control
bearings <- data.frame(bearing = c(10, 20, 350, 5), site = c("a", "a", "b", "b"))
hf <- headings_frame(bearings, col = "bearing", units = "degrees",
                     angle_convention = "clock")
hf
#> # A tibble: 4 × 2
#>   bearing site 
#>     <dbl> <chr>
#> 1    1.40 a    
#> 2    1.22 a    
#> 3    1.75 b    
#> 4    1.48 b

Angle conventions

circ_summarise(hd, col = "heading", units = "radians", .by = "condition")
#> # A tibble: 3 × 6
#>   condition     n mean_dir mean_dir_deg resultant_R kappa
#>   <chr>     <int>    <dbl>        <dbl>       <dbl> <dbl>
#> 1 control      20   0.0125         89.3       0.929  7.31
#> 2 high         20   5.66          126.        0.670  1.83
#> 3 moderate     20   0.687          50.6       0.928  7.20

State the convention whenever you report a direction.

Coordinates and calibration

Heading rules that use a radius (crossing, exit, entry, ring_tangent, distal with max_radius) read radii in the units of the coordinates the Tracks object holds. Decide how those coordinates relate to the arena before choosing a rule.

Map every column yourself

Time

Failures are information

radiatR stops rather than guessing. Read the error; do not work around it.

Condition class Meaning
radiatR_invalid_rows x/y missing or non-finite; the error lists rows and ids
radiatR_malformed_values a column holds values that are not numeric; lists rows and values, and suggested_decimal when they look written with the other decimal mark
radiatR_ambiguous_decimal a ; file’s sniffed decimal point is shown only outside the role columns, which hold values like 1.234 (1.234 or 1234?); pass read_opts = list(decimal = ) (also raised when no data row of the first 20 lines is whole)
radiatR_invalid_tracks the data break a Tracks invariant (see ?tracks)
radiatR_invalid_argument an argument cannot be used as given (for read_opts: an unknown entry, a bad decimal mark, or an option the dialect cannot use; option names it)
radiatR_nonestimable a statistic cannot be estimated for a group
radiatR_dropped_rows warning raised when on_invalid = "drop" removed rows
radiatR_attrition message from the deeplabcut, sleap, ethovision and anymaze dialects: the points masked at load and the rows left without a position (kept in @meta$attrition; not the heading attrition of the next section)
radiatR_dialect_error a dialect cannot read the file as that program’s output; the message says why

Heading rules and attrition

derive_headings() returns one row per track (some rules can return more). When a rule yields no heading for a track, the row is kept with NA and the result carries n_total and n_missing (headings, i.e. rows), n_trials (distinct trials) and missing_ids (each trial with a missing heading, once) attributes. on_missing controls what else happens: "warn" (the default) raises a warning, "error" stops, "quiet" says nothing. The ransac_straight rule draws random numbers, so call set.seed() before it.

attr(hd, "n_total")
#> [1] 60
attr(hd, "n_missing")
#> [1] 0

Attrition is often not random: a track that never reaches a ring has no crossing heading, and those animals may differ from the rest. Report n_missing alongside any statistic, and do not switch rules silently to recover the missing tracks.

Tests

set.seed(1)
test_uniformity(hd, group_col = "condition", angle_col = "heading")
#>   condition statistic      p_value  n     test
#> 1   control 0.9289411 5.069033e-08 20 rayleigh
#> 2      high 0.6697242 4.300494e-05 20 rayleigh
#> 3  moderate 0.9277095 5.207452e-08 20 rayleigh
test_mean_directions(hd, group_col = "condition", angle_col = "heading")
#>   n_groups statistic df1 df2      p_value            test
#> 1        3  22.91549   2  57 4.976226e-08 Watson-Williams

Pitfalls

  1. Reporting mean_dir_deg as if it were counter-clockwise from East.
  2. Treating normalize_xy = TRUE as calibration.
  3. Forgetting keep / carry, or misspelling a name in them, then finding the grouping column is gone.
  4. Using on_invalid = "drop" without saying how many rows were dropped.
  5. Ignoring n_missing after derive_headings().
  6. Giving radii to a heading rule in the wrong units.
  7. Reporting a resampling p-value without a seed.
  8. Catching an error and carrying on with a different method.
  9. Letting read_tracks() guess an angle or weight column from its name.

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.