
Standardized vendor-neutral gaze data-quality metrics
standardized_spatial_quality.RdCompute and report separable eye-tracking quality dimensions: target-referenced accuracy, RMS sample-to-sample precision, spatial standard-deviation precision, BCEA, effective sampling behavior, sampling jitter, valid-data fraction, and data loss. User thresholds create review flags only and never trigger automatic exclusion.
Usage
validate_gaze_quality_inputs(data, x = "gaze_x", y = "gaze_y", time = NULL,
target_x = NULL, target_y = NULL, by = NULL, unit = "degrees",
time_unit = "ms", unit_column = NULL)
compute_gaze_accuracy(data, x = "gaze_x", y = "gaze_y",
target_x = "target_x", target_y = "target_y", by = NULL,
unit = "degrees", output_unit = NULL, geometry = NULL)
compute_rms_s2s(data, x = "gaze_x", y = "gaze_y", time = NULL, by = NULL,
unit = "degrees", output_unit = NULL, geometry = NULL,
dimension = c("2d", "horizontal", "vertical"), time_unit = "ms",
max_gap_ms = NULL)
compute_gaze_sd_precision(data, x = "gaze_x", y = "gaze_y", by = NULL,
unit = "degrees", output_unit = NULL, geometry = NULL)
compute_bcea(data, x = "gaze_x", y = "gaze_y", by = NULL,
probability = 0.68, unit = "degrees", output_unit = NULL,
geometry = NULL)
compute_gaze_precision(data, x = "gaze_x", y = "gaze_y", time = NULL,
by = NULL, probability = 0.68, unit = "degrees", output_unit = NULL,
geometry = NULL, dimension = "2d", time_unit = "ms", max_gap_ms = NULL)
estimate_sampling_interval(data, time = "timestamp_ms", by = NULL,
time_unit = "ms")
estimate_sampling_jitter(data, time = "timestamp_ms", by = NULL,
time_unit = "ms")
estimate_effective_sampling_rate(data, time = "timestamp_ms", by = NULL,
time_unit = "ms", nominal_sampling_hz = NULL,
dropped_interval_factor = 1.5, x = NULL, y = NULL, valid = NULL)
compute_valid_sample_fraction(data, x = "gaze_x", y = "gaze_y",
valid = NULL, by = NULL)
compute_gaze_data_loss(data, x = "gaze_x", y = "gaze_y",
time = "timestamp_ms", valid = NULL, missing_reason = NULL,
by = NULL, time_unit = "ms")
summarise_spatial_quality(data, x = "gaze_x", y = "gaze_y",
target_x = "target_x", target_y = "target_y", time = NULL, by = NULL,
unit = "degrees", output_unit = NULL, geometry = NULL,
dimension = "2d", time_unit = "ms", max_gap_ms = NULL,
probability = 0.68)
summarise_sampling_quality(data, time = "timestamp_ms", by = NULL,
time_unit = "ms", nominal_sampling_hz = NULL,
dropped_interval_factor = 1.5, x = NULL, y = NULL, valid = NULL)
create_gaze_quality_report(data, x = "gaze_x", y = "gaze_y",
time = "timestamp_ms", target_x = "target_x", target_y = "target_y",
valid = NULL, missing_reason = NULL, by = NULL, unit = "degrees",
output_unit = NULL, geometry = NULL, time_unit = "ms",
nominal_sampling_hz = NULL, bcea_probability = 0.68,
max_gap_ms = NULL, thresholds = NULL, preprocessing_spec = NULL,
event_detector = NULL, aoi_specification = NULL, quality_rules = NULL,
model_specification = NULL, software_version = NULL,
unit_column = NULL)
compare_gaze_quality_sessions(data, session = "session_id", by = NULL, ...)
compare_gaze_quality_conditions(data, condition = "condition", by = NULL, ...)
plot_gaze_accuracy(report, metric = "accuracy_mean", ...)
plot_gaze_precision(report, metric = "precision_rms_s2s", ...)
plot_bcea(report, ...)
plot_sampling_intervals(data, time = "timestamp_ms", time_unit = "ms", ...)
plot_gaze_quality_dashboard(report, ...)
report_gaze_quality(report, digits = 3L)
simulate_gaze_quality_calibration(seed = 20260918L,
samples_per_target = 18L, nominal_sampling_hz = 60)Arguments
- data
A data frame or object coercible to a data frame.
- x, y
Columns containing horizontal and vertical gaze coordinates.
- time
Timestamp column.
- target_x, target_y
Known validation-target coordinate columns.
- by
Optional grouping columns defining the quality-analysis unit.
- unit
Input coordinate unit:
"degrees","pixels", or"normalized".- output_unit
Optional explicit output coordinate unit. No conversion occurs when omitted.
- geometry
Named screen/viewing geometry used only for explicit coordinate conversion.
- time_unit
Timestamp unit: seconds, milliseconds, microseconds, or nanoseconds.
- unit_column
Optional column used to reject mixed or conflicting coordinate units. For the canonical report, an existing
coordinate_unitcolumn is detected automatically when this argument is omitted.- dimension
RMS-S2S dimension: two-dimensional, horizontal, or vertical.
- max_gap_ms
Optional explicit maximum interval permitted for an adjacent-sample RMS pair.
- probability, bcea_probability
Probability region used for BCEA.
- nominal_sampling_hz
Optional nominal hardware rate used for comparison and dropped-interval diagnostics.
- dropped_interval_factor
Multiple of the nominal interval used to count long intervals.
- valid
Optional explicit validity column. Missing gaze coordinates remain unavailable regardless of this flag.
- missing_reason
Optional loss-reason column such as blink, tracker invalidity, or off-screen.
- thresholds
Optional named study-specific review thresholds; these never exclude data automatically.
- preprocessing_spec, event_detector, aoi_specification, quality_rules, model_specification, software_version
Optional provenance fields preserved on the canonical report.
- session, condition
Grouping column used for convenience comparisons.
- report
A quality-report-like data frame.
- metric
Metric column plotted by a focused quality plot.
- digits
Number of digits in the compact reporting string.
- seed
Deterministic synthetic-data seed.
- samples_per_target
Synthetic samples generated at each of nine validation targets.
- ...
Additional arguments forwarded to the canonical report or base plotting function.
Details
Accuracy is target-referenced error. RMS-S2S precision quantifies adjacent-sample fluctuation and never bridges a missing sample. Spatial SD and BCEA quantify point-cloud spread around a stable target and use population standard deviations (denominator \(n\)). BCEA always records its probability level.
Effective sampling frequency is estimated from the effective sample count divided
by an estimated recording duration (timestamp span plus one median positive
inter-sample interval). When gaze coordinates and validity are supplied, the
effective sample count contains valid gaze observations with finite timestamps;
otherwise the metric describes the timestamp stream. With a nominal rate,
long_interval_count counts intervals exceeding the declared nominal-gap
multiple, whereas dropped_interval_count estimates the number of missing
nominal samples represented by those long intervals.
The package deliberately does not impose universal acceptability cutoffs. A
gaze_quality_report stores review flags and provenance while preserving all
analysis units for downstream filtering, weighting, stratification, sensitivity
analysis, and transparent reporting.
Value
Metric functions return data frames with explicit units and diagnostics.
create_gaze_quality_report() returns a data frame of class
gaze_quality_report with a gaze_quality_provenance attribute.
Plot functions draw base-R diagnostics and invisibly return the plotted data.
report_gaze_quality() returns a compact character summary.
simulate_gaze_quality_calibration() returns a deterministic synthetic
nine-point validation data set spanning six quality profiles.
References
Dunn, M. J., et al. (2024). A minimal reporting guideline for eye-tracking studies. Behavior Research Methods.
Niehorster, D. C., et al. (2026). How to determine the quality of eye-tracking data: A tutorial. Behavior Research Methods. doi:10.3758/s13428-026-03039-4.
Examples
d <- simulate_gaze_quality_calibration(samples_per_target = 4)
q <- create_gaze_quality_report(
d,
by = c("profile", "target_id"),
valid = "valid",
missing_reason = "missing_reason",
nominal_sampling_hz = 60
)
head(q[c(
"profile", "target_id", "accuracy_mean", "precision_rms_s2s",
"bcea", "effective_sampling_hz", "data_loss_fraction"
)])
#> profile target_id accuracy_mean precision_rms_s2s bcea
#> 1 missingness 1 0.3385511 0.4586771 0.32314661
#> 2 missingness 2 0.2567571 0.4603552 0.17342363
#> 3 missingness 3 0.2884298 0.3774378 0.20977189
#> 4 missingness 4 0.2610593 0.4301536 0.19541697
#> 5 missingness 5 0.2288653 0.2539276 0.09689068
#> 6 missingness 6 0.3642338 0.3385071 0.07407507
#> effective_sampling_hz data_loss_fraction
#> 1 60 0
#> 2 60 0
#> 3 60 0
#> 4 60 0
#> 5 60 0
#> 6 60 0
report_gaze_quality(q)
#> [1] "accuracy_mean: mean 0.643, range 0.094-1.969; precision_rms_s2s: mean 0.597, range 0.112-2.220; precision_sd: mean 0.368, range 0.080-1.229; bcea: mean 0.578, range 0.004-3.320; effective_sampling_hz: mean 60.180, range 45.174-89.438; valid_sample_fraction: mean 1.000, range 1.000-1.000; data_loss_fraction: mean 0.000, range 0.000-0.000. Review required for 0/54 analysis units. Thresholds, when supplied, are study-specific review rules and never trigger automatic exclusion."