| Type: | Package |
| Title: | Hierarchical Signal Detection Theory Models for Unconscious Processing |
| Version: | 0.1.0 |
| Description: | Fits hierarchical signal detection theory (SDT) models to paired direct and indirect measures, the design used to test for unconscious processing. Continuous indirect measures (typically response times) are dichotomized with the within-subject median split of Meyen et al. (2022) <doi:10.1037/xge0001065> so that both tasks are placed on a common sensitivity scale. The package estimates a binomial probit mixed model in which the two sensitivities are correlated random effects, and tests the three hypotheses of interest: the group-level difference between sensitivities, their latent correlation, and the latent regression of the indirect on the direct measure, whose intercept is the test for unconscious processing. Frequentist estimation uses 'lme4'. |
| License: | GPL-3 |
| Encoding: | UTF-8 |
| LazyData: | true |
| LazyDataCompression: | xz |
| Depends: | R (≥ 4.1) |
| Imports: | stats, utils, lme4, ggplot2, rlang |
| Suggests: | testthat (≥ 3.0.0), knitr, rmarkdown |
| VignetteBuilder: | knitr |
| Config/testthat/edition: | 3 |
| Config/Needs/website: | pkgdown |
| URL: | https://github.com/RicardoReySaez/uSDT, https://ricardoreysaez.github.io/uSDT/ |
| BugReports: | https://github.com/RicardoReySaez/uSDT/issues |
| Config/roxygen2/version: | 8.1.0 |
| NeedsCompilation: | no |
| Packaged: | 2026-09-18 17:31:16 UTC; 34653 |
| Author: | Ricardo Rey-Sáez |
| Maintainer: | Ricardo Rey-Sáez <ricardoreysaez95@gmail.com> |
| Repository: | CRAN |
| Date/Publication: | 2026-09-29 13:40:02 UTC |
uSDT: Hierarchical Signal Detection Theory for Unconscious Processing
Description
Fits hierarchical signal detection theory models to paired direct and indirect measures. This is the design used to test whether a stimulus is processed without awareness.
The workflow
-
usdt_data_long()orusdt_data_tasks()prepare the data. Printing the result reports how every column was read, which tasks were split at the median, and what the model will do with all of it. -
sdt_moments()gives descriptive estimates for each subject. -
hsdt()fits the model and tests the three hypotheses. -
plot()andusdt_reliability()help to interpret the fit, andusdt_boot()adds intervals by simulation when the model needs them.
The three hypotheses
- H1
The difference between the average sensitivities of the two tasks.
- H2
The correlation between the two sensitivities across subjects.
- H3
The regression of the indirect sensitivity on the direct one. Its intercept is the sensitivity expected in the indirect task from a subject whose direct sensitivity is zero, which is the test for unconscious processing.
Confidence intervals
H1 and the regression of H3 use Wald intervals. The correlation of H2 uses a Fisher-z interval, so its limits stay between -1 and 1. When the model reaches a boundary and an interval becomes unreliable, the package reports it as unavailable and explains why.
Author(s)
Maintainer: Ricardo Rey-Sáez ricardoreysaez95@gmail.com (ORCID)
Authors:
Ricardo Rey-Sáez ricardoreysaez95@gmail.com (ORCID)
Francisco Garre-Frutos fgfrutos@gmail.com (ORCID)
Alicia Franco-Martínez aliciafranco96@gmail.com (ORCID)
Miguel Vadillo mgl.vadillo@gmail.com (ORCID)
See Also
Useful links:
Report bugs at https://github.com/RicardoReySaez/uSDT/issues
Fit a hierarchical signal detection theory model
Description
Fits a bivariate hierarchical SDT model using lme4::glmer() and evaluates
the core unconscious processing hypotheses. The model estimates task-specific
sensitivities (d') and response criteria (c) as fixed effects,
while estimating their variation and correlation across participants via
random effects.
Usage
hsdt(
data,
estimation = c("frequentist"),
fix_criteria = c("auto", "none"),
level = 0.95,
optimizer = "bobyqa",
...
)
## S3 method for class 'hsdt'
summary(object, ...)
## S3 method for class 'hsdt'
print(x, ...)
Arguments
data |
A |
estimation |
Estimation framework. Currently only |
fix_criteria |
How to handle response criteria. |
level |
Confidence level for Wald intervals (default is 0.95). |
optimizer |
Primary optimizer passed to |
... |
Additional arguments passed to |
object |
An |
x |
An |
Details
The model fits trial counts with a binomial probit link, directly mapping coefficients to standard Signal Detection Theory parameters. Fixed effects capture population sensitivities and criteria, while random effects estimate participant variation and the latent correlation between direct and indirect sensitivity.
Hypotheses evaluated by default:
-
H1: Mean sensitivity difference between tasks.
-
H2: Latent correlation of sensitivities across participants.
-
H3: Latent regression of indirect on direct sensitivity. Its intercept reflects expected indirect performance when direct awareness is zero (
d'_{\mathrm{Direct}} = 0).
When sample sizes or trial counts are low, variance components can reach
singular boundaries. In these cases, the function issues a warning, and
parametric bootstrap intervals can be calculated using usdt_boot().
Value
An object of class hsdt containing:
-
$fit: The underlyingglmerModobject fromlme4. -
$tests: Summary table for hypotheses H1, H2, and H3. -
$pars: Model parameter estimates on the SDT scale. -
$design: Summary of the model specification and formula. -
$diagnostics: Convergence flags and singular fit indicators.
See Also
usdt_data_tasks(), usdt_tests(), usdt_boot(), plot.hsdt()
Examples
# Contextual cuing data from Vadillo et al. (2025)
d <- usdt_data_tasks(
direct = vadillo_awareness,
indirect = vadillo_cuing,
subject_col = "subj",
condition_col = "condition",
condition_levels = c(signal = "old", noise = "new"),
response_col = list(direct = "judged.old", indirect = "rt"),
response_levels = list(direct = c(signal = 1, noise = 0),
indirect = c(signal = "faster", noise = "slower")),
dichotomize = list(direct = FALSE, indirect = TRUE)
)
m <- hsdt(d)
# Full summary table with SDT parameters and hypothesis tests
summary(m)
# Inspect the model formula (indirect criterion omitted by default)
m$design$formula
Dichotomize response times into binary choices
Description
Splits response times (or other continuous measures) at each subject's
overall median, following the preprocessing approach of Meyen et al. (2022).
The median is calculated across all trials for each participant without
distinguishing between stimulus conditions or other covariates. This produces
a binary outcome that allows response times to be mapped onto a Signal
Detection Theory sensitivity metric (d').
Usage
meyen_split(x, by, signal = c("faster", "slower"), ties = c("noise", "random"))
Arguments
x |
Numeric vector of continuous values, typically response times. |
by |
Vector identifying the subject for each observation in |
signal |
Character string specifying which side of the median will be
treated as the "signal" response under an SDT framework. Use |
ties |
How to handle trials that match the subject's median exactly.
|
Details
With an odd number of trials (n), a dataset cannot be split into two
equal halves because the median falls exactly on an observed trial.
Setting ties = "noise" assigns this middle trial to noise, producing a
signal proportion of (n - 1) / (2\cdot n) and slightly shifting the response
criterion. In practice, this difference (1 / (2\cdot n)) is negligible, but
setting ties = "random" resolves ties probabilistically to avoid any
systematic directional bias.
Value
An integer vector of 0s (noise response) and 1s (signal response)
matching the length of x. Missing values (NA) are preserved.
References
Meyen, S., Zerweck, I. A., Amado, C., von Luxburg, U., & Franz, V. H. (2022). Advancing research on unconscious priming: When can scientists claim an indirect task advantage? Journal of Experimental Psychology: General, 151(1), 65–81. doi:10.1037/xge0001065
Examples
rt <- c(320, 410, 295, 500, 380, 450)
subj <- rep(c("s1", "s2"), each = 3)
meyen_split(rt, by = subj)
Diagnostic and analytical plots for hierarchical SDT models
Description
Generates diagnostic visualizations for a fitted hierarchical SDT model, including observed versus latent regression (H3), shrinkage patterns, participant-level caterpillar intervals, and model-implied ROC curves.
Usage
## S3 method for class 'hsdt'
plot(
x,
type = c("regression", "shrinkage", "caterpillar", "roc"),
subject_id = NULL,
band = TRUE,
population_reference = TRUE,
observed_se = NULL,
...
)
Arguments
x |
An |
type |
Character string indicating the plot type:
|
subject_id |
Identifier for a specific participant when |
band |
Logical. Show confidence bands around regression lines or ROC
curves (default is |
population_reference |
Logical. When plotting an individual ROC curve, add population-average curves as dashed reference lines. |
observed_se |
Variance formulation for empirical intervals in
|
... |
Additional arguments passed to underlying plotting methods. |
Value
A ggplot object. Its underlying data frame is stored in $data.
Regression plot (type = "regression")
Compares observed and latent associations across two panels sharing axes.
The left panel shows observed d' values and an ordinary least-squares
line. When direct task reliability is low, trial-level sampling noise
attenuates this observed slope toward zero. The right panel plots the latent
regression line (d'_I on d'_D) from H3, correcting for
measurement error. The value of each line at d'_D = 0 marks the
intercept testing for unconscious processing, and both panels display it the
same way: an open circle at the point estimate with a vertical line spanning
its confidence interval. The observed marker is the least-squares intercept
and the latent marker is its measurement-error-corrected counterpart, so the
two panels place the same hypothesis side by side. Confidence bands are
computed via the delta method or bootstrap replicates when usdt_boot() is
present.
Shrinkage plot (type = "shrinkage")
Connects each participant's observed d' (from sdt_moments() with Hautus
correction) to their model-implied d'. The lower the reliability of the
measures, the higher the shrinkage of observed estimates toward the
group-level mean.
Caterpillar plot (type = "caterpillar")
Plots observed d' and model-implied d' with confidence intervals
for every participant. Empirical intervals use normal approximations based
on observed_se. Model-implied intervals incorporate uncertainty from
population means, variance components, and participant random effects.
ROC plot (type = "roc")
Displays model-implied ROC curves for an average participant or a specific individual, with points marking the estimated response criteria.
See Also
hsdt(), sdt_moments(), usdt_boot()
Examples
# Contextual cuing data from Vadillo et al. (2025)
d <- usdt_data_tasks(
direct = vadillo_awareness,
indirect = vadillo_cuing,
subject_col = "subj",
condition_col = "condition",
condition_levels = c(signal = "old", noise = "new"),
response_col = list(direct = "judged.old", indirect = "rt"),
response_levels = list(direct = c(signal = 1, noise = 0),
indirect = c(signal = "faster", noise = "slower")),
dichotomize = list(direct = FALSE, indirect = TRUE)
)
fit <- hsdt(d)
# 1. Observed vs. latent regression (H3)
plot(fit, type = "regression")
# 2. Bivariate shrinkage toward the group mean
plot(fit, type = "shrinkage")
# 3. Participant-level intervals (observed vs. model-implied)
plot(fit, type = "caterpillar")
# 4. Model-implied ROC curves
plot(fit, type = "roc")
plot(fit, type = "roc", subject_id = "2001", population_reference = TRUE)
Signal detection measures for each subject
Description
Computes empirical hit rates, false-alarm rates, sensitivity (d'), and
response criteria for each participant without fitting a model. It can also
calculate sampling variances, standard errors, and expected values for
d'.
Usage
sdt_moments(
data,
subject_col = NULL,
condition_col = NULL,
condition_levels = NULL,
response_col = NULL,
response_levels = NULL,
coding = c("deviation", "treatment"),
correction = c("hautus", "none"),
variances = FALSE
)
Arguments
data |
A |
subject_col, condition_col, response_col |
Column names for subject,
condition, and response variables. Only required when |
condition_levels, response_levels |
Named vectors mapping condition and
response labels, like |
coding |
Criterion definition to report: |
correction |
Handling of extreme rates (0 or 1) that make |
variances |
Logical. If |
Details
Edge corrections apply only to participants with extreme rates (0 or 1) rather than the whole sample, leaving well-defined rates unchanged.
When requested, the sampling variance of d' is estimated using the
asymptotic approximation of Gourevitch and Galanter (1967) and the
binomial-distribution approach of Miller (1996). See Suero et al. (2017)
for a comparison between the two approaches.
Value
A data frame with one row per subject (or per subject and task for
usdt_data inputs) containing:
-
hit,miss,fa,cr: Raw response counts. -
hr,far: Observed hit and false-alarm rates. -
zhr,zfar: Probit-transformed rates. -
dprime,criterion: Descriptive SDT estimates. -
corrected: Logical flag indicating whether the participant received an edge correction. -
var_gg,se_gg: Asymptotic variance and standard error from Gourevitch and Galanter (1967), present whenvariances = TRUE. -
var_miller,se_miller,expected_dprime: Moments from Miller (1996), present whenvariances = TRUE.
References
Gourevitch, V., & Galanter, E. (1967). A significance test for one parameter isosensitivity functions. Psychometrika, 32(1), 25–33. doi:10.1007/BF02289402
Hautus, M. J. (1995). Corrections for extreme proportions and their biasing
effects on estimated values of d'. Behavior Research Methods,
Instruments, & Computers, 27(1), 46–51. doi:10.3758/BF03203619
Miller, J. (1996). The sampling distribution of d'. Perception &
Psychophysics, 58(1), 65–72. doi:10.3758/BF03205476
Suero, M., Privado, J., & Botella, J. (2017). Methods to estimate the variance of some indices of the signal detection theory: A simulation study. Psicologica, 38(1), 77–109.
See Also
Examples
# 1. From a prepared usdt_data object (both tasks at once)
d <- usdt_data_tasks(
direct = vadillo_awareness,
indirect = vadillo_cuing,
subject_col = "subj",
condition_col = "condition",
condition_levels = c(signal = "old", noise = "new"),
response_col = list(direct = "judged.old", indirect = "rt"),
response_levels = list(direct = c(signal = 1, noise = 0),
indirect = c(signal = "faster", noise = "slower")),
dichotomize = list(direct = FALSE, indirect = TRUE)
)
head(sdt_moments(d))
# 2. From raw trials with sampling variances and standard errors
head(sdt_moments(vadillo_awareness,
subject_col = "subj",
condition_col = "condition",
condition_levels = c(signal = "old", noise = "new"),
response_col = "judged.old",
response_levels = c(signal = 1, noise = 0),
variances = TRUE))
Parametric bootstrap intervals for hierarchical SDT models
Description
Simulates new datasets from a fitted model using lme4::bootMer(), refits
the model to each replicate, and computes bootstrap confidence intervals
for the three core hypotheses (H1, H2, H3). This is especially useful when
asymptotic Wald intervals are unreliable due to singular or boundary fits.
Usage
usdt_boot(
object,
nsim = 1000,
ncores = 1L,
max_attempts = 2 * nsim,
seed = NULL,
progress = interactive(),
level = 0.95,
type = c("perc", "norm", "basic")
)
Arguments
object |
An |
nsim |
Target number of successful replicates (at least 500). |
ncores |
Number of CPU cores for parallel processing. Values above 1 create a temporary cluster that works across Windows, macOS, and Linux, and automatically stops when finished. |
max_attempts |
Maximum number of refits to attempt. Defaults to
|
seed |
Random seed for reproducibility. With the default |
progress |
Logical. Display a progress bar during fitting (defaults to
|
level |
Confidence level for intervals (default is 0.95). |
type |
Type of bootstrap interval: |
Details
Replicates are dropped only if the model fails to fit or does not converge. Singular fits and boundary estimates are intentionally retained because discarding them artificially narrows intervals in constrained settings.
When an attempted run finishes with fewer than 500 usable replicates, the
original Wald intervals are preserved, a warning is issued, and raw
attempt diagnostics are stored in $boot.
Point estimates remain identical to the original model fit. Two-sided
bootstrap p-values compare the observed test statistic against the
centered bootstrap distribution using standard finite-sample adjustment
((k + 1) / (B + 1)), ensuring p-values never equal zero.
Value
An updated hsdt object where interval columns in $tests are
replaced by bootstrap estimates. A new $boot element contains:
-
$t: Matrix of replicates for the three hypotheses. -
$variance: Replicates of sensitivity variances. -
$population: Replicates of average criteria and sensitivities. -
$subjects: Replicates of individual-level parameters. Run diagnostics and convergence counts (
usable,attempted,retained,failures).
See Also
Examples
# Contextual cuing data from Vadillo et al. (2025)
d <- usdt_data_tasks(
direct = vadillo_awareness,
indirect = vadillo_cuing,
subject_col = "subj",
condition_col = "condition",
condition_levels = c(signal = "old", noise = "new"),
response_col = list(direct = "judged.old", indirect = "rt"),
response_levels = list(direct = c(signal = 1, noise = 0),
indirect = c(signal = "faster", noise = "slower")),
dichotomize = list(direct = FALSE, indirect = TRUE)
)
m <- hsdt(d)
# Run parametric bootstrap with 500 replicates. Refitting this model 500
# times takes several minutes
b <- usdt_boot(m, nsim = 500, seed = 1)
# Inspect updated summary with bootstrap intervals and p-values
summary(b)
# Check fit diagnostics across bootstrap replicates
b$boot[c("usable", "attempted", "retained", "failures")]
Prepare data for hierarchical SDT models
Description
Formats direct and indirect task data into a standardized structure for
hsdt(). Use usdt_data_tasks() when tasks are stored in separate data
frames, or usdt_data_long() when both tasks are kept in a single data frame
with a column that identifies each task.
Usage
usdt_data_tasks(
direct,
indirect,
subject_col,
condition_col = NULL,
condition_levels = NULL,
response_col = NULL,
response_levels = NULL,
successes_col = NULL,
trials_col = NULL,
successes_type = c("auto", "counts", "proportions"),
sdt_cols = NULL,
dichotomize = c("none", "indirect", "direct", "both"),
ties = c("noise", "random"),
coding = c("deviation", "treatment"),
labels = c(direct = "Direct", indirect = "Indirect")
)
usdt_data_long(
data,
task_col,
task_levels,
subject_col,
condition_col = NULL,
condition_levels = NULL,
response_col = NULL,
response_levels = NULL,
successes_col = NULL,
trials_col = NULL,
successes_type = c("auto", "counts", "proportions"),
sdt_cols = NULL,
dichotomize = c("none", "indirect", "direct", "both"),
ties = c("noise", "random"),
coding = c("deviation", "treatment"),
labels = NULL
)
## S3 method for class 'usdt_data'
print(x, ...)
Arguments
direct, indirect |
Data frames for each task (used in |
subject_col |
Name of the column that identifies participants. |
condition_col |
Name of the column for signal and noise conditions.
Not needed when using |
condition_levels |
Named vector mapping condition labels, like
|
response_col |
Name of the column with responses. Can be binary choices or continuous values (like response times) to split at the median. |
response_levels |
Named vector mapping responses, like
|
successes_col, trials_col |
Names of columns with pre-calculated counts
or proportions of signal responses and total trials. Use these instead of
|
successes_type |
Format of |
sdt_cols |
Named vector for SDT table columns, like
|
dichotomize |
Which tasks to split at the median using |
ties |
How to handle trials that fall exactly on the median.
See |
coding |
How condition is coded in the model: |
labels |
Optional names for the tasks in printed output. |
data |
A single data frame with both tasks (used in |
task_col |
Name of the column that identifies the task in |
task_levels |
Named vector mapping task labels, like
|
x |
A |
... |
Ignored. |
Details
The functions count responses for each subject and condition, check that the same subjects appear in both tasks, and print a summary table so you can verify the column settings before fitting the model.
Value
An object of class usdt_data. The $agg table contains the counts
used by hsdt(), and $meta contains setup details and summaries.
Settings per task
Arguments for columns and levels take either a single value (used for both tasks) or a list with separate settings for each task:
condition_col = list(direct = "cond", indirect = "cue")
condition_levels = list(direct = c(signal = "old", noise = "new"),
indirect = c(signal = "congruent", noise = "incongruent"))
dichotomize = list(direct = FALSE, indirect = TRUE)
This works for all column and level arguments, so you can combine trial-level data in one task with summary tables in the other.
Condition coding
Under "deviation" coding (-0.5 vs. +0.5), the intercept is -c, the
criterion measured from the point between the two distributions. Under
"treatment" coding (0 vs. 1), the intercept is z(\mathrm{FAR}), the
criterion measured from the noise distribution.
When a task is split at the median, deviation coding sets the group criterion to zero in balanced designs, so the model does not need to estimate it.
See Also
hsdt(), meyen_split(), sdt_moments()
Examples
# 1. Tasks in separate data frames
# Direct task: binary choices (old/new)
# Indirect task: response times (split at the median)
d_separate <- usdt_data_tasks(
direct = vadillo_awareness,
indirect = vadillo_cuing,
subject_col = "subj",
condition_col = "condition",
condition_levels = c(signal = "old", noise = "new"),
response_col = list(direct = "judged.old", indirect = "rt"),
response_levels = list(direct = c(signal = 1, noise = 0),
indirect = c(signal = "faster", noise = "slower")),
dichotomize = list(direct = FALSE, indirect = TRUE)
)
d_separate
# 2. Tasks combined in a single long data frame
long <- rbind(
data.frame(task = "D",
subj = vadillo_awareness$subj,
condition = vadillo_awareness$condition,
response = vadillo_awareness$judged.old),
data.frame(task = "I",
subj = vadillo_cuing$subj,
condition = vadillo_cuing$condition,
response = vadillo_cuing$rt)
)
d_long <- usdt_data_long(
long,
task_col = "task",
task_levels = c(direct = "D", indirect = "I"),
subject_col = "subj",
condition_col = "condition",
condition_levels = c(signal = "old", noise = "new"),
response_col = "response",
response_levels = list(direct = c(signal = 1, noise = 0),
indirect = c(signal = "faster", noise = "slower")),
dichotomize = list(direct = FALSE, indirect = TRUE)
)
d_long
Test the three core hypotheses of a hierarchical SDT model
Description
Evaluates the difference between average task sensitivities (H1), their
correlation across subjects (H2), and the regression of indirect sensitivity
on direct sensitivity (H3). usdt_tests() computes all three together,
while individual functions compute them separately.
Usage
usdt_tests(fit, direct = "d_D", indirect = "d_I", level = 0.95)
sensitivity_diff(fit, direct = "d_D", indirect = "d_I", level = 0.95)
latent_cor(fit, direct = "d_D", indirect = "d_I", level = 0.95)
latent_regression(fit, direct = "d_D", indirect = "d_I", level = 0.95)
Arguments
fit |
A fitted model: an |
direct, indirect |
Character strings naming the sensitivity terms in the
model. Defaults match the internal naming of |
level |
Confidence level for intervals (default is 0.95). |
Details
These tests run automatically inside hsdt() and appear in its summary.
Calling them directly is especially useful when fitting custom models with
lme4::glmer(), allowing you to test these hypotheses while controlling for
additional covariates (e.g., set size, experimental groups).
Value
A data frame with columns term, estimate, se, statistic,
p.value, conf.low, conf.high, and ci_method. Columns status and
reason flag unsupported estimates (e.g., singular fits). usdt_tests()
includes an extra hypothesis column (H1, H2, H3).
The three hypotheses
-
H1 (Mean difference): Tests whether average sensitivity differs between the direct and indirect tasks.
-
H2 (Correlation): Tests the correlation between task sensitivities across participants using a Fisher-
ztransformed interval. -
H3 (Latent regression): Regresses indirect sensitivity onto direct sensitivity. The intercept represents expected indirect performance when direct sensitivity is zero (
d'_{\mathrm{Direct}} = 0), testing for unconscious processing.
Because both the correlation (H2) and regression slope (H3) are zero if and only if the covariance between sensitivities is zero, they evaluate the same association and share identical test statistics.
Custom models with covariates
To adjust tests for additional factors, specify the model directly using
lme4::glmer(). As long as the two sensitivity terms are included as fixed
effects and correlated across subjects via random slopes, usdt_tests() will
compute the latent tests conditional on those covariates.
See Also
Examples
# 1. Standard model via hsdt()
d <- usdt_data_tasks(
direct = vadillo_awareness,
indirect = vadillo_cuing,
subject_col = "subj",
condition_col = "condition",
condition_levels = c(signal = "old", noise = "new"),
response_col = list(direct = "judged.old", indirect = "rt"),
response_levels = list(direct = c(signal = 1, noise = 0),
indirect = c(signal = "faster", noise = "slower")),
dichotomize = list(direct = FALSE, indirect = TRUE)
)
m <- hsdt(d)
# All three tests at once
usdt_tests(m)
# Or one test at a time
sensitivity_diff(m) # H1
latent_cor(m) # H2
latent_regression(m) # H3
# 2. Custom model with covariates via glmer()
# Controlling for display set size across both tasks
trials <- rbind(
data.frame(vadillo_awareness[c("subj", "condition", "set.size")],
task = "D", resp = vadillo_awareness$judged.old),
data.frame(vadillo_cuing[c("subj", "condition", "set.size")],
task = "I", resp = meyen_split(vadillo_cuing$rt,
by = vadillo_cuing$subj))
)
# Deviation contrasts (-0.5 vs 0.5); `direct` flags the direct task
trials <- within(trials, {
cond <- ifelse(condition == "old", 0.5, -0.5)
size <- ifelse(set.size == "set size 16", 0.5, -0.5)
direct <- as.integer(task == "D")
})
# Standard glmer formula: indirect criterion is omitted (fixed at 0
# by the median split). Random effects estimate the direct criterion
# and correlated task sensitivities across subjects.
fit <- lme4::glmer(
resp ~ 0 + direct + task:size + task:cond +
(0 + direct | subj) + (0 + task:cond | subj),
data = trials, family = binomial("probit"),
control = lme4::glmerControl(optimizer = "bobyqa")
)
# Check the names lme4 assigned to the sensitivity terms
names(lme4::fixef(fit))
# Evaluate hypotheses conditional on set size
usdt_tests(fit, direct = "taskD:cond", indirect = "taskI:cond")
Reliability of direct and indirect task measures
Description
Estimates the reliability of sensitivity (d') by separating true
variance across participants from sampling noise caused by finite trial counts.
Values close to 1 indicate that the measure reliably separates participants,
whereas values near 0 indicate that observed differences are mostly
measurement error.
Usage
usdt_reliability(object)
## S3 method for class 'usdt_reliability'
summary(object, ...)
## S3 method for class 'usdt_reliability'
print(x, ...)
Arguments
object |
An |
... |
Ignored. |
x |
A |
Details
For participant i in task j, reliability is defined as:
\frac{\tau_j^2}{\tau_j^2 + v_{ij}}
where \tau_j^2 is the true variance in sensitivity across participants
from the model's random effects, and v_{ij} is the squared standard
error of d' for that participant. This error variance reflects how
precisely their trials determine sensitivity, accounting for trial count,
performance level on the probit curve, and uncertainty in the criterion.
This variance is calculated using the large-sample Fisher information formula
from Gourevitch and Galanter (1967). Unlike sdt_moments(), which evaluates
that formula at raw empirical proportions (var_gg), usdt_reliability()
evaluates it at the response probabilities predicted by the fitted
hierarchical model.
Overall task reliability averages v_{ij} across participants,
representing the expected proportion of true variance for a participant
drawn at random from the sample.
When object includes bootstrap replicates from usdt_boot(), confidence
intervals for reliability are computed automatically across all retained
samples.
Value
An object of class usdt_reliability containing:
-
$tasks: Overall reliability and variance components for each task. -
$subjects: Participant-leveld', error variances, and individual reliabilities. Bootstrap intervals for both components when available in
object.
References
Gourevitch, V., & Galanter, E. (1967). A significance test for one parameter isosensitivity functions. Psychometrika, 32(1), 25–33. doi:10.1007/BF02289402
See Also
hsdt(), usdt_boot(), sdt_moments()
Examples
# Contextual cuing data from Vadillo et al. (2025)
d <- usdt_data_tasks(
direct = vadillo_awareness,
indirect = vadillo_cuing,
subject_col = "subj",
condition_col = "condition",
condition_levels = c(signal = "old", noise = "new"),
response_col = list(direct = "judged.old", indirect = "rt"),
response_levels = list(direct = c(signal = 1, noise = 0),
indirect = c(signal = "faster", noise = "slower")),
dichotomize = list(direct = FALSE, indirect = TRUE)
)
r <- usdt_reliability(hsdt(d))
r
# Participant-level estimates (one row per subject and task)
head(r$subjects)
Awareness data from a probabilistic cuing experiment
Description
Trial-level direct-awareness data from Experiment 2 of Vadillo et al.
(2025). The object reproduces the source CSV file without filtering or
recoding and can be used as the direct input to usdt_data_tasks().
Usage
vadillo_awareness
Format
A data frame with 6,656 rows, 104 participants, and 10 variables:
subjParticipant identifier.
fileOriginal participant file name.
trialTrial number.
pattIdPattern identifier.
judgmAwareness judgement on the original response scale.
judged.oldWhether the pattern was judged old (1) or new (0).
conditionWhether the pattern was old or new.
offsetSpatial-offset condition.
colorColour condition.
set.sizeSet-size condition.
Source
Vadillo, M. A., Malejka, S., & Shanks, D. R. (2025). Mapping the reliability multiverse of contextual cuing. Journal of Experimental Psychology: Learning, Memory, and Cognition. doi:10.1037/xlm0001410. Data retrieved from https://osf.io/jp3gx/.
Examples
data(vadillo_awareness)
str(vadillo_awareness)
Cuing data from a probabilistic cuing experiment
Description
Trial-level indirect-task data from Experiment 2 of Vadillo et al. (2025).
The object reproduces the source CSV file without filtering or recoding and
can be used as the indirect input to usdt_data_tasks().
Usage
vadillo_cuing
Format
A data frame with 39,936 rows, 104 participants, and 13 variables:
experimentExperiment label.
subjParticipant identifier.
fileOriginal participant file name.
trialTrial number.
blockBlock number.
epochEpoch number.
pattIdPattern identifier.
accResponse accuracy (1 = correct, 0 = incorrect).
rtResponse time in milliseconds.
conditionWhether the pattern was old or new.
offsetSpatial-offset condition.
colorColour condition.
set.sizeSet-size condition.
Source
Vadillo, M. A., Malejka, S., & Shanks, D. R. (2025). Mapping the reliability multiverse of contextual cuing. Journal of Experimental Psychology: Learning, Memory, and Cognition. doi:10.1037/xlm0001410. Data retrieved from https://osf.io/jp3gx/.
Examples
data(vadillo_cuing)
str(vadillo_cuing)