Skip to contents

This vignette defines the main workflow used throughout AccumulatR. Read it first if you want the package vocabulary before moving to the task-specific examples.

## 
## Attaching package: 'AccumulatR'
## The following object is masked from 'package:stats':
## 
##     simulate

The basic workflow

Most workflows in AccumulatR follow the same four steps:

  1. Define a model with accumulators, pools, and observed responses.
  2. Finalize that model with finalize_model().
  3. Work with behavioral data, either simulated with simulate() or collected in an experiment.
  4. Prepare the data, build a model context, and evaluate candidate parameter values.

Core ideas

Trial

A trial is a single behavioral observation. In the simplest case, each row of your data corresponds to one trial.

R

R is the observed response label on a trial. For a two-choice task, typical values might be "left" and "right", or "red" and "green", etc.

rt

rt is the observed response time for R.

Component

A component serves two purposes. It can be used to account for different trial types in your data, for example when a subset of your data requires different accumulator structures. It can also be used to allow for latent mixtures within trial. If your model has only one trial type, you usually do not need this column. See also the Working with Mixtures vignette.

Onset

An onset is the time at which an accumulator becomes active. Most accumulators start at time 0, while in some cases, extra information appears during the trial. In AccumulatR, an onset can be:

  • a fixed delay, such as onset = 0.15
  • a chained onset, such as onset = after("A"), meaning the process starts only after another accumulator (in this case A) or pool has finished

Both onset and non-decision time (t0) shift response times. The difference in AccumulatR is that t0 is an estimated parameter, whereas onset is part of the model structure.

A minimal model

The example below defines a basic two-choice race model with two lognormal accumulators.

model <- race_spec() |>
  add_accumulator("left", "lognormal") |>
  add_accumulator("right", "lognormal") |>
  add_outcome("left", "left") |>
  add_outcome("right", "right") |>
  finalize_model()

Simulated behavioral data

We can generate a small behavioral dataset from this model. Here build_param_matrix makes one row of parameters per trial. This allows you to trial-wise manipulate the specific parameters, for example using a design matrix specification.

pars <- c(
  left.m = log(0.28), left.s = 0.16,
  right.m = log(0.35), right.s = 0.18
)

param_df <- build_param_matrix(model, pars, n_trials = 6)
sim <- simulate(model, param_df, seed = 123)

head(sim)
##   trial     R        rt
## 1     1  left 0.3182631
## 2     2  left 0.3414185
## 3     3  left 0.2883234
## 4     4  left 0.3669476
## 5     5  left 0.3057125
## 6     6 right 0.2456584

Each row is one trial, R is the observed response, and rt is the response time.

From behavioral data to likelihood

To fit a model, the usual pattern is:

prepared <- prepare_data(model, sim[c("trial", "R", "rt")])
ctx <- make_context(model)
log_likelihood(ctx, prepared, param_df)
## [1] 5.291506

prepare_data() reshapes the behavioral data for likelihood evaluation, and make_context() builds the model-side runtime state. log_likelihood() returns the fit of a parameter set to those observed data.