| Title: | Inattention Detection Pipeline for Psychophysical Tasks |
|---|---|
| Description: | Three-stage pipeline for detecting inattention episodes in long psychophysical tasks (200+ trials). Uses accuracy residuals and response pattern signals to locate, sharpen, and formally test candidate inattention regions at trial-level precision. |
| Authors: | Pawel Lenartowicz [aut, cre] (ORCID: <https://orcid.org/0000-0002-6906-7217>), Maja Willard [aut] (ORCID: <https://orcid.org/0009-0005-3482-1119>) |
| Maintainer: | Pawel Lenartowicz <[email protected]> |
| License: | GPL (>= 3) |
| Version: | 0.1.0 |
| Built: | 2026-05-13 23:10:44 UTC |
| Source: | https://github.com/cran/inough |
Returns a data frame of all trials flagged by the detection pipeline,
suitable for downstream filtering via dplyr::anti_join or similar.
flags(x)flags(x)
x |
An |
Data frame with columns id, trial_idx,
flag_type ("bailout" or "chunk"), chunk_id
(integer, NA for bailout), p_adj (numeric, NA for
bailout).
Pipeline tuning parameters
inough_control( lz_threshold = 0.2, window_size = 3, sd_threshold = 2, window_weight = "uniform", min_chunk = 6, comparison = "clean" )inough_control( lz_threshold = 0.2, window_size = 3, sd_threshold = 2, window_weight = "uniform", min_chunk = 6, comparison = "clean" )
lz_threshold |
LZ complexity below this triggers bail-out (default 0.2). |
window_size |
Half-width of rolling window; total window = 2*w+1 (default 3, giving 7-trial windows). |
sd_threshold |
Number of SDs above chance that |
window_weight |
Weighting scheme for the rolling window:
|
min_chunk |
Minimum chunk length in trials to retain after merging (default 6). |
comparison |
t-test comparison set: |
An inough_control object with a pre-computed
screening_threshold based on sd_threshold and the window.
Two-stage pipeline: (1) dual-track screening with chunk filtering, (2) formal t-test with FDR correction. Participants with extremely stereotyped responses or chance-level accuracy are bailed out first.
inough_detect( signals, fdr_alpha = 0.2, control = inough_control(), heuristics = inough_heuristics() )inough_detect( signals, fdr_alpha = 0.2, control = inough_control(), heuristics = inough_heuristics() )
signals |
An |
fdr_alpha |
FDR significance level for BH correction (default 0.05). |
control |
An |
heuristics |
An |
An inough_detected object.
Configures optional refinements applied after chunk screening: boundary extension mode and spurious-accuracy trimming.
inough_heuristics( boundary_mode = "heuristic", spurious = TRUE, spurious_n = 6L, spurious_k = NULL, min_left = 7L )inough_heuristics( boundary_mode = "heuristic", spurious = TRUE, spurious_n = 6L, spurious_k = NULL, min_left = 7L )
boundary_mode |
How to extend chunk boundaries after detection:
|
spurious |
Logical; enable spurious-start accuracy trimming
(default |
spurious_n |
Number of trials at chunk start to inspect (default 6). |
spurious_k |
Explicit threshold: flag if |
min_left |
Minimum trials remaining after spurious trimming (default 7). Chunks shorter than this after trimming are dropped. |
An inough_heuristics object.
Fits a probit GLMM on accuracy and computes response bias indicators.
This is the first step in the inough pipeline: call inough_signals,
then pass the result to inough_detect.
inough_signals( df, correct, response, id = "ID", learning_effect = TRUE, participant_effect = TRUE, trial_transform = "sqrt" )inough_signals( df, correct, response, id = "ID", learning_effect = TRUE, participant_effect = TRUE, trial_transform = "sqrt" )
df |
A data frame with rows ordered by trial within each participant. |
correct |
Formula. LHS names the accuracy column (0/1 integer). RHS
names design predictors that explain correctness (e.g.,
|
response |
Formula identifying the response column. Use a two-sided
formula where the RHS names the column (e.g., |
id |
String naming the participant identifier column (default
|
learning_effect |
Logical. If |
participant_effect |
Logical. If |
trial_transform |
Transformation applied to trial index before rescaling
to [-1, 1]. One of |
An inough_signals object.
Computes the normalized LZ76 complexity of a binary sequence. Higher values indicate more random/complex sequences; lower values indicate more predictable/repetitive patterns.
lz_complexity(x)lz_complexity(x)
x |
Integer vector of 0s and 1s. |
Numeric scalar in \[0, 1\]. Normalized complexity where 1 = maximally complex (random) and values near 0 = highly predictable.
lz_complexity(c(0, 0, 0, 0, 0)) # low lz_complexity(c(0, 1, 0, 1, 0, 1)) # low-medium lz_complexity(sample(0:1, 100, TRUE)) # near 1lz_complexity(c(0, 0, 0, 0, 0)) # low lz_complexity(c(0, 1, 0, 1, 0, 1)) # low-medium lz_complexity(sample(0:1, 100, TRUE)) # near 1
Produces a stacked 4-panel visualization: accuracy strip, accuracy residuals, lag-1 response, and dual-track z-scores. Flagged chunks are highlighted as red shaded regions.
## S3 method for class 'inough_detected' plot(x, id, ...)## S3 method for class 'inough_detected' plot(x, id, ...)
x |
An |
id |
Character scalar — participant ID to plot. |
... |
Ignored. |
A patchwork object (invisibly).
Creates a self-contained HTML file with a participant browser, diagnostic plots, chunk details, and summary statistics.
report(x, ...) ## S3 method for class 'inough_detected' report(x, file = NULL, custom_plot = NULL, ...)report(x, ...) ## S3 method for class 'inough_detected' report(x, file = NULL, custom_plot = NULL, ...)
x |
An |
... |
Arguments passed to methods. |
file |
Output file path. If |
custom_plot |
Optional per-trial variable to show as an extra panel in the participant view. A list with three fields:
|
Invisibly returns the file path.
A minimal anonymized subset of the Dual Task (Gabor orientation under motor interference) dataset, intended for demonstrating the inough pipeline. Twenty participants were sampled to span a range of attention profiles: clean performers, two bail-out cases (one for response stereotypy, one for chance-level accuracy), participants with localized inattention chunks, and participants with extended inattention periods.
task_exampletask_example
A data frame with one row per trial and the following columns:
Anonymized participant identifier (factor,
P01–P20).
Block index within the session (integer, >= 1;
practice block excluded).
Trial index within the participant's session (integer).
Stimulus identifier (integer).
Stimulus weight / contrast (numeric).
Gabor orientation code (integer).
Cue type code (integer).
Participant's response (integer, two unique values).
Trial accuracy (integer, 0 or 1).
Participant identifiers have been replaced with arbitrary codes
(P01–P20) and any session timing information has been
removed.
A subset of the Dual Task (s_9) data collected in the
COST/Kraken consciousness study (Krakow site). Participant IDs have
been re-coded for anonymity.
data(task_example) head(task_example) signals <- inough_signals( task_example, correct = correct ~ stim + weight + orient + cue_type + block, response = response ~ response, id = "participant" ) det <- inough_detect(signals) summary(det)data(task_example) head(task_example) signals <- inough_signals( task_example, correct = correct ~ stim + weight + orient + cue_type + block, response = response ~ response, id = "participant" ) det <- inough_detect(signals) summary(det)