| Title: | Design Matrix Construction for fMRI Analysis |
|---|---|
| Description: | Constructs and inspects design matrices for functional magnetic resonance imaging (fMRI) analyses. Provides a formula interface for specifying event-related designs with flexible hemodynamic response function (HRF) bases, parametric modulators, and trialwise models. Includes facilities for baseline/nuisance regressors, contrast specification, and utilities for naming, validation, and visualization. Intended to support the model-building stage prior to statistical fitting. Implements methods described in Friston et al. (1995) <doi:10.1006/nimg.1995.1007> and Lindquist (2008) <doi:10.1214/09-STS282>. |
| Authors: | Bradley Buchsbaum [aut, cre, cph] |
| Maintainer: | Bradley Buchsbaum <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.6.1.9000 |
| Built: | 2026-10-16 13:22:37 UTC |
| Source: | https://github.com/bbuchsbaum/fmridesign |
Generates a baselinespec for modeling low-frequency drift in fMRI time series.
baseline( degree = 1, basis = c("constant", "poly", "bs", "ns"), name = NULL, intercept = c("runwise", "global", "none") )baseline( degree = 1, basis = c("constant", "poly", "bs", "ns"), name = NULL, intercept = c("runwise", "global", "none") )
degree |
Number of basis terms per image block (ignored for "constant"). |
basis |
Type of basis ("constant", "poly", "bs", or "ns"). |
name |
Optional name for the term. |
intercept |
Type of intercept to include ("runwise", "global", or "none"). |
A baselinespec list instance.
baseline(degree = 3, basis = "bs")baseline(degree = 3, basis = "bs")
Builds a baseline model to account for noise and non-event-related variance. This model may include a drift term, a block intercept term, and nuisance regressors.
baseline_model( basis = c("constant", "poly", "bs", "ns"), degree = 1, sframe, intercept = c("runwise", "global", "none"), nuisance_list = NULL, nuisance_check = c("warn", "error", "drop", "none"), na_action = c("drop", "zero", "median") )baseline_model( basis = c("constant", "poly", "bs", "ns"), degree = 1, sframe, intercept = c("runwise", "global", "none"), nuisance_list = NULL, nuisance_check = c("warn", "error", "drop", "none"), na_action = c("drop", "zero", "median") )
basis |
Character; type of basis function ("constant", "poly", "bs", or "ns"). |
degree |
Integer; degree of the spline/polynomial function. |
sframe |
A sampling_frame object. |
intercept |
Character; whether to include an intercept ("runwise", "global", or "none").
Ignored when |
nuisance_list |
Optional list of nuisance matrices or data frames (one per fMRI block). |
nuisance_check |
Character; how to handle nuisance diagnostics. |
na_action |
Character; how to handle |
An object of class "baseline_model".
sframe <- fmrihrf::sampling_frame(blocklens = c(100, 100), TR = 2) bmod <- baseline_model(basis = "bs", degree = 3, sframe = sframe) bmod_global <- baseline_model(basis = "bs", degree = 3, sframe = sframe, intercept = "global") bmod_nointercept <- baseline_model(basis = "bs", degree = 3, sframe = sframe, intercept = "none") stopifnot(ncol(design_matrix(bmod)) == 8)sframe <- fmrihrf::sampling_frame(blocklens = c(100, 100), TR = 2) bmod <- baseline_model(basis = "bs", degree = 3, sframe = sframe) bmod_global <- baseline_model(basis = "bs", degree = 3, sframe = sframe, intercept = "global") bmod_nointercept <- baseline_model(basis = "bs", degree = 3, sframe = sframe, intercept = "none") stopifnot(ncol(design_matrix(bmod)) == 8)
Extract baseline terms
## S3 method for class 'baseline_model' baseline_terms(x, ...) baseline_terms(x, ...)## S3 method for class 'baseline_model' baseline_terms(x, ...) baseline_terms(x, ...)
x |
The object. |
... |
Additional arguments. |
A named list of baseline term objects.
sframe <- fmrihrf::sampling_frame(blocklens = 6, TR = 1) bmod <- baseline_model(sframe = sframe) baseline_terms(bmod)sframe <- fmrihrf::sampling_frame(blocklens = 6, TR = 1) bmod <- baseline_model(sframe = sframe) baseline_terms(bmod)
Generates the _b## suffix for HRF basis functions.
basis_suffix(j, nb)basis_suffix(j, nb)
j |
Integer vector of basis indices (1-based). |
nb |
Total number of basis functions. |
Character vector of suffixes (e.g., _b01, _b02).
basis_suffix(1:3, 5) basis_suffix(1:10, 10)basis_suffix(1:3, 5) basis_suffix(1:10, 10)
Returns a block variable that is constant over the span of a scanning run.
block(x)block(x)
x |
The block variable. |
An object of class "blockspec".
block(run)block(run)
blockids() on an event_model returns one run id per event, in
event order: the run each onset belongs to. It does not return one id per
scan. For per-scan run ids use blockids(x$sampling_frame). blocklens(x)
gives the number of scans in each run.
## S3 method for class 'event_model' blockids(x, ...)## S3 method for class 'event_model' blockids(x, ...)
x |
An |
... |
Unused. |
fmrireg releases before its switch to fmridesign's method returned per-scan
ids here whenever fmrireg was loaded. To flag the change, the first call in
a session prints a one-time message (class
fmridesign_blockids_per_event).
Integer vector with one run id per event.
fmrihrf::blockids(), fmrihrf::blocklens()
sf <- fmrihrf::sampling_frame(blocklens = c(20, 20), TR = 2) des <- data.frame(onset = c(0, 10, 0, 10, 20), run = c(1, 1, 2, 2, 2), cond = factor(c("A", "B", "A", "B", "A"))) em <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sf) blockids(em) # per event: 1 1 2 2 2 blockids(em$sampling_frame) # per scan: 20 x 1, then 20 x 2 blocklens(em) # scans per run: 20 20sf <- fmrihrf::sampling_frame(blocklens = c(20, 20), TR = 2) des <- data.frame(onset = c(0, 10, 0, 10, 20), run = c(1, 1, 2, 2, 2), cond = factor(c("A", "B", "A", "B", "A"))) em <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sf) blockids(em) # per event: 1 1 2 2 2 blockids(em$sampling_frame) # per scan: 20 x 1, then 20 x 2 blocklens(em) # scans per run: 20 20
Creates a generator function for use with the hrf_fun parameter in hrf().
The generator produces boxcar HRFs where each event's duration determines
the boxcar width.
boxcar_hrf_gen(normalize = TRUE, min_duration = 0.1)boxcar_hrf_gen(normalize = TRUE, min_duration = 0.1)
normalize |
Logical; whether to normalize the boxcar HRF. Default TRUE. |
min_duration |
Numeric; minimum duration to use (prevents zero-width boxcars). Default 0.1. |
A function that takes an event data frame and returns a list of HRF objects.
weighted_hrf_gen() for weighted impulse HRFs
trial_data <- data.frame( onset = c(0, 10, 25), duration = c(2, 5, 3), condition = c("A", "B", "A"), run = 1 ) sf <- fmrihrf::sampling_frame(blocklens = 50, TR = 2) emod <- event_model( onset ~ hrf(condition, hrf_fun = boxcar_hrf_gen()), data = trial_data, block = ~run, sampling_frame = sf, durations = trial_data$duration ) print(emod)trial_data <- data.frame( onset = c(0, 10, 25), duration = c(2, 5, 3), condition = c("A", "B", "A"), run = 1 ) sf <- fmrihrf::sampling_frame(blocklens = 50, TR = 2) emod <- event_model( onset ~ hrf(condition, hrf_fun = boxcar_hrf_gen()), data = trial_data, block = ~run, sampling_frame = sf, durations = trial_data$duration ) print(emod)
Generate the B-spline basis matrix for a polynomial spline.
BSpline(x, degree)BSpline(x, degree)
x |
a numeric vector at which to evaluate the spline. Missing values are not allowed in x |
degree |
the degree of the piecewise polynomial |
an BSpline list instance
x_vals <- seq(0, 1, length.out = 6) bs_obj <- BSpline(x_vals, degree = 3) dim(bs_obj$y) bs_obj$namex_vals <- seq(0, 1, length.out = 6) bs_obj <- BSpline(x_vals, degree = 3) dim(bs_obj$y) bs_obj$name
Extract cells from a design object
## S3 method for class 'baseline_model' cells(x, drop.empty = TRUE, ...) cells(x, drop.empty = TRUE, ...) ## S3 method for class 'event' cells(x, drop.empty = TRUE, ...) ## S3 method for class 'event_model' cells(x, ...) ## S3 method for class 'event_term' cells(x, drop.empty = TRUE, ...) ## S3 method for class 'covariate_convolved_term' cells(x, ...) ## S3 method for class 'feature_term' cells(x, ...)## S3 method for class 'baseline_model' cells(x, drop.empty = TRUE, ...) cells(x, drop.empty = TRUE, ...) ## S3 method for class 'event' cells(x, drop.empty = TRUE, ...) ## S3 method for class 'event_model' cells(x, ...) ## S3 method for class 'event_term' cells(x, drop.empty = TRUE, ...) ## S3 method for class 'covariate_convolved_term' cells(x, ...) ## S3 method for class 'feature_term' cells(x, ...)
x |
The object to extract cells from. |
drop.empty |
Logical indicating whether to drop empty cells (default: TRUE). |
... |
Additional arguments (e.g., exclude_basis for convolved_term method). |
A data.frame/tibble of cells (categorical combinations) relevant to x.
sframe <- fmrihrf::sampling_frame(blocklens = 6, TR = 1) bmod <- baseline_model(sframe = sframe) head(cells(bmod))sframe <- fmrihrf::sampling_frame(blocklens = 6, TR = 1) bmod <- baseline_model(sframe = sframe) head(cells(bmod))
Convenience helper to quickly flag highly correlated regressors.
This is a pairwise check only: constant columns (including intercepts) are
excluded, and ok = TRUE does not establish full rank, estimability or good
contrast precision. Dependencies involving several columns, such as task
regressors summing to an intercept in a no-rest design, can pass this check.
Use check_estimability() on the full design, including baseline/nuisance
regressors, to inspect those dependencies.
check_collinearity(X, threshold = 0.9)check_collinearity(X, threshold = 0.9)
X |
A numeric design matrix (or an |
threshold |
Absolute correlation above which a pair is flagged. Default 0.9. |
A list with elements: ok (logical), pairs (data.frame with
offending pairs and their correlations). Invisibly returns the same list.
# Create a simple event model des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) emodel <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) # Check for multicollinearity res <- check_collinearity(design_matrix(emodel), threshold = 0.95) if (!res$ok) print(res$pairs)# Create a simple event model des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) emodel <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) # Check for multicollinearity res <- check_collinearity(design_matrix(emodel), threshold = 0.95) if (!res$ok) print(res$pairs)
Diagnoses dependencies involving many regressors, including event regressors
and the baseline. Unlike check_collinearity(), this uses the singular values
of the full design rather than pairwise correlations.
check_estimability( x, contrasts = NULL, baseline = NULL, absolute = TRUE, condition_threshold = 10, coverage_threshold = 0.9, tol = 1e-08 ) ## S3 method for class 'estimability_check' print(x, ...)check_estimability( x, contrasts = NULL, baseline = NULL, absolute = TRUE, condition_threshold = 10, coverage_threshold = 0.9, tol = 1e-08 ) ## S3 method for class 'estimability_check' print(x, ...)
x |
An |
contrasts |
A numeric vector, a matrix with contrast vectors in columns,
or a list of these. Names on vectors or row names on matrices are matched
strictly to design columns; omitted columns receive zero weight. Unnamed
weights must span the input design or the full design including appended
baseline columns. For an event model, |
baseline |
|
absolute |
Include diagnostics for individual coefficients of the input
design (before appending a baseline). Default |
condition_threshold |
Condition-number warning threshold, default 10. This is a screening heuristic, not a universal precision cutoff. |
coverage_threshold |
Flag runs whose event coverage exceeds this fraction, default 0.9. Coverage is context, not an estimability test. |
tol |
Relative singular-value cutoff for numerical rank and relative
null-space tolerance for contrast estimability. Default |
... |
Unused. |
Columns are scaled to unit Euclidean norm without centring, retaining the
intercept. condition_number is the exact spectral ratio (largest/smallest
singular value), or Inf for a numerically rank-deficient design. It is not
the default approximation returned by kappa(). Zero columns are retained.
weakest_direction gives named loadings in the scaled coordinates and the
corresponding coefficient direction in the original units. Its sign is
arbitrary; when the smallest singular value is repeated, the direction is
not unique. baseline_pattern labels a possible baseline-versus-regressors
dependency when all loadings outside the baseline have one sign and baseline
loadings have the opposite sign, in an ill-conditioned or deficient design.
This is a heuristic interpretation, not proof of a particular task structure.
A contrast is estimable when it is orthogonal to the design's null space.
Estimable contrasts receive a variance_factor, equal to
for full-rank designs and the corresponding generalized
inverse quadratic form otherwise. Non-estimable contrasts receive NA,
never a misleading finite pseudoinverse variance. These are variances per
unit independent residual variance in the original coefficient units;
rescaling a contrast rescales its variance quadratically. F-contrast columns
are assessed separately, not as an omnibus F statistic. For inference with
temporal filtering or correlated errors, supply the actual filtered/whitened
full design and matching contrasts.
Event coverage is the union of modelled event intervals, clipped to each
run's [0, n_scans * TR) window. Overlapping events or repeated terms count
once; zero-duration events occupy no time. Coverage uses retained event
terms, including term-specific subsets/durations, and is unavailable (NULL)
for raw matrices or models without event timing. High coverage suggests
inspecting scientifically appropriate centred or reference-condition
contrasts, which estimate different quantities from absolute coefficients.
An estimability_check list with ok, rank, n_columns,
n_observations, full_rank, condition_number, condition_threshold,
ill_conditioned, singular_values, column_norms, weakest_direction,
baseline_pattern, baseline (source and column names), contrasts
(name, quantity, estimable, variance_factor, null_fraction), coverage
(run, duration, covered, fraction, high_coverage), and explanatory messages.
ok means full numerical rank and condition number within the threshold;
it does not certify adequate precision for a scientific question.
validate_contrasts(), baseline_model()
# Every observation belongs to one task: absolute effects alias the intercept. X <- cbind(task_A = c(1, 1, 0, 0), task_B = c(0, 0, 1, 1), intercept = 1) check_collinearity(X)$ok check_estimability(X, contrasts = list(A_vs_B = c(1, -1, 0)))# Every observation belongs to one task: absolute effects alias the intercept. X <- cbind(task_A = c(1, 1, 0, 0), task_B = c(0, 0, 1, 1), intercept = 1) check_collinearity(X)$ok check_estimability(X, contrasts = list(A_vs_B = c(1, -1, 0)))
Inspects a block-wise nuisance regressor list before it is added to a
baseline model. The check is run per block and compares nuisance columns
against the baseline terms that would be constructed from basis, degree,
and intercept.
check_nuisance( nuisance_list, sframe, basis = c("constant", "poly", "bs", "ns"), degree = 1, intercept = c("runwise", "global", "none"), tol = sqrt(.Machine$double.eps), duplicate_threshold = 1 - sqrt(.Machine$double.eps), na_action = c("drop", "zero", "median") )check_nuisance( nuisance_list, sframe, basis = c("constant", "poly", "bs", "ns"), degree = 1, intercept = c("runwise", "global", "none"), tol = sqrt(.Machine$double.eps), duplicate_threshold = 1 - sqrt(.Machine$double.eps), na_action = c("drop", "zero", "median") )
nuisance_list |
A list of numeric matrices or data frames, one per block. |
sframe |
A sampling frame. |
basis, degree, intercept
|
Baseline model settings used to construct the comparison baseline terms. |
tol |
Numeric tolerance passed to QR rank checks. |
duplicate_threshold |
Absolute correlation threshold used to flag duplicate or near-duplicate columns. |
na_action |
Character; how to handle |
A nuisance_check object with ok, problems, by_block, and
normalized nuisance_list elements.
sframe <- fmrihrf::sampling_frame(blocklens = 20, TR = 1) motion <- cbind( linear = seq_len(20), duplicate = seq_len(20), constant = 1 ) report <- check_nuisance(list(motion), sframe, basis = "constant") report$ok report$by_block[[1]]$keepsframe <- fmrihrf::sampling_frame(blocklens = 20, TR = 1) motion <- cbind( linear = seq_len(20), duplicate = seq_len(20), constant = 1 ) report <- check_nuisance(list(motion), sframe, basis = "constant") report$ok report$by_block[[1]]$keep
Drops nuisance columns that are non-finite, zero-variance, or fail to increase QR rank after the block's baseline terms and earlier nuisance columns. Column order is respected, so when two columns are aliased the earlier column is kept.
clean_nuisance( nuisance_list, sframe, basis = c("constant", "poly", "bs", "ns"), degree = 1, intercept = c("runwise", "global", "none"), tol = sqrt(.Machine$double.eps), duplicate_threshold = 1 - sqrt(.Machine$double.eps), na_action = c("drop", "zero", "median") )clean_nuisance( nuisance_list, sframe, basis = c("constant", "poly", "bs", "ns"), degree = 1, intercept = c("runwise", "global", "none"), tol = sqrt(.Machine$double.eps), duplicate_threshold = 1 - sqrt(.Machine$double.eps), na_action = c("drop", "zero", "median") )
nuisance_list |
A list of numeric matrices or data frames, one per block. |
sframe |
A sampling frame. |
basis, degree, intercept
|
Baseline model settings used to construct the comparison baseline terms. |
tol |
Numeric tolerance passed to QR rank checks. |
duplicate_threshold |
Absolute correlation threshold used to flag duplicate or near-duplicate columns. |
na_action |
Character; how to handle |
A list with nuisance_list and report elements. Pass
result$nuisance_list to baseline_model().
sframe <- fmrihrf::sampling_frame(blocklens = 20, TR = 1) motion <- cbind( linear = seq_len(20), duplicate = seq_len(20), constant = 1 ) cleaned <- clean_nuisance(list(motion), sframe, basis = "constant") colnames(cleaned$nuisance_list[[1]])sframe <- fmrihrf::sampling_frame(blocklens = 20, TR = 1) motion <- cbind( linear = seq_len(20), duplicate = seq_len(20), constant = 1 ) cleaned <- clean_nuisance(list(motion), sframe, basis = "constant") colnames(cleaned$nuisance_list[[1]])
Define a contrast by directly targeting design matrix columns using regex patterns. This is useful for contrasts involving continuous variables or specific basis functions.
column_contrast(pattern_A, pattern_B = NULL, name, where = NULL)column_contrast(pattern_A, pattern_B = NULL, name, where = NULL)
pattern_A |
A character string containing a regex pattern to identify the columns for the positive (+) part of the contrast. |
pattern_B |
Optional character string containing a regex pattern for the
negative (-) part (for A-B type contrasts). If NULL, creates a contrast testing
the average of columns matching |
name |
A character string name for the contrast (mandatory). |
where |
Currently unused for column_contrast, but kept for API consistency. |
Weights are assigned as +1/nA to the nA columns matched by pattern_A and
-1/nB to the nB columns matched by pattern_B, so the contrast compares the
average effect of the 'A' columns with the average of the 'B' columns (or
with baseline if pattern_B is NULL) and sums to zero when both groups are
present. A contrast is evaluated within the single term it is attached to
(via hrf(..., contrasts = )); only that term's columns are candidates.
What the patterns are matched against. Each pattern is matched, with
grepl() semantics, against two names for every column of the term:
the design-matrix column name, exactly as shown by
colnames(design_matrix(model)): term_tag_condition_tag, plus a
_b## basis suffix for multi-basis HRFs (e.g. cond_cond.A,
task_cond_task.face_cond.A, cond_cond.A_b02). See
event_model() for the naming scheme and how the term tag is chosen;
the term-level condition name, i.e. the same name without the
term_tag_ prefix (e.g. cond.A, cond.A_b02), as returned by
conditions(term, expand_basis = TRUE). This is accepted for backward
compatibility.
The design-matrix names take precedence: a pattern that matches at least one
design-matrix column name selects exactly those columns, and the term-level
names are consulted only when it matches none. Both routes therefore refer
to the same columns ("^cond_cond\\.A$" and "^cond\\.A$" select the same
column). If a pattern matches in both namespaces but selects different
columns (for example, an unanchored "h" against hf_task.face and
hf_task.house, where only task.house contains "h" at term level), the
pattern is ambiguous and an error is raised; anchor it on the design-matrix
names ("^hf_task\\.house$"). If a pattern matches nothing in either
namespace a warning lists the available column names, and an error follows
if neither pattern selected any column.
Use standard R regex syntax for the patterns. Remember to escape special
characters (e.g., \\[, \\., \\*), and anchor patterns with ^ and $
to avoid accidental partial matches.
A column_contrast_spec object containing the specification.
event_model() for the column naming scheme,
pair_contrast() with basis = for basis-restricted condition contrasts.
des <- data.frame( onset = seq(0, 70, by = 10), run = 1, cond = factor(rep(c("A", "B"), 4)) ) sframe <- fmrihrf::sampling_frame(blocklens = 50, TR = 2) # Patterns written against the design-matrix column names # (colnames are "cond_cond.A", "cond_cond.B") cset <- contrast_set( column_contrast(pattern_A = "^cond_cond\\.A$", pattern_B = "^cond_cond\\.B$", name = "A_vs_B") ) emod <- event_model(onset ~ hrf(cond, contrasts = cset), data = des, block = ~run, sampling_frame = sframe) colnames(design_matrix(emod)) contrast_weights(emod)[["cond#A_vs_B"]]$offset_weights # Multi-basis HRF: select only the first basis function (_b01) of each # condition. Column names are "cond_cond.A_b01", "cond_cond.A_b02", ... cset_mb <- contrast_set( column_contrast(pattern_A = "^cond_cond\\.A_b01$", pattern_B = "^cond_cond\\.B_b01$", name = "A_vs_B_b01"), column_contrast(pattern_A = "_b01$", name = "canonical_mean") ) emod_mb <- event_model(onset ~ hrf(cond, basis = "spmg3", contrasts = cset_mb), data = des, block = ~run, sampling_frame = sframe) colnames(design_matrix(emod_mb)) contrast_weights(emod_mb)[["cond#A_vs_B_b01"]]$offset_weights # Legacy term-level patterns select the same columns cc_legacy <- column_contrast(pattern_A = "^cond\\.A_b01$", pattern_B = "^cond\\.B_b01$", name = "legacy")des <- data.frame( onset = seq(0, 70, by = 10), run = 1, cond = factor(rep(c("A", "B"), 4)) ) sframe <- fmrihrf::sampling_frame(blocklens = 50, TR = 2) # Patterns written against the design-matrix column names # (colnames are "cond_cond.A", "cond_cond.B") cset <- contrast_set( column_contrast(pattern_A = "^cond_cond\\.A$", pattern_B = "^cond_cond\\.B$", name = "A_vs_B") ) emod <- event_model(onset ~ hrf(cond, contrasts = cset), data = des, block = ~run, sampling_frame = sframe) colnames(design_matrix(emod)) contrast_weights(emod)[["cond#A_vs_B"]]$offset_weights # Multi-basis HRF: select only the first basis function (_b01) of each # condition. Column names are "cond_cond.A_b01", "cond_cond.A_b02", ... cset_mb <- contrast_set( column_contrast(pattern_A = "^cond_cond\\.A_b01$", pattern_B = "^cond_cond\\.B_b01$", name = "A_vs_B_b01"), column_contrast(pattern_A = "_b01$", name = "canonical_mean") ) emod_mb <- event_model(onset ~ hrf(cond, basis = "spmg3", contrasts = cset_mb), data = des, block = ~run, sampling_frame = sframe) colnames(design_matrix(emod_mb)) contrast_weights(emod_mb)[["cond#A_vs_B_b01"]]$offset_weights # Legacy term-level patterns select the same columns cc_legacy <- column_contrast(pattern_A = "^cond\\.A_b01$", pattern_B = "^cond\\.B_b01$", name = "legacy")
Extract columns
## S3 method for class 'Scale' columns(x, ...) ## S3 method for class 'ScaleWithin' columns(x, ...) ## S3 method for class 'RobustScale' columns(x, ...) columns(x, ...) ## S3 method for class 'event_model' columns(x, ...)## S3 method for class 'Scale' columns(x, ...) ## S3 method for class 'ScaleWithin' columns(x, ...) ## S3 method for class 'RobustScale' columns(x, ...) columns(x, ...) ## S3 method for class 'event_model' columns(x, ...)
x |
The object. |
... |
Additional arguments. |
Character vector of column names produced by the object.
bs_basis <- BSpline(seq(0, 1, length.out = 5), degree = 3) columns(bs_basis)bs_basis <- BSpline(seq(0, 1, length.out = 5), degree = 3) columns(bs_basis)
event_term to a per-condition basis listA lightweight wrapper around convolve() that post-processes the
resulting design matrix into a named list of T x d matrices - one per
experimental condition ("base condition tag"). This keeps all of the
heavy lifting inside fmrireg while exposing a minimal, pipe-friendly API
that can be used anywhere a condition -> basis split is required (e.g. for
CFALS).
condition_basis_list( x, hrf, sampling_frame, ..., output = c("condition_list", "matrix") )condition_basis_list( x, hrf, sampling_frame, ..., output = c("condition_list", "matrix") )
x |
An |
hrf |
An |
sampling_frame |
A |
... |
Further arguments passed on to
|
output |
Either "matrix" (default) for the ordinary design matrix or "condition_list" for the split-by-condition list. |
A numeric matrix or a named list of matrices, depending on
output.
term <- event_term( list(condition = factor(c("A", "B", "A"))), onsets = c(0, 10, 20), blockids = c(1, 1, 1) ) sf <- fmrihrf::sampling_frame(blocklens = 30, TR = 1) condition_basis_list(term, fmrihrf::HRF_SPMG1, sf)term <- event_term( list(condition = factor(c("A", "B", "A"))), onsets = c(0, 10, 20), blockids = c(1, 1, 1) ) sf <- fmrihrf::sampling_frame(blocklens = 30, TR = 1) condition_basis_list(term, fmrihrf::HRF_SPMG1, sf)
For an event_model the result also has term and column_name: the
design-matrix column of each condition, found by its canonical name
(columns are <term tag>_<canonical>). A condition with no column (an
empty cell when drop.empty = FALSE, or a multi-basis term when
expand_basis = FALSE) has column_name = NA.
## S3 method for class 'covariate_term' condition_map(x, drop.empty = TRUE, expand_basis = FALSE, ...) ## S3 method for class 'covariate_convolved_term' condition_map(x, drop.empty = TRUE, expand_basis = FALSE, ...) condition_map(x, drop.empty = TRUE, expand_basis = FALSE, ...) ## S3 method for class 'feature_term' condition_map(x, drop.empty = TRUE, expand_basis = FALSE, ...)## S3 method for class 'covariate_term' condition_map(x, drop.empty = TRUE, expand_basis = FALSE, ...) ## S3 method for class 'covariate_convolved_term' condition_map(x, drop.empty = TRUE, expand_basis = FALSE, ...) condition_map(x, drop.empty = TRUE, expand_basis = FALSE, ...) ## S3 method for class 'feature_term' condition_map(x, drop.empty = TRUE, expand_basis = FALSE, ...)
x |
The object to inspect. |
drop.empty |
Logical whether to drop empty conditions (default: TRUE). |
expand_basis |
Logical whether to expand basis functions (default: FALSE). |
... |
Additional arguments. |
A tibble mapping display names to canonical names.
term <- event_term( list( category = factor(c("face", "scene", "face")), attention = factor(c("attend", "attend", "ignore")) ), onsets = c(0, 10, 20), blockids = c(1, 1, 1) ) condition_map(term)term <- event_term( list( category = factor(c("face", "scene", "face")), attention = factor(c("attend", "attend", "ignore")) ), onsets = c(0, 10, 20), blockids = c(1, 1, 1) ) condition_map(term)
Extract conditions from a design object
## S3 method for class 'baseline_model' conditions(x, ...) ## S3 method for class 'covariate_term' conditions( x, drop.empty = TRUE, expand_basis = FALSE, style = c("canonical", "display"), ... ) ## S3 method for class 'covariate_convolved_term' conditions( x, drop.empty = TRUE, expand_basis = FALSE, style = c("canonical", "display"), ... ) conditions( x, drop.empty = TRUE, expand_basis = FALSE, style = c("canonical", "display"), ... ) ## S3 method for class 'event_term' conditions( x, drop.empty = TRUE, expand_basis = FALSE, style = c("canonical", "display"), ... ) ## S3 method for class 'convolved_term' conditions(x, ...) ## S3 method for class 'feature_term' conditions( x, drop.empty = TRUE, expand_basis = FALSE, style = c("canonical", "display"), ... )## S3 method for class 'baseline_model' conditions(x, ...) ## S3 method for class 'covariate_term' conditions( x, drop.empty = TRUE, expand_basis = FALSE, style = c("canonical", "display"), ... ) ## S3 method for class 'covariate_convolved_term' conditions( x, drop.empty = TRUE, expand_basis = FALSE, style = c("canonical", "display"), ... ) conditions( x, drop.empty = TRUE, expand_basis = FALSE, style = c("canonical", "display"), ... ) ## S3 method for class 'event_term' conditions( x, drop.empty = TRUE, expand_basis = FALSE, style = c("canonical", "display"), ... ) ## S3 method for class 'convolved_term' conditions(x, ...) ## S3 method for class 'feature_term' conditions( x, drop.empty = TRUE, expand_basis = FALSE, style = c("canonical", "display"), ... )
x |
The object to extract conditions from. |
... |
Additional arguments. |
drop.empty |
Logical whether to drop conditions with no events (default: TRUE).
The |
expand_basis |
Logical whether to expand basis functions (default: FALSE). |
style |
Naming style. |
A character vector of condition names.
term <- event_term( list(condition = factor(c("A", "B", "A"))), onsets = c(0, 10, 20), blockids = c(1, 1, 1) ) conditions(term) conditions(term, style = "display") conditions(term, expand_basis = TRUE)term <- event_term( list(condition = factor(c("A", "B", "A"))), onsets = c(0, 10, 20), blockids = c(1, 1, 1) ) conditions(term) conditions(term, style = "display") conditions(term, expand_basis = TRUE)
Construct method
## S3 method for class 'baselinespec' construct(x, model_spec, ...) ## S3 method for class 'covariatespec' construct(x, model_spec, sampling_frame = NULL, ...) construct(x, ...) ## S3 method for class 'featurespec' construct(x, model_spec, ...)## S3 method for class 'baselinespec' construct(x, model_spec, ...) ## S3 method for class 'covariatespec' construct(x, model_spec, sampling_frame = NULL, ...) construct(x, ...) ## S3 method for class 'featurespec' construct(x, model_spec, ...)
x |
The object. |
model_spec |
A model specification object (used by some methods). For baselinespec: typically a sampling_frame or list containing one. For hrfspec/covariatespec: contains data and other model information. |
... |
Additional arguments. |
sampling_frame |
A sampling_frame object (used by covariatespec method). |
A constructed object; return type depends on method.
sframe <- fmrihrf::sampling_frame(blocklens = 5, TR = 1) drift_spec <- baseline(degree = 2, basis = "poly") construct(drift_spec, sframe)sframe <- fmrihrf::sampling_frame(blocklens = 5, TR = 1) drift_spec <- baseline(degree = 2, basis = "poly") construct(drift_spec, sframe)
Define a linear contrast using a formula expression.
contrast(form, name, where = NULL)contrast(form, name, where = NULL)
form |
A formula describing the contrast. |
name |
A character label for the contrast. |
where |
An expression defining the subset over which the contrast is applied (default: NULL). |
A list containing the contrast specification.
# A minus B contrast using display labels contrast(~ A - B, name="A_B") # With subsetting contrast(~ A - B, name="A_B_block1", where = ~ block == 1)# A minus B contrast using display labels contrast(~ A - B, name="A_B") # With subsetting contrast(~ A - B, name="A_B_block1", where = ~ block == 1)
contrast objectDrives the unified post-processing pipeline: expands the base mask across
basis functions (when applicable), applies basis filtering, attaches the
standard contrast list class, and returns an object compatible with
downstream contrast_weights.event_model().
contrast_from_mask(mask, spec, term, classes = character())contrast_from_mask(mask, spec, term, classes = character())
mask |
Output of |
spec |
The originating contrast spec (stored on the result). |
term |
The |
classes |
Character vector of extra S3 classes prepended to the
default |
Custom contrast types implement contrast_mask() and call this driver.
A contrast object.
term <- event_term( list(condition = factor(c("A", "B"))), onsets = c(0, 2), blockids = c(1, 1) ) condition_names <- conditions(term, drop.empty = FALSE) weights <- matrix( c(1, -1), ncol = 1, dimnames = list(condition_names, "A-B") ) spec <- structure( list(name = "A-B", basis = NULL, basis_weights = NULL), class = c("example_contrast_spec", "contrast_spec", "list") ) result <- contrast_from_mask( list(weights = weights, condnames = condition_names), spec, term ) result$weightsterm <- event_term( list(condition = factor(c("A", "B"))), onsets = c(0, 2), blockids = c(1, 1) ) condition_names <- conditions(term, drop.empty = FALSE) weights <- matrix( c(1, -1), ncol = 1, dimnames = list(condition_names, "A-B") ) spec <- structure( list(name = "A-B", basis = NULL, basis_weights = NULL), class = c("example_contrast_spec", "contrast_spec", "list") ) result <- contrast_from_mask( list(weights = weights, condnames = condition_names), spec, term ) result$weights
contrast_mask() is the extension point for new contrast types: it
returns a base contrast matrix with one row per base condition (no
basis expansion) and one column per contrast column. The unified driver
contrast_from_mask() handles basis expansion, basis filtering and
packaging into a contrast object compatible with
contrast_weights.event_model().
contrast_mask(x, term, ...)contrast_mask(x, term, ...)
x |
A |
term |
An |
... |
Additional arguments passed to methods. |
To register a custom contrast type:
Define a constructor that produces a list with class
c("my_spec", "contrast_spec", "list").
Implement contrast_mask.my_spec() returning the base weights.
Implement contrast_weights.my_spec() as a one-liner:
contrast_weights.my_spec <- function(x, term, ...) {
contrast_from_mask(contrast_mask(x, term, ...), x, term)
}
The built-in spec classes (pair_contrast_spec, oneway_contrast_spec,
poly_contrast_spec, ...) implement contrast_weights() directly, so
they do not require contrast_mask() methods.
A list with elements:
weights : numeric matrix, n_base_conditions x n_contrast_cols,
row names = base condition names.
condnames : character vector of base condition names.
term <- event_term( list(condition = factor(c("A", "B"))), onsets = c(0, 2), blockids = c(1, 1) ) spec <- structure( list(name = "A-B"), class = c("example_contrast_spec", "contrast_spec", "list") ) contrast_mask.example_contrast_spec <- function(x, term, ...) { condition_names <- conditions(term, drop.empty = FALSE) weights <- matrix( c(1, -1), ncol = 1, dimnames = list(condition_names, x$name) ) list(weights = weights, condnames = condition_names) } contrast_mask(spec, term)term <- event_term( list(condition = factor(c("A", "B"))), onsets = c(0, 2), blockids = c(1, 1) ) spec <- structure( list(name = "A-B"), class = c("example_contrast_spec", "contrast_spec", "list") ) contrast_mask.example_contrast_spec <- function(x, term, ...) { condition_names <- conditions(term, drop.empty = FALSE) weights <- matrix( c(1, -1), ncol = 1, dimnames = list(condition_names, x$name) ) list(weights = weights, condnames = condition_names) } contrast_mask(spec, term)
Construct a list of contrast_spec objects. Nested contrast_set arguments,
including results from one_against_all_contrast() or pairwise_contrasts(),
are recursively flattened in argument order. Individual specifications and
their list names are preserved; names on enclosing sets are not used as
prefixes. Empty sets contribute no specifications. Ordinary lists are not
flattened; splice those explicitly with do.call(contrast_set, specs).
contrast_set(...)contrast_set(...)
... |
Individual |
A list of contrast_spec objects with class "contrast_set".
c1 <- contrast(~ A - B, name="A_B") c2 <- contrast(~ B - C, name="B_C") contrast_set(c1,c2) contrast_set(c1, one_against_all_contrast(c("A", "B", "C"), "condition"))c1 <- contrast(~ A - B, name="A_B") c2 <- contrast(~ B - C, name="B_C") contrast_set(c1,c2) contrast_set(c1, one_against_all_contrast(c("A", "B", "C"), "condition"))
Compute the contrast weights for a unit_contrast_spec object.
Compute the contrast weights for an oneway_contrast_spec object.
Compute the contrast weights for an interaction_contrast_spec object.
Compute the contrast weights for a poly_contrast_spec object.
Compute the contrast weights for a pair_contrast_spec object.
Compute contrast weights for a column_contrast_spec object by targeting
the term's design matrix columns with regex patterns. Patterns are matched
against the design-matrix column names (term_tag_condition_tag[_b##])
first and, only if they match none, against the term-level condition names;
see column_contrast() for the precedence rules.
Compute the contrast weights for a contrast_formula_spec object.
Compute the contrast weights for a contrast_diff_spec object.
Compute the contrast weights for each contrast specification within a contrast_set object.
## S3 method for class 'unit_contrast_spec' contrast_weights(x, term, ...) ## S3 method for class 'oneway_contrast_spec' contrast_weights(x, term, ...) ## S3 method for class 'interaction_contrast_spec' contrast_weights(x, term, ...) ## S3 method for class 'poly_contrast_spec' contrast_weights(x, term, ...) ## S3 method for class 'pair_contrast_spec' contrast_weights(x, term, ...) ## S3 method for class 'column_contrast_spec' contrast_weights(x, term, ...) ## S3 method for class 'contrast_formula_spec' contrast_weights(x, term, ...) ## S3 method for class 'contrast_diff_spec' contrast_weights(x, term, ...) ## S3 method for class 'contrast_set' contrast_weights(x, term, ...) contrast_weights(x, ...) ## S3 method for class 'convolved_term' contrast_weights(x, ...) ## S3 method for class 'event_model' contrast_weights(x, ...)## S3 method for class 'unit_contrast_spec' contrast_weights(x, term, ...) ## S3 method for class 'oneway_contrast_spec' contrast_weights(x, term, ...) ## S3 method for class 'interaction_contrast_spec' contrast_weights(x, term, ...) ## S3 method for class 'poly_contrast_spec' contrast_weights(x, term, ...) ## S3 method for class 'pair_contrast_spec' contrast_weights(x, term, ...) ## S3 method for class 'column_contrast_spec' contrast_weights(x, term, ...) ## S3 method for class 'contrast_formula_spec' contrast_weights(x, term, ...) ## S3 method for class 'contrast_diff_spec' contrast_weights(x, term, ...) ## S3 method for class 'contrast_set' contrast_weights(x, term, ...) contrast_weights(x, ...) ## S3 method for class 'convolved_term' contrast_weights(x, ...) ## S3 method for class 'event_model' contrast_weights(x, ...)
x |
The object. |
term |
A term object against which weights should be computed. |
... |
Additional arguments. |
If the weight matrices returned by a contrast specification contain row names, these are matched to the column names of the corresponding term in the design matrix. This allows contrasts to target only a subset of term levels.
A list containing the term, name, weights, condition names, and contrast specification.
A list containing the term, name, weights, condition names, and contrast specification.
A list containing the term, name, weights, condition names, and contrast specification.
A list containing the term, name, weights, condition names, and contrast specification.
A list containing the term, name, weights, condition names, and contrast specification.
A list containing the contrast details:
term |
The original |
name |
The name of the contrast. |
weights |
A numeric matrix with one row per column of the term (row
names are the term-level condition names from
|
condnames |
Character vector of all expanded condition names from |
contrast_spec |
The original |
A list containing the term, name, weights, condition names, and contrast specification.
A list containing the term, name, weights, condition names, and contrast specification.
A named list where each element is the result of calling contrast_weights on the corresponding contrast_spec in the set. The list names are the names of the individual contrasts.
A named list of contrast weight objects or matrices.
des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) cset <- contrast_set( diff = column_contrast(pattern_A = "cond.A", pattern_B = "cond.B", name = "diff") ) emod <- event_model(onset ~ hrf(cond, contrasts = cset), data = des, block = ~run, sampling_frame = sframe) contrast_weights(emod)des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) cset <- contrast_set( diff = column_contrast(pattern_A = "cond.A", pattern_B = "cond.B", name = "diff") ) emod <- event_model(onset ~ hrf(cond, contrasts = cset), data = des, block = ~run, sampling_frame = sframe) contrast_weights(emod)
Extract contrasts
contrasts(x, ...) ## S3 method for class 'feature_term' contrasts(x, ...)contrasts(x, ...) ## S3 method for class 'feature_term' contrasts(x, ...)
x |
The object. |
... |
Additional arguments. |
A named list of contrast specifications.
des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) cset <- contrast_set( diff = column_contrast(pattern_A = "cond.A", pattern_B = "cond.B", name = "diff") ) emod <- event_model(onset ~ hrf(cond, contrasts = cset), data = des, block = ~run, sampling_frame = sframe) contrasts(emod)des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) cset <- contrast_set( diff = column_contrast(pattern_A = "cond.A", pattern_B = "cond.B", name = "diff") ) emod <- event_model(onset ~ hrf(cond, contrasts = cset), data = des, block = ~run, sampling_frame = sframe) contrasts(emod)
This function collects the contrast specifications defined for each term within the model and returns them as a named list.
## S3 method for class 'event_model' contrasts(x, ...)## S3 method for class 'event_model' contrasts(x, ...)
x |
An |
... |
Unused. |
A named list of contrast specifications.
des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) cset <- contrast_set( diff = column_contrast(pattern_A = "cond.A", pattern_B = "cond.B", name = "diff") ) emod <- event_model(onset ~ hrf(cond, contrasts = cset), data = des, block = ~run, sampling_frame = sframe) contrasts(emod)des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) cset <- contrast_set( diff = column_contrast(pattern_A = "cond.A", pattern_B = "cond.B", name = "diff") ) emod <- event_model(onset ~ hrf(cond, contrasts = cset), data = des, block = ~run, sampling_frame = sframe) contrasts(emod)
This accessor returns the list of contrast specifications attached to the term's originating hrfspec, if any.
## S3 method for class 'event_term' contrasts(x, ...)## S3 method for class 'event_term' contrasts(x, ...)
x |
An |
... |
Unused. |
A list of contrast specifications or NULL when none are defined.
des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) cset <- contrast_set( diff = column_contrast(pattern_A = "cond.A", pattern_B = "cond.B", name = "diff") ) emod <- event_model(onset ~ hrf(cond, contrasts = cset), data = des, block = ~run, sampling_frame = sframe) contrasts(terms(emod)[[1]])des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) cset <- contrast_set( diff = column_contrast(pattern_A = "cond.A", pattern_B = "cond.B", name = "diff") ) emod <- event_model(onset ~ hrf(cond, contrasts = cset), data = des, block = ~run, sampling_frame = sframe) contrasts(terms(emod)[[1]])
Retrieve contrast specifications from an hrfspec
## S3 method for class 'hrfspec' contrasts(x, ...)## S3 method for class 'hrfspec' contrasts(x, ...)
x |
An |
... |
Unused. |
The list of contrast specifications attached to the hrfspec, or NULL.
condition <- factor(c("A", "B")) cset <- contrast_set( diff = column_contrast(pattern_A = "condition.A", pattern_B = "condition.B", name = "diff") ) spec <- hrf(condition, contrasts = cset) contrasts(spec)condition <- factor(c("A", "B")) cset <- contrast_set( diff = column_contrast(pattern_A = "condition.A", pattern_B = "condition.B", name = "diff") ) spec <- hrf(condition, contrasts = cset) contrasts(spec)
Convolve events with a hemodynamic response function
convolve( x, hrf, sampling_frame, drop.empty = TRUE, summate = TRUE, precision = 0.1, normalize = FALSE, ... ) ## S3 method for class 'event_term' convolve( x, hrf, sampling_frame, drop.empty = TRUE, summate = TRUE, precision = 0.3, normalize = FALSE, ... )convolve( x, hrf, sampling_frame, drop.empty = TRUE, summate = TRUE, precision = 0.1, normalize = FALSE, ... ) ## S3 method for class 'event_term' convolve( x, hrf, sampling_frame, drop.empty = TRUE, summate = TRUE, precision = 0.3, normalize = FALSE, ... )
x |
The events to convolve. |
hrf |
The hemodynamic response function. |
sampling_frame |
The sampling frame. |
drop.empty |
Logical indicating whether to drop columns with all zeros. |
summate |
Logical indicating whether to sum convolved signals. |
precision |
Numeric specifying the temporal precision for convolution. |
normalize |
Logical; if TRUE, each convolved regressor column is peak-normalized. Default FALSE. |
... |
Additional arguments. |
A matrix-like (often tibble) of convolved regressors.
term <- event_term( list(condition = factor(c("A", "B", "A"))), onsets = c(0, 5, 10), blockids = c(1, 1, 1) ) sf <- fmrihrf::sampling_frame(blocklens = 20, TR = 1) conv <- convolve(term, fmrihrf::HRF_SPMG1, sf) names(conv)term <- event_term( list(condition = factor(c("A", "B", "A"))), onsets = c(0, 5, 10), blockids = c(1, 1, 1) ) sf <- fmrihrf::sampling_frame(blocklens = 20, TR = 1) conv <- convolve(term, fmrihrf::HRF_SPMG1, sf) names(conv)
Convolves a HRF with a design matrix (one column per condition) to produce a list of regressors.
convolve_design(hrf, dmat, globons, durations, summate = TRUE, hrf_list = NULL)convolve_design(hrf, dmat, globons, durations, summate = TRUE, hrf_list = NULL)
hrf |
A function representing the HRF (used when hrf_list is NULL). |
dmat |
Design matrix (with named columns). |
globons |
Numeric vector of global onsets. |
durations |
Numeric vector of event durations. |
summate |
Logical; if TRUE, summate the convolved HRF (default: TRUE). |
hrf_list |
Optional list of HRF objects, one per event (row in dmat). When provided, allows per-onset HRF specification. The list is subsetted to match non-zero amplitude events for each condition. |
A list of regressors (one for each column).
hrf <- fmrihrf::HRF_SPMG1 dmat <- data.frame(A = c(1, 0, 1), B = c(0, 1, 0)) globons <- c(0, 10, 20) durations <- rep(0, 3) regs <- convolve_design(hrf, dmat, globons, durations) length(regs)hrf <- fmrihrf::HRF_SPMG1 dmat <- data.frame(A = c(1, 0, 1), B = c(0, 1, 0)) globons <- c(0, 10, 20) durations <- rep(0, 3) regs <- convolve_design(hrf, dmat, globons, durations) length(regs)
Compute correlation map
correlation_map(x, ...)correlation_map(x, ...)
x |
The object. |
... |
Additional arguments. |
A ggplot2 object visualizing regressor correlations.
des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) correlation_map(emod)des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) correlation_map(emod)
Shows the pairwise correlations between design-matrix columns as the lower
triangle of a matrix. The fill is the package's diverging palette, fixed
at [-1, 1] by default with a neutral zero; for up to 20 columns each cell
also prints r (two decimals for up to 10 columns). Cells with abs(r) at or
above flag_threshold are outlined and counted in the subtitle, which
also names the most strongly correlated pair.
## S3 method for class 'event_model' correlation_map( x, rotate_x_text = TRUE, method = c("pearson", "spearman"), half_matrix = TRUE, limits = c("fixed", "data"), absolute_limits = NULL, annotate = NULL, flag_threshold = 0.5, vif_threshold = 5, title = "Regressor correlations", subtitle = NULL, within_run = FALSE, label_values = NULL, ... ) ## S3 method for class 'baseline_model' correlation_map( x, method = c("pearson", "spearman"), half_matrix = TRUE, limits = c("fixed", "data"), absolute_limits = NULL, rotate_x_text = TRUE, annotate = NULL, flag_threshold = 0.5, vif_threshold = 5, title = "Baseline regressor correlations", subtitle = NULL, within_run = TRUE, label_values = NULL, ... )## S3 method for class 'event_model' correlation_map( x, rotate_x_text = TRUE, method = c("pearson", "spearman"), half_matrix = TRUE, limits = c("fixed", "data"), absolute_limits = NULL, annotate = NULL, flag_threshold = 0.5, vif_threshold = 5, title = "Regressor correlations", subtitle = NULL, within_run = FALSE, label_values = NULL, ... ) ## S3 method for class 'baseline_model' correlation_map( x, method = c("pearson", "spearman"), half_matrix = TRUE, limits = c("fixed", "data"), absolute_limits = NULL, rotate_x_text = TRUE, annotate = NULL, flag_threshold = 0.5, vif_threshold = 5, title = "Baseline regressor correlations", subtitle = NULL, within_run = TRUE, label_values = NULL, ... )
x |
An |
rotate_x_text |
Logical; angle column labels when they would overlap. |
method |
Correlation method, |
half_matrix |
Logical; if |
limits |
|
absolute_limits |
Deprecated logical kept for compatibility; |
annotate |
Logical or |
flag_threshold |
Cells with abs(r) at or above this value are outlined. |
vif_threshold |
VIFs at or above this value are flagged. |
title, subtitle
|
Plot title and subtitle. |
within_run |
Logical. If |
label_values |
An alias for |
... |
Passed to |
Pairwise correlations miss multicollinearity, so the diagonal shows each
column's variance inflation factor, VIF_j = 1 / (1 - R2_j), from
regressing column j on all other columns after removing each run's mean
(per-run intercepts). VIFs at or above vif_threshold are drawn in a
warning colour, and a column that is an exact linear combination of
others is marked "aliased".
Correlations are computed over all scans of the full design matrix, with
runs concatenated (as stated in the caption). Columns keep design order and
are grouped by term, so the map lines up with design_map().
A ggplot object.
design_map(), check_collinearity()
des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) correlation_map(emod) bmod <- baseline_model(basis = "poly", degree = 2, sframe = fmrihrf::sampling_frame(c(40, 40), TR = 1)) correlation_map(bmod)des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) correlation_map(emod) bmod <- baseline_model(basis = "poly", degree = 2, sframe = fmrihrf::sampling_frame(c(40, 40), TR = 1)) correlation_map(bmod)
Creates a covariate term that is added directly to the fMRI model without being convolved with a hemodynamic response function (HRF). This is useful for including nuisance variables, continuous covariates, or any other regressors that should not undergo HRF convolution.
covariate(..., data, id = NULL, prefix = NULL, subset = NULL)covariate(..., data, id = NULL, prefix = NULL, subset = NULL)
... |
Covariate expressions. Each expression may evaluate to a numeric vector, matrix, or data frame. Matrix/data-frame columns are expanded into separate regressors. |
data |
A data.frame containing the variables. |
id |
An optional term identifier. As elsewhere in |
prefix |
An optional term-tag prefix used when |
subset |
Optional expression used to subset the covariate data. |
In fMRI analysis, some predictors should not be convolved with the HRF because they represent:
Continuous physiological measurements (e.g., heart rate, respiration)
Motion parameters from head movement correction
Scanner drift or other technical artifacts
Behavioral measures that directly correlate with BOLD signal
Global signal or other nuisance variables
The covariate term can be combined with standard HRF-convolved event terms in the same model. For example:
model <- event_model(onset ~ hrf(stimulus) + covariate(motion_x, motion_y, data = cov_data),
data = events, block = ~ 1, sampling_frame = sframe)
Final columns follow the package-wide
term_tag_condition_tag convention. The default term tag is cov; id
or prefix replaces it. Thus covariate(x, y, data = d) produces cov_x
and cov_y, while id = "motion" produces motion_x and motion_y.
Named matrix columns become condition tags; unnamed or duplicated matrix
columns use deterministic feature_suffix() tags such as f01 and f02.
A list containing information about the covariate term with class 'covariatespec' that can be used within an event_model.
event_model() for creating complete fMRI models
hrf() for creating HRF-convolved event terms
# Add motion parameters as covariates motion_data <- data.frame( x = rnorm(100), # x translation y = rnorm(100) # y translation ) cv <- covariate(x, y, data = motion_data, prefix = "motion") # A matrix is expanded using its column names lag_set <- cbind(lag_m2 = rnorm(100), lag_0 = rnorm(100), lag_p2 = rnorm(100)) lag_data <- data.frame(row = seq_len(100)) lag_data$lag_set <- lag_set cv_lags <- covariate(lag_set, data = lag_data, id = "alignment") # Combine with event model sframe <- sampling_frame(blocklens = c(100), TR = 2) # 50 events, strictly increasing onsets per block event_data <- data.frame( stimulus = factor(rep(c("A", "B"), 25)), onset = seq(0, by = 4, length.out = 50) ) # Full model with both HRF-convolved events and non-convolved covariates model <- event_model( onset ~ hrf(stimulus) + covariate(x, y, data = motion_data, id = "motion"), data = event_data, block = ~ 1, sampling_frame = sframe )# Add motion parameters as covariates motion_data <- data.frame( x = rnorm(100), # x translation y = rnorm(100) # y translation ) cv <- covariate(x, y, data = motion_data, prefix = "motion") # A matrix is expanded using its column names lag_set <- cbind(lag_m2 = rnorm(100), lag_0 = rnorm(100), lag_p2 = rnorm(100)) lag_data <- data.frame(row = seq_len(100)) lag_data$lag_set <- lag_set cv_lags <- covariate(lag_set, data = lag_data, id = "alignment") # Combine with event model sframe <- sampling_frame(blocklens = c(100), TR = 2) # 50 events, strictly increasing onsets per block event_data <- data.frame( stimulus = factor(rep(c("A", "B"), 25)), onset = seq(0, by = 4, length.out = 50) ) # Full model with both HRF-convolved events and non-convolved covariates model <- event_model( onset ~ hrf(stimulus) + covariate(x, y, data = motion_data, id = "motion"), data = event_data, block = ~ 1, sampling_frame = sframe )
Returns a tibble with one row per column of the design matrix and structured metadata (term, condition, basis, role, run, etc.).
design_colmap(x, ...)design_colmap(x, ...)
x |
An object containing or producing a design matrix (e.g., event_model, baseline_model). |
... |
Additional arguments passed to methods. |
A tibble with per-column metadata.
# Create a simple event model des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) # Extract column metadata colmap <- design_colmap(emod) head(colmap) # Query specific columns colmap[colmap$condition == "A", ]# Create a simple event model des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) # Extract column metadata colmap <- design_colmap(emod) head(colmap) # Query specific columns colmap[colmap$condition == "A", ]
Returns a tibble with one row per column of the design matrix and structured metadata derived from existing package attributes and naming conventions. This avoids ad-hoc string parsing in user code and provides a consistent, queryable view of the design.
## S3 method for class 'event_model' design_colmap(x, ...)## S3 method for class 'event_model' design_colmap(x, ...)
x |
An object containing or producing a design matrix
(e.g., |
... |
Unused; reserved for future extensions. |
A tibble with columns:
col (integer): 1-based column index
name (character): column name
term_tag (character): term identifier (event tag or baseline term name)
term_index (integer): position within terms(x)
condition (character): condition/event label without basis suffix (if applicable)
run (integer): block/run id when the column is block-specific; NA if pooled
role (character): e.g., "task", "drift", "intercept", "nuisance"
model_source (character): "event" or "baseline"
basis_name (character): HRF or baseline basis identifier when available
basis_ix (integer): within-condition basis index (HRF component); NA if not applicable
basis_total (integer): total number of basis components for the column's term; NA if not applicable
basis_label (character): human-readable label for the basis component when known
pretty_name (character): concise, human-friendly label for display (e.g., "RT" or "RT_lag_02")
is_block_diagonal (logical): TRUE when the regressor is per-run/block
modulation_type (character): "amplitude", "parametric", "covariate", or "feature"
modulation_id (character): modulator identifier when applicable (e.g., "RT", "RT_by_group")
# Create event model des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) # Get column metadata colmap <- design_colmap(emod) head(colmap) # Query columns by condition colmap[colmap$condition == "A", ]# Create event model des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) # Get column metadata colmap <- design_colmap(emod) head(colmap) # Query columns by condition colmap[colmap$condition == "A", ]
Compute design map
design_map(x, ...)design_map(x, ...)
x |
The object. |
... |
Additional arguments. |
A ggplot2 object visualizing the design matrix.
des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) design_map(emod)des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) design_map(emod)
Draws the design matrix as an image in the style of SPM: one row per scan (time runs downward), one column per regressor. Columns are grouped by model term under a spanner, runs are separated by thin rules and labelled in the left margin, and the right margin marks the first scan of each run.
## S3 method for class 'event_model' design_map( x, block_separators = TRUE, rotate_x_text = TRUE, fill_midpoint = NULL, fill_limits = NULL, scale = c("column", "none"), palette = c("diverging", "grey"), y_axis = c("scan", "time"), title = "Design matrix", subtitle = NULL, max_labels = 60, ... ) ## S3 method for class 'baseline_model' design_map( x, block_separators = TRUE, rotate_x_text = TRUE, fill_midpoint = NULL, fill_limits = NULL, scale = c("column", "none"), palette = c("diverging", "grey"), y_axis = c("scan", "time"), title = "Baseline design matrix", subtitle = NULL, max_labels = 60, ... )## S3 method for class 'event_model' design_map( x, block_separators = TRUE, rotate_x_text = TRUE, fill_midpoint = NULL, fill_limits = NULL, scale = c("column", "none"), palette = c("diverging", "grey"), y_axis = c("scan", "time"), title = "Design matrix", subtitle = NULL, max_labels = 60, ... ) ## S3 method for class 'baseline_model' design_map( x, block_separators = TRUE, rotate_x_text = TRUE, fill_midpoint = NULL, fill_limits = NULL, scale = c("column", "none"), palette = c("diverging", "grey"), y_axis = c("scan", "time"), title = "Baseline design matrix", subtitle = NULL, max_labels = 60, ... )
x |
An |
block_separators |
Logical; draw a rule at each run boundary. |
rotate_x_text |
Logical; angle the column labels when they would
otherwise overlap. With |
fill_midpoint |
Numeric or |
fill_limits |
Numeric length-2 vector or |
scale |
|
palette |
|
y_axis |
Label the right-hand axis by |
title, subtitle
|
Plot title and subtitle. The default subtitle states the number of regressors, runs, and scans, and the TR, and names any near-flat columns. |
max_labels |
Maximum number of column labels to print; beyond this labels are thinned to every k-th column. |
... |
Passed to |
By default each column is divided by its maximum absolute value
(scale = "column", stated in the legend) so regressors in different units
share one fill scale; zero is always the neutral midpoint of the
package's diverging palette. Because rescaling would make a near-flat
regressor look healthy, real magnitudes stay visible: a strip of bars under
the matrix shows each column's peak absolute value relative to the largest
in its term, and columns below 5% of that (or all zero) are marked in
orange, outlined over the matrix, and named in the subtitle. With 12 or
fewer columns each label also carries the column's raw range. Use
scale = "none" to plot raw values, or palette = "grey" for an SPM-style
greyscale.
For baseline models, columns are grouped by term (drift, intercept, nuisance) and then run, with a "Run k" sub-spanner over each run's columns, so the block-diagonal structure reads as a staircase; nuisance columns are drawn at reduced opacity so they do not dominate.
A ggplot object.
correlation_map(), plot_contrasts(), theme_fmridesign()
des <- data.frame( onset = c(0, 10, 20, 30, 5, 15, 25, 35), run = rep(1:2, each = 4), cond = factor(c("A", "B", "A", "B", "B", "A", "B", "A")) ) sframe <- fmrihrf::sampling_frame(blocklens = c(40, 40), TR = 2) emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) design_map(emod) design_map(emod, palette = "grey", y_axis = "time") bmod <- baseline_model(basis = "poly", degree = 3, sframe = sframe) design_map(bmod)des <- data.frame( onset = c(0, 10, 20, 30, 5, 15, 25, 35), run = rep(1:2, each = 4), cond = factor(c("A", "B", "A", "B", "B", "A", "B", "A")) ) sframe <- fmrihrf::sampling_frame(blocklens = c(40, 40), TR = 2) emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) design_map(emod) design_map(emod, palette = "grey", y_axis = "time") bmod <- baseline_model(basis = "poly", degree = 3, sframe = sframe) design_map(bmod)
Extract or construct a design matrix
## S3 method for class 'baseline_model' design_matrix(x, blockid = NULL, allrows = FALSE, ...) ## S3 method for class 'baseline_term' design_matrix(x, blockid = NULL, allrows = FALSE, ...) design_matrix(x, ...) ## S3 method for class 'event_model' design_matrix(x, blockid = NULL, ...) ## S3 method for class 'convolved_term' design_matrix(x, blockid = NULL, ...) ## S3 method for class 'event_term' design_matrix(x, drop.empty = TRUE, ...)## S3 method for class 'baseline_model' design_matrix(x, blockid = NULL, allrows = FALSE, ...) ## S3 method for class 'baseline_term' design_matrix(x, blockid = NULL, allrows = FALSE, ...) design_matrix(x, ...) ## S3 method for class 'event_model' design_matrix(x, blockid = NULL, ...) ## S3 method for class 'convolved_term' design_matrix(x, blockid = NULL, ...) ## S3 method for class 'event_term' design_matrix(x, drop.empty = TRUE, ...)
x |
The object to extract design matrix from. |
blockid |
Block ID(s) to extract (for baseline_term method). |
allrows |
Whether to return all rows (for baseline_term method). |
... |
Additional arguments. |
drop.empty |
Whether to drop empty columns (for event_term method). |
A matrix-like object (often tibble) with rows = scans, cols = regressors.
sframe <- fmrihrf::sampling_frame(blocklens = 6, TR = 1) bmod <- baseline_model(sframe = sframe) head(design_matrix(bmod))sframe <- fmrihrf::sampling_frame(blocklens = 6, TR = 1) bmod <- baseline_model(sframe = sframe) head(design_matrix(bmod))
Returns the col_metadata tibble attached to a design matrix produced by
event_model(). If the attribute is missing (e.g., on a manually
constructed matrix) returns NULL.
design_meta(x)design_meta(x)
x |
A design matrix or any object with a |
A tibble, or NULL.
des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) design_meta(emod)des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) design_meta(emod)
Generator for use with the hrf_fun parameter in hrf(). Creates per-onset
HRFs by convolving a base HRF with a boxcar of each event's duration, then
normalizing to peak = 1. This preserves the temporal shape of the
duration-modulated response while equalizing amplitude across events.
duration_hrf_gen(base = fmrihrf::HRF_SPMG1, min_duration = 0)duration_hrf_gen(base = fmrihrf::HRF_SPMG1, min_duration = 0)
base |
Base HRF object. Default |
min_duration |
Minimum duration (prevents zero-width events). Default 0. |
A function for use with hrf_fun in hrf().
boxcar_hrf_gen() for duration-based boxcar HRFs
# Events with variable durations trial_data <- data.frame( onset = c(0, 10, 25), duration = c(2, 5, 3), condition = c("A", "B", "A"), run = 1 ) sf <- fmrihrf::sampling_frame(blocklens = 50, TR = 2) emod <- event_model( onset ~ hrf(condition, hrf_fun = duration_hrf_gen()), data = trial_data, block = ~run, sampling_frame = sf, durations = trial_data$duration ) print(emod)# Events with variable durations trial_data <- data.frame( onset = c(0, 10, 25), duration = c(2, 5, 3), condition = c("A", "B", "A"), run = 1 ) sf <- fmrihrf::sampling_frame(blocklens = 50, TR = 2) emod <- event_model( onset ~ hrf(condition, hrf_fun = duration_hrf_gen()), data = trial_data, block = ~run, sampling_frame = sf, durations = trial_data$duration ) print(emod)
Extract elements from an object
elements(x, ...) ## S3 method for class 'event' elements(x, what = c("values", "labels"), transformed = TRUE, ...) ## S3 method for class 'event_term' elements(x, what = c("values", "labels"), ...)elements(x, ...) ## S3 method for class 'event' elements(x, what = c("values", "labels"), transformed = TRUE, ...) ## S3 method for class 'event_term' elements(x, what = c("values", "labels"), ...)
x |
The object to extract elements from. |
... |
Additional arguments. |
what |
Character string specifying what to extract: "values" for numeric/actual values, or "labels" for descriptive labels/names. |
transformed |
Logical indicating whether to return transformed values. Default is TRUE. |
Requested elements; structure depends on method (e.g., numeric values or labels).
# Create an event term with mixed categorical and continuous events term <- event_term( list( condition = factor(c("A", "B", "A", "B")), intensity = c(1.2, 0.8, 1.5, 0.9) ), onsets = c(0, 10, 20, 30), blockids = c(1, 1, 1, 1) ) # Extract values (actual numeric/factor codes) elements(term, what = "values") # Extract labels (descriptive names/levels) elements(term, what = "labels")# Create an event term with mixed categorical and continuous events term <- event_term( list( condition = factor(c("A", "B", "A", "B")), intensity = c(1.2, 0.8, 1.5, 0.9) ), onsets = c(0, 10, 20, 30), blockids = c(1, 1, 1, 1) ) # Extract values (actual numeric/factor codes) elements(term, what = "values") # Extract labels (descriptive names/levels) elements(term, what = "labels")
This is a user-facing wrapper around the internal event() constructor,
specifically for creating event sequences modulated by a basis set.
event_basis( basis, name = NULL, onsets, blockids = 1, durations = 0, subset = NULL )event_basis( basis, name = NULL, onsets, blockids = 1, durations = 0, subset = NULL )
basis |
A |
name |
Optional name for the event variable. If NULL, uses |
onsets |
Numeric vector of event onsets (seconds). |
blockids |
Numeric vector of block IDs. |
durations |
Numeric vector of event durations (seconds), or a scalar. |
subset |
Optional logical vector indicating which events to keep. If
provided, the vector must match |
An S3 object of class event and event_seq.
basis <- BSpline(1:21, 3) onsets <- seq(0, 20, length.out = 21) blockids <- rep(1, length(onsets)) ebasis <- event_basis(basis, onsets=onsets, blockids=blockids) print(ebasis) levels(ebasis)basis <- BSpline(1:21, 3) onsets <- seq(0, 20, length.out = 21) blockids <- rep(1, length(onsets)) ebasis <- event_basis(basis, onsets=onsets, blockids=blockids) print(ebasis) levels(ebasis)
Retrieve per-event condition assignments
event_conditions(x, drop.empty = FALSE, ...)event_conditions(x, drop.empty = FALSE, ...)
x |
The object of interest. |
drop.empty |
Logical; drop unused levels when |
... |
Additional arguments passed to methods. |
Typically a factor aligned with the events of x.
term <- event_term( list(condition = factor(c("A", "B", "A"))), onsets = c(0, 10, 20), blockids = c(1, 1, 1) ) event_conditions(term)term <- event_term( list(condition = factor(c("A", "B", "A"))), onsets = c(0, 10, 20), blockids = c(1, 1, 1) ) event_conditions(term)
This is a user-facing wrapper around the internal event() constructor,
specifically for creating categorical event sequences from factors or characters.
event_factor(fac, name, onsets, blockids = 1, durations = 0, subset = NULL)event_factor(fac, name, onsets, blockids = 1, durations = 0, subset = NULL)
fac |
A factor or something coercible to a factor. |
name |
Name of the event variable. |
onsets |
Numeric vector of event onsets (seconds). |
blockids |
Numeric vector of block IDs. |
durations |
Numeric vector of event durations (seconds), or a scalar. |
subset |
Optional logical vector indicating which events to keep. If
provided, the vector must match Column names are sanitized using |
An S3 object of class event and event_seq.
event_model, event_variable, event_matrix, event_basis
ef_onsets <- seq(1, 100, length.out = 6) efac <- event_factor(factor(c("a", "b", "c", "a", "b", "c")), "abc", onsets = ef_onsets, blockids = rep(1, length(ef_onsets))) print(efac) levels(efac)ef_onsets <- seq(1, 100, length.out = 6) efac <- event_factor(factor(c("a", "b", "c", "a", "b", "c")), "abc", onsets = ef_onsets, blockids = rep(1, length(ef_onsets))) print(efac) levels(efac)
This is a user-facing wrapper around the internal event() constructor,
specifically for creating continuous event sequences from numeric matrices.
event_matrix(mat, name, onsets, blockids = 1, durations = 0, subset = NULL)event_matrix(mat, name, onsets, blockids = 1, durations = 0, subset = NULL)
mat |
A numeric matrix of continuous event values (one row per event). |
name |
Name of the event variable. |
onsets |
Numeric vector of event onsets (seconds). |
blockids |
Numeric vector of block IDs. |
durations |
Numeric vector of event durations (seconds), or a scalar. |
subset |
Optional logical vector indicating which events to keep. If
provided, the vector must match If |
An S3 object of class event and event_seq.
mat <- matrix(rnorm(20), 10, 2, dimnames=list(NULL, c("Val1", "Val2"))) onsets <- seq(1, 100, length.out = 10) durations <- rep(1, 10) blockids <- rep(1, 10) eset <- event_matrix(mat, "eset", onsets, blockids, durations) print(eset) columns(eset) # Alias for levelsmat <- matrix(rnorm(20), 10, 2, dimnames=list(NULL, c("Val1", "Val2"))) onsets <- seq(1, 100, length.out = 10) durations <- rep(1, 10) blockids <- rep(1, 10) eset <- event_matrix(mat, "eset", onsets, blockids, durations) print(eset) columns(eset) # Alias for levels
This file contains the generic functions used throughout the fmridesign package. These generics define the interface for working with event models, baseline models, and related design components. Construct an event model
This is the main constructor for event_model objects. It unifies the previous
formula and list-based interfaces and uses a more efficient internal pipeline.
event_model( formula_or_list, data = NULL, block = NULL, sampling_frame, durations = 0, drop_empty = TRUE, precision = 0.3, parallel = FALSE, progress = FALSE, strict = FALSE, ... ) event_model( formula_or_list, data = NULL, block = NULL, sampling_frame, durations = 0, drop_empty = TRUE, precision = 0.3, parallel = FALSE, progress = FALSE, strict = FALSE, ... )event_model( formula_or_list, data = NULL, block = NULL, sampling_frame, durations = 0, drop_empty = TRUE, precision = 0.3, parallel = FALSE, progress = FALSE, strict = FALSE, ... ) event_model( formula_or_list, data = NULL, block = NULL, sampling_frame, durations = 0, drop_empty = TRUE, precision = 0.3, parallel = FALSE, progress = FALSE, strict = FALSE, ... )
formula_or_list |
Either a formula (e.g., |
data |
A |
block |
A formula (e.g., |
sampling_frame |
An object of class |
durations |
Numeric vector or scalar specifying event durations (seconds). Default is 0. |
drop_empty |
Logical indicating whether to drop empty events during term construction. Default is TRUE. |
precision |
Numeric precision for HRF sampling/convolution. Default is 0.3. |
parallel |
Logical compatibility shim reserved for future use. The
current implementation always evaluates terms sequentially; when set to
|
progress |
Logical indicating whether to show a progress bar during term realisation. Default is FALSE. |
strict |
Logical controlling the onset bounds check. When |
... |
Additional arguments (currently unused). |
This function creates an event-based fMRI regression model, represented as a data structure.
The columns in the resulting design matrix follow the naming convention:
term_tag + _ + condition_tag + _b## basis suffix
Where:
term_tag: The unique tag assigned to the hrf() term (see below).
condition_tag: Represents the specific factor level or continuous regressor within the term (e.g., condition.A, poly_RT_01, condition.A_task.go).
_b##: Optional suffix added for HRFs with multiple basis functions (e.g., _b01, _b02).
Within a multi-basis term, columns are ordered condition-major: all basis
functions of the first condition, then all of the second, and so on
(cond.A_b01, cond.A_b02, cond.B_b01, cond.B_b02, ...). The order returned by
conditions(term, expand_basis = TRUE) is the same.
Each term in the model (typically defined by an hrf() call in a formula) gets a
unique term_tag. This tag is used as the prefix for all columns generated by that term.
Default Naming: If no explicit id (or name) is given in hrf(), the tag is derived
from the variable names (e.g., hrf(condition) -> condition, hrf(RT, acc) -> RT_acc).
Explicit Naming: Use id= within hrf() for an explicit tag (e.g., hrf(condition, id="CondMain")).
Sanitization: Dots (.) in tags are converted to underscores (_).
Clash Resolution: If multiple terms generate the same tag, # and a number are appended
to ensure uniqueness (e.g., condition, condition#1).
This consistent naming scheme replaces the previous compact and qualified styles.
An event_model object describing the task design.
An object of class c("event_model", "list") containing the terms, design matrix,
sampling frame, and other metadata.
des <- data.frame(onset = seq(0, 90, by=10), run = rep(1:2, each=5), cond = factor(rep(c("A","B"), 5)), mod = rnorm(10)) sframe <- fmrihrf::sampling_frame(blocklens=c(50, 60), TR=2) ev_model_form <- event_model(onset ~ hrf(cond) + hrf(mod, basis="spmg3"), data = des, block = ~run, sampling_frame = sframe) print(ev_model_form) head(design_matrix(ev_model_form)) spec1 <- hrf(cond) spec2 <- hrf(mod, basis = "spmg3") ev_model_list <- event_model(list(spec1, spec2), data = des, block = des$run, sampling_frame = sframe) print(ev_model_list)des <- data.frame(onset = seq(0, 90, by=10), run = rep(1:2, each=5), cond = factor(rep(c("A","B"), 5)), mod = rnorm(10)) sframe <- fmrihrf::sampling_frame(blocklens=c(50, 60), TR=2) ev_model_form <- event_model(onset ~ hrf(cond) + hrf(mod, basis="spmg3"), data = des, block = ~run, sampling_frame = sframe) print(ev_model_form) head(design_matrix(ev_model_form)) spec1 <- hrf(cond) spec2 <- hrf(mod, basis = "spmg3") ev_model_list <- event_model(list(spec1, spec2), data = des, block = des$run, sampling_frame = sframe) print(ev_model_list)
Extract event table
event_table(x, ...) ## S3 method for class 'convolved_term' event_table(x, ...) ## S3 method for class 'feature_term' event_table(x, ...)event_table(x, ...) ## S3 method for class 'convolved_term' event_table(x, ...) ## S3 method for class 'feature_term' event_table(x, ...)
x |
The object. |
... |
Additional arguments. |
A data.frame/tibble of event rows.
term <- event_term( list(condition = factor(c("A", "B", "A"))), onsets = c(0, 10, 20), blockids = c(1, 1, 1) ) event_table(term)term <- event_term( list(condition = factor(c("A", "B", "A"))), onsets = c(0, 10, 20), blockids = c(1, 1, 1) ) event_table(term)
Generates an event_term object which represents the combination of one
or more event sequences (e.g., a factor crossed with a numeric modulator).
It takes a list of variables (factors, numeric vectors, matrices, basis objects)
along with shared onsets, block IDs, and durations.
It uses the EV factory internally to create standardized event objects for each variable.
event_term(evlist, onsets, blockids, durations = 0, subset = NULL)event_term(evlist, onsets, blockids, durations = 0, subset = NULL)
evlist |
A named list of variables (factors, numeric, matrices, ParametricBasis objects). The names are used as variable identifiers within the term. |
onsets |
Numeric vector of onset times (in seconds). |
blockids |
Numeric vector of block numbers (non-decreasing integers). |
durations |
Numeric vector of event durations (seconds, default is 0).
Can be scalar (recycled) or vector matching length of |
subset |
Optional logical vector indicating which events to retain (applied before processing). |
A list object with class c("event_term", "event_seq"). Contains:
varname |
Concatenated variable names from |
events |
A named list of the processed |
subset |
The |
event_table |
A tibble representing the combinations of descriptive levels/names
for each event in the term, constructed using |
onsets |
Numeric vector of onsets (after processing/subsetting). |
blockids |
Numeric vector of block IDs (after processing/subsetting). |
durations |
Numeric vector of durations (after processing/subsetting). |
x1 <- factor(rep(letters[1:3], 10)) x2 <- factor(rep(1:3, each = 10)) onsets <- seq(1, 100, length.out = 30) blockids <- rep(1:3, each = 10) eterm <- event_term(list(Condition = x1, Group = x2), onsets = onsets, blockids = blockids) print(eterm) head(event_table(eterm)) levels(eterm) head(design_matrix(eterm)) term <- event_term( list(condition = factor(c("A", "B", "A"))), onsets = c(0, 10, 20), blockids = c(1, 1, 1) ) head(design_matrix(term))x1 <- factor(rep(letters[1:3], 10)) x2 <- factor(rep(1:3, each = 10)) onsets <- seq(1, 100, length.out = 30) blockids <- rep(1:3, each = 10) eterm <- event_term(list(Condition = x1, Group = x2), onsets = onsets, blockids = blockids) print(eterm) head(event_table(eterm)) levels(eterm) head(design_matrix(eterm)) term <- event_term( list(condition = factor(c("A", "B", "A"))), onsets = c(0, 10, 20), blockids = c(1, 1, 1) ) head(design_matrix(term))
Extract event terms
event_terms(x, ...)event_terms(x, ...)
x |
The object. |
... |
Additional arguments. |
A named list of event term objects.
# Create a simple experimental design des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) # Extract event terms (named list of event term objects) terms_list <- event_terms(emod) names(terms_list)# Create a simple experimental design des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) # Extract event terms (named list of event term objects) terms_list <- event_terms(emod) names(terms_list)
This is a user-facing wrapper around the internal event() constructor,
specifically for creating continuous event sequences from numeric vectors.
event_variable(vec, name, onsets, blockids = 1, durations = 0, subset = NULL)event_variable(vec, name, onsets, blockids = 1, durations = 0, subset = NULL)
vec |
Numeric vector representing continuous event values. |
name |
Name of the event variable. |
onsets |
Numeric vector of event onsets (seconds). |
blockids |
Numeric vector of block IDs. |
durations |
Numeric vector of event durations (seconds), or a scalar. |
subset |
Optional logical vector indicating which events to keep. If
provided, the vector must match |
An S3 object of class event and event_seq.
ev_onsets <- seq(1, 100, length.out = 6) evar <- event_variable(c(1, 2, 3, 4, 5, 6), "example_var", onsets = ev_onsets, blockids = rep(1, length(ev_onsets))) print(evar) is_continuous(evar)ev_onsets <- seq(1, 100, length.out = 6) evar <- event_variable(c(1, 2, 3, 4, 5, 6), "example_var", onsets = ev_onsets, blockids = rep(1, length(ev_onsets))) print(evar) is_continuous(evar)
Retrieve canonical event information
events(x, drop.empty = FALSE, ...) ## S3 method for class 'feature_term' events(x, ...)events(x, drop.empty = FALSE, ...) ## S3 method for class 'feature_term' events(x, ...)
x |
The object to summarise. |
drop.empty |
Logical; whether to drop empty conditions in the resulting factor. |
... |
Additional arguments passed to methods. |
A data.frame (or tibble) with onset, duration, block, and condition columns.
# Create an event term with condition factor term <- event_term( list(condition = factor(c("A", "B", "A"))), onsets = c(0, 10, 20), blockids = c(1, 1, 1) ) # Extract canonical event information evt_info <- events(term) print(evt_info)# Create an event term with condition factor term <- event_term( list(condition = factor(c("A", "B", "A"))), onsets = c(0, 10, 20), blockids = c(1, 1, 1) ) # Extract canonical event information evt_info <- events(term) print(evt_info)
Compute F-contrasts
Fcontrasts(x, ...) ## S3 method for class 'convolved_term' Fcontrasts(x, ...) ## S3 method for class 'event_model' Fcontrasts(x, ...) ## S3 method for class 'feature_term' Fcontrasts(x, ...)Fcontrasts(x, ...) ## S3 method for class 'convolved_term' Fcontrasts(x, ...) ## S3 method for class 'event_model' Fcontrasts(x, ...) ## S3 method for class 'feature_term' Fcontrasts(x, ...)
x |
The object. |
... |
Additional arguments. |
Row names of the contrast matrices can specify which levels of the term are tested. Any matching is done against the design matrix column names.
For terms with a multi-basis HRF (e.g. "spmg2", "spmg3", FIR), the
term-level contrast (one row per condition) is expanded to
: the condition effect is
tested jointly in every basis function, so a term with conditions
and basis functions yields a
matrix for its main effect. Columns are named <contrast column>_b##.
Terms with no categorical variable (e.g. hrf(rt), covariates, feature
terms) contribute no F-contrasts; a model made only of such terms returns
an empty list. Calling Fcontrasts() directly on such an event_term
still signals an error.
A named list of matrices with F-contrast weights.
des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) names(Fcontrasts(emod))des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) names(Fcontrasts(emod))
Specify a continuously sampled feature (for example RMS energy) to be
convolved with an HRF via fmrihrf::feature_regressor(). Unlike hrf(),
this is a time series, not a list of trials.
feature( x, dt = NULL, times = NULL, start = 0, center = TRUE, scale = c("none", "sd"), mask = NULL, basis = "spmg1", nbasis = 1, lag = 0, span = NULL, precision = NULL, id = NULL, name = NULL, prefix = NULL )feature( x, dt = NULL, times = NULL, start = 0, center = TRUE, scale = c("none", "sd"), mask = NULL, basis = "spmg1", nbasis = 1, lag = 0, span = NULL, precision = NULL, id = NULL, name = NULL, prefix = NULL )
x |
Numeric vector, matrix (samples x features), or a list of those (one per run). |
dt |
Positive sampling interval in seconds. Mutually exclusive with
|
times |
Sample times in seconds, or a list of per-run time vectors.
Mutually exclusive with |
start |
Start time in seconds used only when |
center, scale, mask, span
|
Passed to |
basis, nbasis, lag
|
HRF specification, as in |
precision |
Optional evaluation precision in seconds. When |
id, name, prefix
|
Term identifier used for column names. If omitted,
the name of |
x may be a numeric vector or a samples-by-features matrix (one run), or a
list of those with one element per sampling_frame block. Supply exactly
one of dt or times. Feature-only models are allowed:
event_model(~ feature(x, dt = 0.1, id = "rms"), sampling_frame = sframe).
A featurespec object for use on the RHS of an event_model()
formula or in the list interface.
fmrihrf::feature_regressor(), hrf(), event_model()
dt <- 0.5 rms <- abs(sin(seq(0, 20, by = dt))) sframe <- sampling_frame(blocklens = 15, TR = 2) emod <- event_model( ~ feature(rms, dt = dt, id = "rms", center = FALSE, scale = "none"), sampling_frame = sframe ) ncol(design_matrix(emod))dt <- 0.5 rms <- abs(sin(seq(0, 20, by = dt))) sframe <- sampling_frame(blocklens = 15, TR = 2) emod <- event_model( ~ feature(rms, dt = dt, id = "rms", center = FALSE, scale = "none"), sampling_frame = sframe ) ncol(design_matrix(emod))
Generates the f## suffix for multi-column continuous events.
feature_suffix(j, nf)feature_suffix(j, nf)
j |
Integer vector of feature indices (1-based). |
nf |
Total number of features. |
Character vector of suffixes (e.g., f01, f02).
feature_suffix(1:3, 5)feature_suffix(1:3, 5)
fmridesign_palette() returns the package's categorical palette (a
colour-vision-deficiency-checked ordering) or its diverging ramp, so custom
plots can match the built-in ones.
fmridesign_palette(type = c("categorical", "diverging"), n = NULL)fmridesign_palette(type = c("categorical", "diverging"), n = NULL)
type |
One of |
n |
Number of colours. For |
A character vector of hex colours.
fmridesign_palette("categorical", 4) fmridesign_palette("diverging", 11)fmridesign_palette("categorical", 4) fmridesign_palette("diverging", 11)
Re-exported functions from the fmrihrf package for convenience. See the upstream fmrihrf documentation for details on usage and return values of each function.
See the corresponding fmrihrf function documentation.
Returns all function names that should be recognized in formulas from registered external packages.
get_all_external_hrf_functions()get_all_external_hrf_functions()
Character vector of function names
register_hrfspec_extension( spec_class = "demo_hrfspec", package = "demoPkg", formula_functions = "demo_hrf" ) get_all_external_hrf_functions()register_hrfspec_extension( spec_class = "demo_hrfspec", package = "demoPkg", formula_functions = "demo_hrf" ) get_all_external_hrf_functions()
Accepts either a single class name or a class vector (the typical output
of class(x)). Returns the first matching registration entry, walking
the class vector from most-specific to least-specific so a subclass's
registration takes precedence over its parent.
get_basis_entry(class_name)get_basis_entry(class_name)
class_name |
Character string or character vector of class names. |
Registration entry (a list) or NULL if no class is registered.
get_basis_entry("Poly")get_basis_entry("Poly")
Returns the function name(s) that should be recognized in formulas for a given external HRF specification class.
get_external_hrfspec_functions(spec_class)get_external_hrfspec_functions(spec_class)
spec_class |
Character string naming the class |
Character vector of function names, or NULL if not registered
register_hrfspec_extension( spec_class = "demo_hrfspec", package = "demoPkg", formula_functions = c("demo_hrf", "demo_trialwise") ) get_external_hrfspec_functions("demo_hrfspec")register_hrfspec_extension( spec_class = "demo_hrfspec", package = "demoPkg", formula_functions = c("demo_hrf", "demo_trialwise") ) get_external_hrfspec_functions("demo_hrfspec")
Get Information About a Registered External HRF Specification
get_external_hrfspec_info(spec_class)get_external_hrfspec_info(spec_class)
spec_class |
Character string naming the class |
A list with registration information, or NULL if not registered
register_hrfspec_extension( spec_class = "demo_hrfspec", package = "demoPkg", requires_external_processing = TRUE, formula_functions = "demo_hrf" ) get_external_hrfspec_info("demo_hrfspec")register_hrfspec_extension( spec_class = "demo_hrfspec", package = "demoPkg", requires_external_processing = TRUE, formula_functions = "demo_hrf" ) get_external_hrfspec_info("demo_hrfspec")
This function is to be used in formulas for fitting functions, e.g. onsets ~ hrf(fac1,fac2) ...
It captures the variables/expressions provided and packages them with HRF/contrast
information into an hrfspec object, which is then processed by event_model.
hrf( ..., basis = "spmg1", hrf_fun = NULL, onsets = NULL, durations = NULL, prefix = NULL, subset = NULL, precision = 0.3, nbasis = 1, contrasts = NULL, id = NULL, name = NULL, lag = 0, summate = TRUE, normalize = FALSE )hrf( ..., basis = "spmg1", hrf_fun = NULL, onsets = NULL, durations = NULL, prefix = NULL, subset = NULL, precision = 0.3, nbasis = 1, contrasts = NULL, id = NULL, name = NULL, lag = 0, summate = TRUE, normalize = FALSE )
... |
One or more variable names (bare or character) or expressions involving variables
present in the |
basis |
the impulse response function or the name of a pre-supplied function,
one of: "gamma", "spmg1", "spmg2", "spmg3", "bspline", "gaussian", "tent", "bs".
Can also be an |
hrf_fun |
optional per-onset HRF generator. Can be:
When |
onsets |
optional onsets override. If missing, onsets will be taken from the LHS of the main model formula. |
durations |
optional durations override. If missing, durations argument from |
prefix |
a character string that is prepended to the variable names and used to identify the term.
Can be used to disambiguate two |
subset |
an expression indicating the subset of 'onsets' to keep. |
precision |
sampling precision in seconds. |
nbasis |
number of basis functions – only used for hemodynamic response functions (e.g. bspline) that take a variable number of bases. |
contrasts |
one or more |
id |
a unique |
name |
Optional human-readable name for the term. |
lag |
a temporal offset in seconds which is added to onset before convolution |
summate |
whether impulse amplitudes sum up when duration is greater than 0. |
normalize |
logical; if TRUE, each convolved regressor column is peak-normalized
so that |
an hrfspec instance
form1 <- onsets ~ hrf(condition, basis="spmg1") form2 <- onsets ~ hrf(condition) + hrf(RT) form3 <- onsets ~ hrf(condition, RT, basis="spmg3") library(rlang) con1 <- pair_contrast(~ condition == "A", ~ condition == "B", name="AvB") form4 <- onsets ~ hrf(condition, Poly(RT, 2), contrasts=con1) form5 <- onsets ~ hrf(condition, hrf_fun = boxcar_hrf_gen()) form6 <- onsets ~ hrf(condition, hrf_fun = weighted_hrf_gen("sub_times", "sub_weights"))form1 <- onsets ~ hrf(condition, basis="spmg1") form2 <- onsets ~ hrf(condition) + hrf(RT) form3 <- onsets ~ hrf(condition, RT, basis="spmg3") library(rlang) con1 <- pair_contrast(~ condition == "A", ~ condition == "B", name="AvB") form4 <- onsets ~ hrf(condition, Poly(RT, 2), contrasts=con1) form5 <- onsets ~ hrf(condition, hrf_fun = boxcar_hrf_gen()) form6 <- onsets ~ hrf(condition, hrf_fun = weighted_hrf_gen("sub_times", "sub_weights"))
A basis that applies identity transform to a set of raw variables.
Ident(...)Ident(...)
... |
a list of variable names |
an instance of class Ident extending ParametricBasis
# Create identity basis from numeric vectors x <- c(1, 2, 3, 4, 5) y <- c(2, 4, 6, 8, 10) ident_basis <- Ident(x, y) print(ident_basis$y)# Create identity basis from numeric vectors x <- c(1, 2, 3, 4, 5) y <- c(2, 4, 6, 8, 10) ident_basis <- Ident(x, y) print(ident_basis$y)
Create an interaction contrast specification
interaction_contrast(A, name, where = NULL)interaction_contrast(A, name, where = NULL)
A |
A formula specifying the interaction contrast |
name |
The name of the contrast |
where |
An optional formula specifying the subset over which the contrast is computed. |
An interaction_contrast_spec object containing the specification for generating interaction contrast weights
oneway_contrast for main effects,
pair_contrast for pairwise comparisons
# Create an interaction contrast for factors A and B con <- interaction_contrast(~ A * B, name = "A_by_B") # Create an interaction contrast with a 'where' clause con <- interaction_contrast(~ A * B, name = "A_by_B", where = ~ block == 1)# Create an interaction contrast for factors A and B con <- interaction_contrast(~ A * B, name = "A_by_B") # Create an interaction contrast with a 'where' clause con <- interaction_contrast(~ A * B, name = "A_by_B", where = ~ block == 1)
Check if categorical
is_categorical(x, ...) ## S3 method for class 'event' is_categorical(x, ...)is_categorical(x, ...) ## S3 method for class 'event' is_categorical(x, ...)
x |
The object. |
... |
Additional arguments. |
Logical scalar indicating whether x is categorical.
# Create a categorical event from factor data cat_event <- event_factor( factor(c("faces", "houses", "faces", "houses")), name = "condition", onsets = c(0, 10, 20, 30), blockids = rep(1, 4) ) is_categorical(cat_event) # Returns TRUE # Create a continuous event from numeric data cont_event <- event_variable( c(1.2, 0.8, 1.5, 0.9), name = "reaction_time", onsets = c(0, 10, 20, 30), blockids = rep(1, 4) ) is_categorical(cont_event) # Returns FALSE # Event term with mixed types is considered categorical mixed_term <- event_term( list(condition = factor(c("A", "B", "A", "B")), modulator = c(1.1, 0.9, 1.2, 0.8)), onsets = c(0, 10, 20, 30), blockids = rep(1, 4) ) is_categorical(mixed_term) # Returns TRUE# Create a categorical event from factor data cat_event <- event_factor( factor(c("faces", "houses", "faces", "houses")), name = "condition", onsets = c(0, 10, 20, 30), blockids = rep(1, 4) ) is_categorical(cat_event) # Returns TRUE # Create a continuous event from numeric data cont_event <- event_variable( c(1.2, 0.8, 1.5, 0.9), name = "reaction_time", onsets = c(0, 10, 20, 30), blockids = rep(1, 4) ) is_categorical(cont_event) # Returns FALSE # Event term with mixed types is considered categorical mixed_term <- event_term( list(condition = factor(c("A", "B", "A", "B")), modulator = c(1.1, 0.9, 1.2, 0.8)), onsets = c(0, 10, 20, 30), blockids = rep(1, 4) ) is_categorical(mixed_term) # Returns TRUE
Check if continuous
is_continuous(x, ...) ## S3 method for class 'event' is_continuous(x, ...)is_continuous(x, ...) ## S3 method for class 'event' is_continuous(x, ...)
x |
The object. |
... |
Additional arguments. |
Logical scalar indicating whether x is continuous.
# Create a continuous event from numeric vector cont_event <- event_variable( c(1.2, 0.8, 1.5, 0.9), name = "reaction_time", onsets = c(0, 10, 20, 30), blockids = rep(1, 4) ) is_continuous(cont_event) # Returns TRUE # Create a continuous event from matrix mat_event <- event_matrix( matrix(c(1.1, 0.9, 1.2, 0.8, 2.1, 1.9, 2.2, 1.8), nrow = 4), name = "coordinates", onsets = c(0, 10, 20, 30), blockids = rep(1, 4) ) is_continuous(mat_event) # Returns TRUE # Categorical event is not continuous cat_event <- event_factor( factor(c("faces", "houses", "faces", "houses")), name = "condition", onsets = c(0, 10, 20, 30), blockids = rep(1, 4) ) is_continuous(cat_event) # Returns FALSE # Event term with all continuous events cont_term <- event_term( list(rt = c(1.1, 0.9, 1.2, 0.8), accuracy = c(0.95, 0.87, 0.92, 0.88)), onsets = c(0, 10, 20, 30), blockids = rep(1, 4) ) is_continuous(cont_term) # Returns TRUE# Create a continuous event from numeric vector cont_event <- event_variable( c(1.2, 0.8, 1.5, 0.9), name = "reaction_time", onsets = c(0, 10, 20, 30), blockids = rep(1, 4) ) is_continuous(cont_event) # Returns TRUE # Create a continuous event from matrix mat_event <- event_matrix( matrix(c(1.1, 0.9, 1.2, 0.8, 2.1, 1.9, 2.2, 1.8), nrow = 4), name = "coordinates", onsets = c(0, 10, 20, 30), blockids = rep(1, 4) ) is_continuous(mat_event) # Returns TRUE # Categorical event is not continuous cat_event <- event_factor( factor(c("faces", "houses", "faces", "houses")), name = "condition", onsets = c(0, 10, 20, 30), blockids = rep(1, 4) ) is_continuous(cat_event) # Returns FALSE # Event term with all continuous events cont_term <- event_term( list(rt = c(1.1, 0.9, 1.2, 0.8), accuracy = c(0.95, 0.87, 0.92, 0.88)), onsets = c(0, 10, 20, 30), blockids = rep(1, 4) ) is_continuous(cont_term) # Returns TRUE
Check if a Class is a Registered External HRF Specification
is_external_hrfspec(x)is_external_hrfspec(x)
x |
An object or character string class name |
Logical indicating if the class is registered as an external HRF spec
register_hrfspec_extension( spec_class = "demo_hrfspec", package = "demoPkg" ) is_external_hrfspec("demo_hrfspec")register_hrfspec_extension( spec_class = "demo_hrfspec", package = "demoPkg" ) is_external_hrfspec("demo_hrfspec")
Returns a character vector of formatted labels for an event object,
using the Variable[Level] style for categorical events,
Variable[Index] for multi-column continuous events, or just
Variable for single continuous events.
Useful for getting consistent labels for individual event components.
This is distinct from levels() which returns the raw level names or column names.
Relies on the internal .level_vector helper function.
## S3 method for class 'event' labels(object, ...)## S3 method for class 'event' labels(object, ...)
object |
An object of class |
... |
Additional arguments (unused). |
A character vector of formatted labels, or character(0) if not applicable.
fac <- factor(rep(c("A", "B"), 3)) onsets <- 1:6 ev_fac <- event_factor(fac, "Condition", onsets, blockids = rep(1, length(onsets))) labels(ev_fac) # Should return c("Condition[A]", "Condition[B]") vals <- 1:6 ev_num <- event_variable(vals, "Modulator", onsets, blockids = rep(1, length(onsets))) labels(ev_num) # Should return "Modulator" mat <- matrix(1:12, 6, 2) colnames(mat) <- c("C1", "C2") ev_mat <- event_matrix(mat, "MatrixVar", onsets, blockids = rep(1, length(onsets))) labels(ev_mat) # Should return c("MatrixVar[1]", "MatrixVar[2]")fac <- factor(rep(c("A", "B"), 3)) onsets <- 1:6 ev_fac <- event_factor(fac, "Condition", onsets, blockids = rep(1, length(onsets))) labels(ev_fac) # Should return c("Condition[A]", "Condition[B]") vals <- 1:6 ev_num <- event_variable(vals, "Modulator", onsets, blockids = rep(1, length(onsets))) labels(ev_num) # Should return "Modulator" mat <- matrix(1:12, 6, 2) colnames(mat) <- c("C1", "C2") ev_mat <- event_matrix(mat, "MatrixVar", onsets, blockids = rep(1, length(onsets))) labels(ev_mat) # Should return c("MatrixVar[1]", "MatrixVar[2]")
Extract levels from various fmrireg objects. These methods extend the base R
levels generic to work with fmrireg-specific classes.
## S3 method for class 'Scale' levels(x, ...) ## S3 method for class 'ScaleWithin' levels(x, ...) ## S3 method for class 'RobustScale' levels(x, ...) ## S3 method for class 'event' levels(x, ...) ## S3 method for class 'event' columns(x, ...)## S3 method for class 'Scale' levels(x, ...) ## S3 method for class 'ScaleWithin' levels(x, ...) ## S3 method for class 'RobustScale' levels(x, ...) ## S3 method for class 'event' levels(x, ...) ## S3 method for class 'event' columns(x, ...)
x |
An object from which to extract levels. Can be:
|
... |
Additional arguments (currently unused). |
A character vector of levels or names, depending on the object type:
For categorical events: the factor levels
For continuous events: the column names (matrices) or variable name (vectors)
For scale objects: the variable name being scaled
columns(event): Alias for levels.event
# Create a categorical event fac_event <- event_factor( factor(c("A", "B", "A", "B")), name = "condition", onsets = c(1, 10, 20, 30), blockids = rep(1, 4) ) levels(fac_event) # Returns: c("A", "B") # Create a continuous event cont_event <- event_variable( c(1.2, 0.8, 1.5, 0.9), name = "reaction_time", onsets = c(1, 10, 20, 30), blockids = rep(1, 4) ) levels(cont_event) # Returns: "reaction_time"# Create a categorical event fac_event <- event_factor( factor(c("A", "B", "A", "B")), name = "condition", onsets = c(1, 10, 20, 30), blockids = rep(1, 4) ) levels(fac_event) # Returns: c("A", "B") # Create a continuous event cont_event <- event_variable( c(1.2, 0.8, 1.5, 0.9), name = "reaction_time", onsets = c(1, 10, 20, 30), blockids = rep(1, 4) ) levels(cont_event) # Returns: "reaction_time"
List All Registered External HRF Specifications
list_external_hrfspecs()list_external_hrfspecs()
A character vector of registered class names
register_hrfspec_extension( spec_class = "demo_hrfspec", package = "demoPkg" ) list_external_hrfspecs()register_hrfspec_extension( spec_class = "demo_hrfspec", package = "demoPkg" ) list_external_hrfspecs()
List Registered Parametric Basis Classes
list_registered_bases()list_registered_bases()
Character vector of registered class names.
list_registered_bases()list_registered_bases()
Superseded by conditions(x, style = "canonical").
## S3 method for class 'covariate_term' longnames(x, ...) ## S3 method for class 'covariate_convolved_term' longnames(x, ...) longnames(x, ...) ## S3 method for class 'event_model' longnames(x, drop.empty = TRUE, expand_basis = FALSE, ...) ## S3 method for class 'convolved_term' longnames(x, ...) ## S3 method for class 'event_seq' longnames(x, ...) ## S3 method for class 'feature_term' longnames(x, ...)## S3 method for class 'covariate_term' longnames(x, ...) ## S3 method for class 'covariate_convolved_term' longnames(x, ...) longnames(x, ...) ## S3 method for class 'event_model' longnames(x, drop.empty = TRUE, expand_basis = FALSE, ...) ## S3 method for class 'convolved_term' longnames(x, ...) ## S3 method for class 'event_seq' longnames(x, ...) ## S3 method for class 'feature_term' longnames(x, ...)
x |
The object. |
... |
Additional arguments. |
drop.empty |
Logical; leave out cells with no events (default |
expand_basis |
Logical; add a basis suffix for multi-basis HRFs
(default |
Long names are the canonical condition names: each factor level is
written variable.level, and the factors of an interaction are joined
with _ (for example condition.A_attn.x). With expand_basis = TRUE
a _bNN suffix is added for each HRF basis function.
They are not the design-matrix column names. A term's columns are
paste0(term_tag, "_", longnames(term, expand_basis = TRUE)), so the
column for level A of hrf(condition) is condition_condition.A, and
longnames(term) returns condition.A. Use columns() (or
colnames(design_matrix(x))) for the column names, and condition_map()
for a table that lines the two up.
With drop.empty = TRUE (the default) a cell of an interaction that has
no events is left out, as it is from the design matrix, so the names line
up one-to-one with the term's columns. drop.empty = FALSE lists the full
grid of factor levels, which is what conditions() always returns.
Methods exist for event_term, event_model (all terms in order),
convolved_term, feature_term, covariate terms, and bare events from
event_factor() and friends (event_seq), which are named as the
single-variable event_term built from them would be.
Character vector of long (fully qualified) names.
# Create a simple event term with one condition factor term <- event_term( list(condition = factor(c("A", "B", "A"))), onsets = c(0, 10, 20), blockids = c(1, 1, 1) ) longnames(term) # Returns: "condition.A" "condition.B" # Create event term with multiple factors term2 <- event_term( list( category = factor(c("face", "scene", "face")), attention = factor(c("attend", "attend", "ignore")) ), onsets = c(0, 10, 20), blockids = c(1, 1, 1) ) longnames(term2) # Returns: "category.face_attention.attend" # "category.scene_attention.attend" # "category.face_attention.ignore" # Long names versus design-matrix column names sf <- fmrihrf::sampling_frame(blocklens = 30, TR = 2) des <- data.frame(onset = c(0, 10, 20), run = 1, condition = factor(c("A", "B", "A"))) em <- event_model(onset ~ hrf(condition), data = des, block = ~run, sampling_frame = sf) longnames(em) # "condition.A" "condition.B" columns(em) # "condition_condition.A" "condition_condition.B"# Create a simple event term with one condition factor term <- event_term( list(condition = factor(c("A", "B", "A"))), onsets = c(0, 10, 20), blockids = c(1, 1, 1) ) longnames(term) # Returns: "condition.A" "condition.B" # Create event term with multiple factors term2 <- event_term( list( category = factor(c("face", "scene", "face")), attention = factor(c("attend", "attend", "ignore")) ), onsets = c(0, 10, 20), blockids = c(1, 1, 1) ) longnames(term2) # Returns: "category.face_attention.attend" # "category.scene_attention.attend" # "category.face_attention.ignore" # Long names versus design-matrix column names sf <- fmrihrf::sampling_frame(blocklens = 30, TR = 2) des <- data.frame(onset = c(0, 10, 20), run = 1, condition = factor(c("A", "B", "A"))) em <- event_model(onset ~ hrf(condition), data = des, block = ~run, sampling_frame = sf) longnames(em) # "condition.A" "condition.B" columns(em) # "condition_condition.A" "condition_condition.B"
onsets(), durations(), blockids() and nbasis() are fmrihrf's
generics, re-exported by fmridesign. fmridesign registers methods on them
for its own classes, so fmrihrf::onsets(term) and fmridesign::onsets(term)
are the same function and dispatch to the same methods, whichever package
is attached first.
fmridesign provides methods for:
onsets(), durations(): event_term, convolved_term
blockids(): event_term, convolved_term, event_model
nbasis(): hrfspec, convolved_term subclasses, feature_term
and the parametric basis classes (Poly, BSpline, Scale, ...)
Methods for fmrihrf's own classes (Reg, HRF, sampling_frame) are
documented in fmrihrf.
## S3 method for class 'covariate_convolved_term' nbasis(x, ...) ## S3 method for class 'convolved_term' nbasis(x, ...) ## S3 method for class 'feature_term' nbasis(x, ...)## S3 method for class 'covariate_convolved_term' nbasis(x, ...) ## S3 method for class 'convolved_term' nbasis(x, ...) ## S3 method for class 'feature_term' nbasis(x, ...)
x |
An object. |
... |
Passed to methods. |
See fmrihrf::onsets(), fmrihrf::durations(),
fmrihrf::blockids() and fmrihrf::nbasis().
term <- event_term( list(condition = factor(c("A", "B", "A"))), onsets = c(0, 10, 20), blockids = c(1, 1, 1), durations = c(2, 2, 2) ) onsets(term) durations(term) blockids(term) identical(onsets, fmrihrf::onsets)term <- event_term( list(condition = factor(c("A", "B", "A"))), onsets = c(0, 10, 20), blockids = c(1, 1, 1), durations = c(2, 2, 2) ) onsets(term) durations(term) blockids(term) identical(onsets, fmrihrf::onsets)
Get number of basis functions from hrfspec
## S3 method for class 'hrfspec' nbasis(x, ...)## S3 method for class 'hrfspec' nbasis(x, ...)
x |
An hrfspec object |
... |
Additional arguments (unused) |
The number of basis functions
# Create hrfspec with canonical HRF (1 basis function) spec1 <- hrf(condition, basis = "spmg1") nbasis(spec1) # Create hrfspec with derivative HRF (2 basis functions) spec2 <- hrf(condition, basis = "spmg2") nbasis(spec2) # Create hrfspec with FIR basis (custom number of basis functions) spec3 <- hrf(condition, basis = "fir", nbasis = 10) nbasis(spec3)# Create hrfspec with canonical HRF (1 basis function) spec1 <- hrf(condition, basis = "spmg1") nbasis(spec1) # Create hrfspec with derivative HRF (2 basis functions) spec2 <- hrf(condition, basis = "spmg2") nbasis(spec2) # Create hrfspec with FIR basis (custom number of basis functions) spec3 <- hrf(condition, basis = "fir", nbasis = 10) nbasis(spec3)
Returns a nuisance term specification from a numeric matrix.
nuisance(x)nuisance(x)
x |
A matrix. |
An object of class "nuisancespec".
mat <- matrix(rnorm(10), nrow = 5) nuisance(mat)mat <- matrix(rnorm(10), nrow = 5) nuisance(mat)
Construct contrasts comparing each factor level against the average of the other levels.
one_against_all_contrast(levels, facname, where = NULL)one_against_all_contrast(levels, facname, where = NULL)
levels |
A vector of factor levels to be compared. |
facname |
A character string specifying the name of the factor containing the supplied levels. |
where |
An optional formula specifying the subset over which the contrast is computed. |
A contrast_set object containing contrasts comparing each factor level against the average of the other levels.
fac <- factor(rep(c("A", "B", "C"), 2)) con <- one_against_all_contrast(levels(fac), "fac")fac <- factor(rep(c("A", "B", "C"), 2)) con <- one_against_all_contrast(levels(fac), "fac")
Create a one-way contrast specification
oneway_contrast(A, name, where = NULL, basis = NULL, basis_weights = NULL)oneway_contrast(A, name, where = NULL, basis = NULL, basis_weights = NULL)
A |
A formula specifying the contrast |
name |
The name of the contrast |
where |
An optional formula specifying the subset over which the contrast is computed. |
basis |
NULL (default: use all basis functions), an integer vector specifying
which basis function indices to include, or |
basis_weights |
NULL (default: equal weights), or a numeric vector of weights to apply
to the selected basis functions. Must have the same length as |
A oneway_contrast_spec object that can be used to generate contrast weights
interaction_contrast for testing interactions,
pair_contrast for pairwise comparisons
# Create a one-way contrast for a factor 'basis' con <- oneway_contrast(~ basis, name = "Main_basis") # Create a one-way contrast with a 'where' clause con <- oneway_contrast(~ basis, name = "Main_basis", where = ~ block == 1) # Test only first two basis functions con <- oneway_contrast(~ condition, name = "Main_early", basis = 1:2)# Create a one-way contrast for a factor 'basis' con <- oneway_contrast(~ basis, name = "Main_basis") # Create a one-way contrast with a 'where' clause con <- oneway_contrast(~ basis, name = "Main_basis", where = ~ block == 1) # Test only first two basis functions con <- oneway_contrast(~ condition, name = "Main_early", basis = 1:2)
Construct a sum-to-zero contrast between two logical expressions. This function is particularly useful for comparing specific conditions or combinations of conditions.
pair_contrast(A, B, name, where = NULL, basis = NULL, basis_weights = NULL)pair_contrast(A, B, name, where = NULL, basis = NULL, basis_weights = NULL)
A |
A formula representing the first logical expression in the contrast. |
B |
A formula representing the second logical expression in the contrast. |
name |
A character string specifying the name of the contrast (mandatory). |
where |
An optional formula specifying the subset over which the contrast is computed. |
basis |
NULL (default: use all basis functions), an integer vector specifying
which basis function indices to include (e.g., |
basis_weights |
NULL (default: equal weights), or a numeric vector of weights to apply
to the selected basis functions. Must have the same length as |
The contrast is constructed as (A - B), where A and B are logical expressions that evaluate to TRUE/FALSE for each observation. The resulting contrast weights sum to zero.
When using multi-basis HRFs (e.g., bspline with 5 basis functions), the basis argument
allows you to test specific temporal components of the response. For example:
basis = 1: Test only the first basis function (often the canonical/early response)
basis = 2:3: Test the second and third basis functions together
basis = NULL or basis = "all": Test all basis functions (default behavior)
With the default (basis = NULL), the single-column t-contrast places the
same weight on every basis column of a condition, i.e. it tests the sum of
the basis coefficients. For informed bases such as "spmg2"/"spmg3"
(canonical plus temporal/dispersion derivatives) that sum is rarely a
meaningful quantity; the SPM convention is to contrast the canonical
regressor only, so use basis = 1 there, or test all components jointly
with an F-contrast (e.g. oneway_contrast()).
The basis_weights argument allows non-uniform weighting across selected basis functions:
basis_weights = c(.1, .2, .4, .2, .1): Gaussian-like emphasis on peak
basis_weights = c(1, 0, 0, 0, 0): Isolate first basis (equivalent to basis = 1)
Weights are applied within each condition, maintaining contrast sum-to-zero property
A pair_contrast_spec object containing:
A |
First logical expression |
B |
Second logical expression |
where |
Subsetting formula (if provided) |
basis |
Basis function specification (if provided) |
basis_weights |
Basis weights (if provided) |
name |
Contrast name |
pairwise_contrasts for all pairwise comparisons,
contrast_set for creating sets of contrasts
# Compare faces vs scenes (all basis functions) pair_contrast(~ category == "face", ~ category == "scene", name = "face_vs_scene") # Test only the second basis function (e.g., linear component for polynomial HRF) pair_contrast(~ category == "face", ~ category == "scene", basis = 2, name = "face_vs_scene_basis2") # Test early response components (first 3 basis functions) pair_contrast(~ category == "face", ~ category == "scene", basis = 1:3, name = "face_vs_scene_early") # Compare with subsetting pair_contrast(~ category == "face", ~ category == "scene", name = "face_vs_scene_block1", where = ~ block == 1) # Complex logical expressions pair_contrast(~ stimulus == "face" & emotion == "happy", ~ stimulus == "face" & emotion == "sad", name = "happy_vs_sad_faces")# Compare faces vs scenes (all basis functions) pair_contrast(~ category == "face", ~ category == "scene", name = "face_vs_scene") # Test only the second basis function (e.g., linear component for polynomial HRF) pair_contrast(~ category == "face", ~ category == "scene", basis = 2, name = "face_vs_scene_basis2") # Test early response components (first 3 basis functions) pair_contrast(~ category == "face", ~ category == "scene", basis = 1:3, name = "face_vs_scene_early") # Compare with subsetting pair_contrast(~ category == "face", ~ category == "scene", name = "face_vs_scene_block1", where = ~ block == 1) # Complex logical expressions pair_contrast(~ stimulus == "face" & emotion == "happy", ~ stimulus == "face" & emotion == "sad", name = "happy_vs_sad_faces")
Construct pairwise contrasts for all combinations of factor levels.
pairwise_contrasts(levels, facname, where = NULL, name_prefix = "con")pairwise_contrasts(levels, facname, where = NULL, name_prefix = "con")
levels |
A vector of factor levels to be compared. |
facname |
The name of the factor variable (column name in the design) these levels belong to. |
where |
An optional formula specifying the subset over which the contrast is computed. |
name_prefix |
A character string to prefix the generated contrast names (default: "con"). |
A contrast_set object containing pairwise contrasts for all combinations of factor levels.
# Assuming 'my_factor' is a column name pairwise_contrasts(c("A", "B", "C"), facname = "my_factor") pairwise_contrasts(c("A", "B", "C"), facname = "my_factor", name_prefix = "pair")# Assuming 'my_factor' is a column name pairwise_contrasts(c("A", "B", "C"), facname = "my_factor") pairwise_contrasts(c("A", "B", "C"), facname = "my_factor", name_prefix = "pair")
Generic function for plotting contrasts.
plot_contrasts(x, ...)plot_contrasts(x, ...)
x |
Object containing contrast information |
... |
Additional arguments passed to methods |
A plot object (typically ggplot2) displaying the contrasts. The exact type depends on the method used.
# Create example data des <- data.frame( onset = c(1, 3, 5, 7), cond = factor(c("A", "B", "A", "B")), run = c(1, 1, 1, 1) ) # Create sampling frame and event model sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) # Create contrast set cset <- contrast_set( main_A = unit_contrast(~ cond == "A", name = "A_vs_baseline"), diff = pair_contrast(~ cond == "A", ~ cond == "B", name = "A_vs_B") ) # Create event model with contrasts emod <- event_model(onset ~ hrf(cond, contrasts = cset), data = des, block = ~run, sampling_frame = sframe) # Plot the contrasts plot_contrasts(emod)# Create example data des <- data.frame( onset = c(1, 3, 5, 7), cond = factor(c("A", "B", "A", "B")), run = c(1, 1, 1, 1) ) # Create sampling frame and event model sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) # Create contrast set cset <- contrast_set( main_A = unit_contrast(~ cond == "A", name = "A_vs_baseline"), diff = pair_contrast(~ cond == "A", ~ cond == "B", name = "A_vs_B") ) # Create event model with contrasts emod <- event_model(onset ~ hrf(cond, contrasts = cset), data = des, block = ~run, sampling_frame = sframe) # Plot the contrasts plot_contrasts(emod)
Shows every contrast defined on an event_model as a row of weights over
all design-matrix columns, in design order and grouped by term, so it
lines up column-for-column with design_map(). Weights use the package's
diverging palette, symmetric about zero up to the largest absolute weight
across all contrasts (stated in the legend), and every weight is printed:
zero weights sit at the neutral midpoint with a faint "0", so exclusion
reads as an explicit weight rather than a missing cell.
## S3 method for class 'event_model' plot_contrasts( x, absolute_limits = FALSE, rotate_x_text = TRUE, scale_mode = c("auto", "diverging", "one_sided"), coord_fixed = FALSE, annotate = NULL, title = "Contrast weights", subtitle = NULL, ... )## S3 method for class 'event_model' plot_contrasts( x, absolute_limits = FALSE, rotate_x_text = TRUE, scale_mode = c("auto", "diverging", "one_sided"), coord_fixed = FALSE, annotate = NULL, title = "Contrast weights", subtitle = NULL, ... )
x |
An |
absolute_limits |
Logical; if |
rotate_x_text |
Logical; angle column labels when they would overlap. |
scale_mode |
|
coord_fixed |
Logical; if |
annotate |
Logical or |
title, subtitle
|
Plot title and subtitle. |
... |
Passed to |
Two columns in the right margin check each row. "sum w" is the sum of the weights; non-zero sums are shown in a warning colour. The SE multiplier is sqrt(c' (X'X)^+ c), with X the design matrix plus one intercept per run: the standard error of the contrast estimate per unit of noise standard deviation, given this design (lower is better). Contrasts that are not estimable from the design are marked "not est.". F-contrasts appear as one row per component, numbered under the contrast name, each with its own values.
A ggplot object.
contrast_weights(), design_map()
des <- data.frame( onset = c(0, 10, 20, 30, 40, 50), run = 1, cond = factor(c("A", "B", "C", "A", "B", "C")) ) sframe <- fmrihrf::sampling_frame(blocklens = 60, TR = 1) cset <- contrast_set( A_vs_B = pair_contrast(~ cond == "A", ~ cond == "B", name = "A_vs_B"), B_vs_C = pair_contrast(~ cond == "B", ~ cond == "C", name = "B_vs_C") ) emod <- event_model(onset ~ hrf(cond, contrasts = cset), data = des, block = ~run, sampling_frame = sframe) plot_contrasts(emod)des <- data.frame( onset = c(0, 10, 20, 30, 40, 50), run = 1, cond = factor(c("A", "B", "C", "A", "B", "C")) ) sframe <- fmrihrf::sampling_frame(blocklens = 60, TR = 1) cset <- contrast_set( A_vs_B = pair_contrast(~ cond == "A", ~ cond == "B", name = "A_vs_B"), B_vs_C = pair_contrast(~ cond == "B", ~ cond == "C", name = "B_vs_C") ) emod <- event_model(onset ~ hrf(cond, contrasts = cset), data = des, block = ~run, sampling_frame = sframe) plot_contrasts(emod)
Draws every time-varying term of a baseline (nuisance) model on a shared time axis: one panel per term, with thin rules at run boundaries and run labels along the top. Lines never connect across run boundaries.
## S3 method for class 'baseline_model' plot( x, term_name = NULL, title = NULL, xlab = NULL, ylab = NULL, line_size = 0.5, color_palette = NULL, block_x = c("global", "run"), drift_scale = c("raw", "unit"), subtitle = NULL, ... )## S3 method for class 'baseline_model' plot( x, term_name = NULL, title = NULL, xlab = NULL, ylab = NULL, line_size = 0.5, color_palette = NULL, block_x = c("global", "run"), drift_scale = c("raw", "unit"), subtitle = NULL, ... )
x |
A |
term_name |
Optional name of a single term to plot (one of
|
title |
Plot title. Defaults to |
xlab |
Label for the x-axis. Defaults to a time label with units. |
ylab |
Label for the y-axis. By default |
line_size |
Line width in mm (default |
color_palette |
Ignored; retained for backward compatibility. Colours
follow the package palette (see |
block_x |
How to lay out runs on the x-axis: |
drift_scale |
|
subtitle |
Plot subtitle. Defaults to a summary of the model (drift basis and size, nuisance regressors per run, runs, scans and TR). |
... |
Additional arguments passed to |
Drift basis functions share one ordered colour ramp (darkest = first basis
function), so a basis function keeps its colour in every run. Nuisance
regressors keep the column names you supplied. When those names look like
rigid-body motion parameters (tx/ty/tz and rx/ry/rz,
trans_x/rot_x, x/y/z and pitch/roll/yaw), translations and
rotations get separate panels, because they are usually in different units
and rotations look flat on a shared axis. Each panel carries a key at its
right edge in column order; panels with more than 7 series use a legend
instead.
Terms that are constant within every run (run intercepts, a global
intercept, a constant drift basis) carry no time course and are left out;
the caption lists what was omitted. Request one explicitly with
term_name to draw it anyway. For spline and polynomial drift the caption
also gives a rough equivalent high-pass period, 2 * run duration / k for
k drift columns per run (the cutoff a discrete cosine basis with k
regressors would have); treat it as a guide, not an exact filter.
A ggplot2 object.
sframe <- fmrihrf::sampling_frame(blocklens = c(40, 40), TR = 2) nuis <- lapply(1:2, function(r) { m <- matrix(cumsum(rnorm(160, sd = 0.1)), 40, 4) colnames(m) <- c("tx", "ty", "rx", "ry") m }) bmod <- baseline_model(basis = "bs", degree = 4, sframe = sframe, nuisance_list = nuis) plot(bmod) plot(bmod, drift_scale = "unit") plot(bmod, term_name = "nuisance", block_x = "run")sframe <- fmrihrf::sampling_frame(blocklens = c(40, 40), TR = 2) nuis <- lapply(1:2, function(r) { m <- matrix(cumsum(rnorm(160, sd = 0.1)), 40, 4) colnames(m) <- c("tx", "ty", "rx", "ry") m }) bmod <- baseline_model(basis = "bs", degree = 4, sframe = sframe, nuisance_list = nuis) plot(bmod) plot(bmod, drift_scale = "unit") plot(bmod, term_name = "nuisance", block_x = "run")
Draws the convolved regressors of an event_model against time, with the
events that generate them marked underneath.
## S3 method for class 'event_model' plot( x, term_name = NULL, style = c("auto", "stacked", "overlay", "heatmap"), show_events = TRUE, facet_threshold = Inf, label_mode = c("auto", "compact", "none"), max_labels = 30, abbrev_min = 10, strip_text_size = 8.5, block_x = c("global", "run"), facet_by_block = FALSE, show_block_bounds = TRUE, y_scale = c("term", "row", "shared"), time_range = NULL, title = NULL, subtitle = NULL, ... )## S3 method for class 'event_model' plot( x, term_name = NULL, style = c("auto", "stacked", "overlay", "heatmap"), show_events = TRUE, facet_threshold = Inf, label_mode = c("auto", "compact", "none"), max_labels = 30, abbrev_min = 10, strip_text_size = 8.5, block_x = c("global", "run"), facet_by_block = FALSE, show_block_bounds = TRUE, y_scale = c("term", "row", "shared"), time_range = NULL, title = NULL, subtitle = NULL, ... )
x |
An |
term_name |
Character. Name of a specific term to plot. If |
style |
Layout; one of |
show_events |
Logical; draw event onset marks (rugs in stacked and
overlay styles, ticks in heatmap style). Default |
facet_threshold |
Integer. In |
label_mode |
Character. One of |
max_labels |
Integer. Label limit used by |
abbrev_min |
Integer. Minimum length used by |
strip_text_size |
Numeric. Size of row and panel labels. |
block_x |
Time axis for multi-run designs. |
facet_by_block |
Logical; if |
show_block_bounds |
Logical; draw rules at each run's start and end.
Drawn only when a |
y_scale |
How stacked rows share their amplitude axis. |
time_range |
Optional numeric length-2 vector (seconds, in the units of
the time axis) to zoom into, e.g. |
title, subtitle
|
Optional plot title and subtitle. |
... |
Unused; accepted for compatibility. |
The default style = "auto" picks the layout that stays readable for the
design at hand:
"stacked": one row per condition on a shared time axis. Each row is
scaled on its own so response shapes stay visible, and a rug under each
trace marks the onsets of that condition's events. Basis sets (e.g.
SPMG3) are drawn in the same row, distinguished by line type.
"heatmap": one raster row per regressor, used automatically for large
designs such as trialwise (beta-series) models, where overlapping traces
are unreadable. Rows are ordered by first onset.
"overlay": all regressors on one shared amplitude axis, useful for
comparing magnitudes directly.
Runs are shown as alternating light bands labelled along the top edge, with thin rules at each run's start and end so late starts and overruns are easy to spot. Lines never connect across a run boundary.
A ggplot2 object.
des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) plot(emod) plot(emod, style = "overlay") plot(emod, term_name = "cond")des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) plot(emod) plot(emod, style = "overlay") plot(emod, term_name = "cond")
Visualizes the runs of a sampling_frame (from fmrihrf) over time.
Printing a sampling_frame is handled by fmrihrf's own print() method.
## S3 method for class 'sampling_frame' plot( x, style = c("timeline", "grid", "lane"), show_ticks = FALSE, tick_every = 5, events = NULL, title = NULL, subtitle = NULL, ... )## S3 method for class 'sampling_frame' plot( x, style = c("timeline", "grid", "lane"), show_ticks = FALSE, tick_every = 5, events = NULL, title = NULL, subtitle = NULL, ... )
x |
A |
style |
Plot style. One of |
show_ticks |
Logical; whether to show per-TR tick marks along each
run (timeline style only). Default |
tick_every |
Integer; draw a tick every |
events |
Optional events to overlay as a coverage
check: an |
title, subtitle
|
Optional title and subtitle; the defaults describe the acquisition (runs, scans, TR, total duration). |
... |
Unused. |
A ggplot object.
sf <- fmrihrf::sampling_frame(blocklens = c(60, 120), TR = 2) plot(sf)sf <- fmrihrf::sampling_frame(blocklens = c(60, 120), TR = 2) plot(sf)
Orthogonal polynomial expansion of a linear term based on poly
Poly(x, degree)Poly(x, degree)
x |
a numeric vector at which to evaluate the polynomial. Missing values are not allowed in x. |
degree |
the degree of the polynomial. Must be less than the number of unique points. |
an instance of class Poly extending ParametricBasis
# Create a 3rd degree polynomial basis x_vals <- c(1, 2, 3, 4, 5, 6) poly_basis <- Poly(x_vals, degree = 3) print(poly_basis$y)# Create a 3rd degree polynomial basis x_vals <- c(1, 2, 3, 4, 5, 6) poly_basis <- Poly(x_vals, degree = 3) print(poly_basis$y)
Create polynomial contrasts for testing trends across ordered factor levels. This is particularly useful for analyzing factors with a natural ordering (e.g., time, dose).
poly_contrast( A, name, where = NULL, degree = 1, value_map = NULL, basis = NULL, basis_weights = NULL )poly_contrast( A, name, where = NULL, degree = 1, value_map = NULL, basis = NULL, basis_weights = NULL )
A |
A formula specifying the ordered factor. |
name |
A character string identifying the contrast. |
where |
An optional formula for subsetting the data. |
degree |
An integer specifying the degree of the polynomial (default: 1). |
value_map |
An optional list mapping factor levels to numeric values. |
basis |
NULL (default: use all basis functions), an integer vector specifying
which basis function indices to include, or |
basis_weights |
NULL (default: equal weights), or a numeric vector of weights to apply
to the selected basis functions. Must have the same length as |
The function creates orthogonal polynomial contrasts up to the specified degree. These contrasts can test for linear, quadratic, cubic, and higher-order trends in the data. The value_map parameter allows for non-uniform spacing between levels.
A poly_contrast_spec object containing the specification for generating polynomial contrast weights.
oneway_contrast for categorical contrasts,
interaction_contrast for interaction effects
# Linear trend across time points pcon <- poly_contrast(~ time, name = "linear_time", degree = 1) # Cubic trend with custom spacing pcon <- poly_contrast(~ dose, name = "dose_cubic", degree = 3, value_map = list("low" = 0, "med" = 2, "high" = 5)) # Linear trend for only first basis function pcon <- poly_contrast(~ dose, name = "dose_linear_basis1", degree = 1, basis = 1)# Linear trend across time points pcon <- poly_contrast(~ time, name = "linear_time", degree = 1) # Cubic trend with custom spacing pcon <- poly_contrast(~ dose, name = "dose_cubic", degree = 3, value_map = list("low" = 0, "med" = 2, "high" = 5)) # Linear trend for only first basis function pcon <- poly_contrast(~ dose, name = "dose_linear_basis1", degree = 1, basis = 1)
Dispatch to the appropriate method for transforming new data according to a specific parametric basis.
## S3 method for class 'ParametricBasis' predict(object, newdata, ...) ## S3 method for class 'Standardized' predict(object, newdata, ...) ## S3 method for class 'Poly' predict(object, newdata, ...) ## S3 method for class 'BSpline' predict(object, newdata, ...) ## S3 method for class 'Ident' predict(object, newdata, ...) ## S3 method for class 'Scale' predict(object, newdata, ...) ## S3 method for class 'ScaleWithin' predict(object, newdata, newgroup, ...) ## S3 method for class 'RobustScale' predict(object, newdata, ...)## S3 method for class 'ParametricBasis' predict(object, newdata, ...) ## S3 method for class 'Standardized' predict(object, newdata, ...) ## S3 method for class 'Poly' predict(object, newdata, ...) ## S3 method for class 'BSpline' predict(object, newdata, ...) ## S3 method for class 'Ident' predict(object, newdata, ...) ## S3 method for class 'Scale' predict(object, newdata, ...) ## S3 method for class 'ScaleWithin' predict(object, newdata, newgroup, ...) ## S3 method for class 'RobustScale' predict(object, newdata, ...)
object |
ParametricBasis object. |
newdata |
Numeric vector to transform. |
... |
Additional arguments. |
newgroup |
Optional factor for group-dependent bases. |
A numeric matrix with transformed values (one column per basis component).
# Create polynomial basis from training data train_x <- 1:10 poly_basis <- Poly(train_x, degree = 2) # Predict on new data new_x <- c(5.5, 7.3, 11.2) predict(poly_basis, new_x) # Create scaling basis train_vals <- c(10, 20, 30, 40, 50) scale_basis <- Scale(train_vals) # Apply same scaling to new data new_vals <- c(15, 25, 35) predict(scale_basis, new_vals)# Create polynomial basis from training data train_x <- 1:10 poly_basis <- Poly(train_x, degree = 2) # Predict on new data new_x <- c(5.5, 7.3, 11.2) predict(poly_basis, new_x) # Create scaling basis train_vals <- c(10, 20, 30, 40, 50) scale_basis <- Scale(train_vals) # Apply same scaling to new data new_vals <- c(15, 25, 35) predict(scale_basis, new_vals)
Displays key information about the baseline model components and a preview of the design matrix.
Print a contrast set.
Print a contrast specification.
Print a contrast.
Print a polynomial contrast specification.
Print a contrast difference specification.
Provides a concise summary of an event object using cli.
Provides a concise summary of an event_model object using cli.
Provides a concise summary of an event_term object using cli.
## S3 method for class 'baseline_model' print(x, ...) ## S3 method for class 'contrast_set' print(x, ...) ## S3 method for class 'contrast_spec' print(x, ...) ## S3 method for class 'contrast' print(x, ...) ## S3 method for class 'poly_contrast_spec' print(x, ...) ## S3 method for class 'contrast_diff_spec' print(x, ...) ## S3 method for class 'event' print(x, ...) ## S3 method for class 'event_model' print(x, ...) ## S3 method for class 'fmri_term' print(x, ...) ## S3 method for class 'convolved_term' print(x, ...) ## S3 method for class 'event_term' print(x, ...) ## S3 method for class 'feature_term' print(x, ...)## S3 method for class 'baseline_model' print(x, ...) ## S3 method for class 'contrast_set' print(x, ...) ## S3 method for class 'contrast_spec' print(x, ...) ## S3 method for class 'contrast' print(x, ...) ## S3 method for class 'poly_contrast_spec' print(x, ...) ## S3 method for class 'contrast_diff_spec' print(x, ...) ## S3 method for class 'event' print(x, ...) ## S3 method for class 'event_model' print(x, ...) ## S3 method for class 'fmri_term' print(x, ...) ## S3 method for class 'convolved_term' print(x, ...) ## S3 method for class 'event_term' print(x, ...) ## S3 method for class 'feature_term' print(x, ...)
x |
An event_term object. |
... |
Additional arguments (unused). |
The input object, invisibly.
sframe <- fmrihrf::sampling_frame(blocklens = 5, TR = 1) bmod <- baseline_model(sframe = sframe) print(bmod)sframe <- fmrihrf::sampling_frame(blocklens = 5, TR = 1) bmod <- baseline_model(sframe = sframe) print(bmod)
Register a basis class so that the term-naming pipeline produces a
well-formed term tag (<prefix>_<varname>) and so that design-matrix
metadata identifies columns built from this basis as parametric.
Built-in bases (Poly, BSpline, Scale, Standardized,
ScaleWithin, RobustScale, Ident) are registered automatically.
register_basis( class_name, prefix = NULL, modulation = c("parametric", "amplitude"), description = NULL )register_basis( class_name, prefix = NULL, modulation = c("parametric", "amplitude"), description = NULL )
class_name |
Character string naming the S3 class extending
|
prefix |
Character string used as the term-tag prefix for terms whose
sole variable is |
modulation |
Character string describing the modulation kind for
columns generated by this basis. Defaults to |
description |
Optional human-readable description. |
Invisibly returns the registration entry.
# Register a custom orthogonal-polynomial basis with prefix "ortho" register_basis("OrthoPoly", prefix = "ortho")# Register a custom orthogonal-polynomial basis with prefix "ortho" register_basis("OrthoPoly", prefix = "ortho")
Register a new HRF specification class that can be used in event models. This allows external packages to extend fmridesign with their own HRF types.
register_hrfspec_extension( spec_class, package, convolved_class = NULL, requires_external_processing = FALSE, formula_functions = NULL )register_hrfspec_extension( spec_class, package, convolved_class = NULL, requires_external_processing = FALSE, formula_functions = NULL )
spec_class |
Character string naming the class to register |
package |
Character string naming the package providing the class |
convolved_class |
Optional character string naming the associated convolved term class |
requires_external_processing |
Logical indicating if this spec should be skipped during standard convolution (e.g., for AFNI terms that are processed externally) |
formula_functions |
Optional character vector of function names that should be recognised in formulas and mapped to this HRF specification class. |
Invisible NULL
register_hrfspec_extension( spec_class = "afni_hrfspec", package = "afnireg", convolved_class = "afni_hrf_convolved_term", requires_external_processing = TRUE, formula_functions = "afni_hrf" )register_hrfspec_extension( spec_class = "afni_hrfspec", package = "afnireg", convolved_class = "afni_hrf_convolved_term", requires_external_processing = TRUE, formula_functions = "afni_hrf" )
Convolve the event-term design matrix with an HRF and return the resulting regressors.
regressors(x, ...) ## S3 method for class 'event_term' regressors(x, hrf, sampling_frame, summate = FALSE, drop.empty = TRUE, ...)regressors(x, ...) ## S3 method for class 'event_term' regressors(x, hrf, sampling_frame, summate = FALSE, drop.empty = TRUE, ...)
x |
The object. |
... |
Additional arguments. |
hrf |
HRF function |
sampling_frame |
sampling_frame object |
summate |
Logical; sum HRF responses |
drop.empty |
Logical; drop empty conditions |
Character vector of regressor names for x.
# Create an event term with two conditions term <- event_term( list(condition = factor(c("A", "B", "A", "B"))), onsets = c(0, 10, 20, 30), blockids = c(1, 1, 1, 1) ) # Create a sampling frame for timing information sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 2) # Extract regressors convolved with canonical HRF reg <- regressors(term, hrf = fmrihrf::HRF_SPMG1, sampling_frame = sframe) names(reg) # Shows regressor names: "condition.A" "condition.B"# Create an event term with two conditions term <- event_term( list(condition = factor(c("A", "B", "A", "B"))), onsets = c(0, 10, 20, 30), blockids = c(1, 1, 1, 1) ) # Create a sampling frame for timing information sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 2) # Extract regressors convolved with canonical HRF reg <- regressors(term, hrf = fmrihrf::HRF_SPMG1, sampling_frame = sframe) names(reg) # Shows regressor names: "condition.A" "condition.B"
Determines if an HRF specification or convolved term should be handled by external tools rather than R's standard convolution.
requires_external_processing(x)requires_external_processing(x)
x |
An object to check |
Logical indicating if external processing is required
register_hrfspec_extension( spec_class = "demo_hrfspec", package = "demoPkg", requires_external_processing = TRUE ) requires_external_processing("demo_hrfspec")register_hrfspec_extension( spec_class = "demo_hrfspec", package = "demoPkg", requires_external_processing = TRUE ) requires_external_processing("demo_hrfspec")
Projects the data onto the orthogonal complement of the design, returning
residuals from an OLS fit. Specialized for event_model, baseline_model,
or a raw numeric design matrix.
residualize(x, data, cols = NULL, ...)residualize(x, data, cols = NULL, ...)
x |
A design object ( |
data |
A numeric vector/matrix/data.frame of observations Y with rows matching |
cols |
Optional integer or character vector selecting columns of the design to project out. |
... |
Additional arguments passed to methods. |
Residuals with the same dimensions as data.
# Simple example with a raw design matrix X <- cbind(1, 1:5) Y <- cbind(1:5, 2:6) R <- residualize(X, Y) dim(R)# Simple example with a raw design matrix X <- cbind(1, 1:5) Y <- cbind(1:5, 2:6) R <- residualize(X, Y) dim(R)
S3 methods for the residualize() generic. These methods project data
onto the orthogonal complement of a design, returning OLS residuals.
## S3 method for class 'matrix' residualize(x, data, cols = NULL, ...) ## S3 method for class 'event_model' residualize(x, data, cols = NULL, ...) ## S3 method for class 'baseline_model' residualize(x, data, cols = NULL, ...)## S3 method for class 'matrix' residualize(x, data, cols = NULL, ...) ## S3 method for class 'event_model' residualize(x, data, cols = NULL, ...) ## S3 method for class 'baseline_model' residualize(x, data, cols = NULL, ...)
x |
A design object: matrix, event_model, or baseline_model. |
data |
Numeric vector/matrix/data.frame of observations Y. |
cols |
Optional integer or character vector selecting columns to project out. |
... |
Additional arguments (currently unused). |
A numeric matrix of residuals with the same dimensions as data.
# Residualize with a raw matrix X <- cbind(1, 1:10) Y <- matrix(rnorm(20), ncol = 2) R <- residualize(X, Y) dim(R) # 10 x 2 # Residualize with an event model des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) Y_sim <- matrix(rnorm(40 * 2), ncol = 2) R_emod <- residualize(emod, Y_sim) dim(R_emod) # 40 x 2# Residualize with a raw matrix X <- cbind(1, 1:10) Y <- matrix(rnorm(20), ncol = 2) R <- residualize(X, Y) dim(R) # 10 x 2 # Residualize with an event model des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) Y_sim <- matrix(rnorm(40 * 2), ncol = 2) R_emod <- residualize(emod, Y_sim) dim(R_emod) # 40 x 2
Robust Scaling (Median/MAD)
RobustScale(x)RobustScale(x)
x |
numeric vector (NAs allowed) |
object of class c("RobustScale","ParametricBasis")
# Create a robust scale transformed basis using median and MAD x_vals <- c(1, 2, 3, 4, 100) # Note the outlier robust_basis <- RobustScale(x_vals) print(robust_basis$y) print(robust_basis$median) print(robust_basis$mad)# Create a robust scale transformed basis using median and MAD x_vals <- c(1, 2, 3, 4, 100) # Note the outlier robust_basis <- RobustScale(x_vals) print(robust_basis$y) print(robust_basis$median) print(robust_basis$mad)
Wraps make.names but allows control over dot replacement.
sanitize(x, allow_dot = TRUE)sanitize(x, allow_dot = TRUE)
x |
A character vector. |
allow_dot |
Logical, if |
A sanitized character vector.
sanitize("a.b c") sanitize("a.b c", allow_dot = FALSE)sanitize("a.b c") sanitize("a.b c", allow_dot = FALSE)
Z-score (global) basis
Scale(x)Scale(x)
x |
numeric vector (NAs allowed) |
object of class c("Scale","ParametricBasis")
# Create a z-score transformed basis x_vals <- c(1, 3, 5, 7, 9, 11) scale_basis <- Scale(x_vals) print(scale_basis$y) print(scale_basis$mean) print(scale_basis$sd)# Create a z-score transformed basis x_vals <- c(1, 3, 5, 7, 9, 11) scale_basis <- Scale(x_vals) print(scale_basis$y) print(scale_basis$mean) print(scale_basis$sd)
Z-score within groups
ScaleWithin(x, g)ScaleWithin(x, g)
x |
numeric vector |
g |
grouping factor / character / integer of same length as x |
An object of class ScaleWithin (a ParametricBasis).
# Create a within-group z-score transformed basis x_vals <- c(1, 2, 3, 10, 11, 12) groups <- c("A", "A", "A", "B", "B", "B") scale_within_basis <- ScaleWithin(x_vals, groups) print(scale_within_basis$y) print(scale_within_basis$means) print(scale_within_basis$sds)# Create a within-group z-score transformed basis x_vals <- c(1, 2, 3, 10, 11, 12) groups <- c("A", "A", "A", "B", "B", "B") scale_within_basis <- ScaleWithin(x_vals, groups) print(scale_within_basis$y) print(scale_within_basis$means) print(scale_within_basis$sds)
Superseded by conditions(x, style = "display").
## S3 method for class 'covariate_term' shortnames(x, ...) ## S3 method for class 'covariate_convolved_term' shortnames(x, ...) shortnames(x, ...) ## S3 method for class 'event_model' shortnames(x, drop.empty = TRUE, ...) ## S3 method for class 'convolved_term' shortnames(x, ...) ## S3 method for class 'event_seq' shortnames(x, ...) ## S3 method for class 'feature_term' shortnames(x, ...)## S3 method for class 'covariate_term' shortnames(x, ...) ## S3 method for class 'covariate_convolved_term' shortnames(x, ...) shortnames(x, ...) ## S3 method for class 'event_model' shortnames(x, drop.empty = TRUE, ...) ## S3 method for class 'convolved_term' shortnames(x, ...) ## S3 method for class 'event_seq' shortnames(x, ...) ## S3 method for class 'feature_term' shortnames(x, ...)
x |
The object. |
... |
Additional arguments. |
drop.empty |
Logical; leave out cells with no events (default |
Short names give the factor levels only, joined with : for
interactions (for example A:x). See longnames() for the qualified
names and how they relate to design-matrix columns.
Character vector of short names.
# Create a simple event term with one condition factor term <- event_term( list(condition = factor(c("A", "B", "A"))), onsets = c(0, 10, 20), blockids = c(1, 1, 1) ) shortnames(term) # Returns: "A" "B" # Create event term with multiple factors term2 <- event_term( list( category = factor(c("face", "scene", "face")), attention = factor(c("attend", "attend", "ignore")) ), onsets = c(0, 10, 20), blockids = c(1, 1, 1) ) shortnames(term2) # Returns: "face:attend" "scene:attend" "face:ignore"# Create a simple event term with one condition factor term <- event_term( list(condition = factor(c("A", "B", "A"))), onsets = c(0, 10, 20), blockids = c(1, 1, 1) ) shortnames(term) # Returns: "A" "B" # Create event term with multiple factors term2 <- event_term( list( category = factor(c("face", "scene", "face")), attention = factor(c("attend", "attend", "ignore")) ), onsets = c(0, 10, 20), blockids = c(1, 1, 1) ) shortnames(term2) # Returns: "face:attend" "scene:attend" "face:ignore"
Generate a set of A-vs-B contrasts where A and B are adjacent, equally sized
and disjoint windows over an ordered factor. For window size k, contrast i
compares A = levels[i:(i+k-1)] against B = levels[(i+k):(i+2k-1)].
This yields length(levels) - 2*k + 1 contrasts that detect local changes
across the sequence without overlapping masks.
sliding_window_contrasts( levels, facname, window_size = 2, where = NULL, name_prefix = "win" )sliding_window_contrasts( levels, facname, window_size = 2, where = NULL, name_prefix = "win" )
levels |
Character vector of ordered factor levels. |
facname |
Name of the factor (column in the design). |
window_size |
Positive integer window size (default 2). |
where |
Optional formula to subset events used when computing weights. |
name_prefix |
Prefix for generated contrast names (default "win"). |
A contrast_set of pair_contrast specifications.
# For levels 1..5, generate 2 disjoint adjacent-window contrasts (k=2) sliding_window_contrasts(as.character(1:5), facname = "intensity", window_size = 2) # For k=3 with 7 levels (disjoint windows): # A=[1,2,3] vs B=[4,5,6], then A=[2,3,4] vs B=[5,6,7] sliding_window_contrasts(LETTERS[1:7], facname = "difficulty", window_size = 3)# For levels 1..5, generate 2 disjoint adjacent-window contrasts (k=2) sliding_window_contrasts(as.character(1:5), facname = "intensity", window_size = 2) # For k=3 with 7 levels (disjoint windows): # A=[1,2,3] vs B=[4,5,6], then A=[2,3,4] vs B=[5,6,7] sliding_window_contrasts(LETTERS[1:7], facname = "difficulty", window_size = 3)
Split by block
split_by_block(x, ...) ## S3 method for class 'event_model' split_by_block(x, ...)split_by_block(x, ...) ## S3 method for class 'event_model' split_by_block(x, ...)
x |
The object. |
... |
Additional arguments. |
A list split by block/run.
des <- data.frame( onset = c(0, 10, 20, 30, 5, 15, 25, 35), run = c(1, 1, 1, 1, 2, 2, 2, 2), cond = factor(c("A", "B", "A", "B", "A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = c(40, 40), TR = 1) emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) block_list <- split_by_block(emod) length(block_list)des <- data.frame( onset = c(0, 10, 20, 30, 5, 15, 25, 35), run = c(1, 1, 1, 1, 2, 2, 2, 2), cond = factor(c("A", "B", "A", "B", "A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = c(40, 40), TR = 1) emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) block_list <- split_by_block(emod) length(block_list)
Split onsets
split_onsets(x, sframe, global = FALSE, blocksplit = FALSE, ...) ## S3 method for class 'event_term' split_onsets(x, sframe, global = FALSE, blocksplit = FALSE, ...)split_onsets(x, sframe, global = FALSE, blocksplit = FALSE, ...) ## S3 method for class 'event_term' split_onsets(x, sframe, global = FALSE, blocksplit = FALSE, ...)
x |
The object. |
sframe |
The sampling frame object containing timing information. |
global |
Whether onsets are in global time units (across all runs). |
blocksplit |
Whether to split onsets by blocks. |
... |
Additional arguments. |
A list of onset vectors, one per block (unless global=TRUE).
# Create an event term with mixed conditions across blocks conditions <- factor(c("A", "B", "A", "B", "A", "B")) onsets <- c(5, 15, 25, 105, 115, 125) # Events in blocks 1 and 2 blockids <- c(1, 1, 1, 2, 2, 2) term <- event_term( list(condition = conditions), onsets = onsets, blockids = blockids ) # Create sampling frame for two blocks of 50 TRs each sframe <- fmrihrf::sampling_frame(blocklens = c(50, 50), TR = 2) # Split onsets by condition (default behavior) onset_list <- split_onsets(term, sframe) names(onset_list) # Shows condition names onset_list$condition.A # Onsets for condition A # Split with global timing (onsets relative to start of experiment) global_onsets <- split_onsets(term, sframe, global = TRUE) # Split by both condition and block block_split <- split_onsets(term, sframe, blocksplit = TRUE)# Create an event term with mixed conditions across blocks conditions <- factor(c("A", "B", "A", "B", "A", "B")) onsets <- c(5, 15, 25, 105, 115, 125) # Events in blocks 1 and 2 blockids <- c(1, 1, 1, 2, 2, 2) term <- event_term( list(condition = conditions), onsets = onsets, blockids = blockids ) # Create sampling frame for two blocks of 50 TRs each sframe <- fmrihrf::sampling_frame(blocklens = c(50, 50), TR = 2) # Split onsets by condition (default behavior) onset_list <- split_onsets(term, sframe) names(onset_list) # Shows condition names onset_list$condition.A # Onsets for condition A # Split with global timing (onsets relative to start of experiment) global_onsets <- split_onsets(term, sframe, global = TRUE) # Split by both condition and block block_split <- split_onsets(term, sframe, blocksplit = TRUE)
Standardize a numeric vector by centering and scaling, handling NAs appropriately.
If the computed standard deviation is NA or zero, a small constant
(1e-6) is used instead to avoid division by zero.
The returned basis matrix has one column with this standardized name.
Standardized(x)Standardized(x)
x |
a numeric vector to standardize. Missing values are allowed and will be replaced with 0 after standardization. |
an instance of class Standardized extending ParametricBasis
# Standardize a numeric vector x_vals <- c(10, 20, 30, 40, 50) std_basis <- Standardized(x_vals) print(std_basis$y) print(std_basis$mean) print(std_basis$sd)# Standardize a numeric vector x_vals <- c(10, 20, 30, 40, 50) std_basis <- Standardized(x_vals) print(std_basis$y) print(std_basis$mean) print(std_basis$sd)
Subset a parametric basis regressor.
sub_basis(x, subset) ## S3 method for class 'Scale' sub_basis(x, subset) ## S3 method for class 'ScaleWithin' sub_basis(x, subset) ## S3 method for class 'RobustScale' sub_basis(x, subset)sub_basis(x, subset) ## S3 method for class 'Scale' sub_basis(x, subset) ## S3 method for class 'ScaleWithin' sub_basis(x, subset) ## S3 method for class 'RobustScale' sub_basis(x, subset)
x |
the object |
subset |
the subset (logical or integer indices) |
An object of the same class as x with subset applied.
# Create some sample data x_vals <- 1:10 rt_vals <- rnorm(10, 500, 50) # Create different basis objects poly_basis <- Poly(x_vals, degree = 3) scale_basis <- Scale(rt_vals) bspline_basis <- BSpline(x_vals, degree = 2) # Subset with integer indices poly_sub <- sub_basis(poly_basis, 1:5) scale_sub <- sub_basis(scale_basis, c(1, 3, 5, 7, 9)) # Subset with logical indices logical_idx <- x_vals <= 5 bspline_sub <- sub_basis(bspline_basis, logical_idx) # Check dimensions nrow(poly_basis$y) # 10 nrow(poly_sub$y) # 5 nrow(scale_sub$y) # 5 nrow(bspline_sub$y) # 5# Create some sample data x_vals <- 1:10 rt_vals <- rnorm(10, 500, 50) # Create different basis objects poly_basis <- Poly(x_vals, degree = 3) scale_basis <- Scale(rt_vals) bspline_basis <- BSpline(x_vals, degree = 2) # Subset with integer indices poly_sub <- sub_basis(poly_basis, 1:5) scale_sub <- sub_basis(scale_basis, c(1, 3, 5, 7, 9)) # Subset with logical indices logical_idx <- x_vals <= 5 bspline_sub <- sub_basis(bspline_basis, logical_idx) # Check dimensions nrow(poly_basis$y) # 10 nrow(poly_sub$y) # 5 nrow(scale_sub$y) # 5 nrow(bspline_sub$y) # 5
Extract term indices
term_indices(x, ...) ## Default S3 method: term_indices(x, ...)term_indices(x, ...) ## Default S3 method: term_indices(x, ...)
x |
The object. |
... |
Additional arguments. |
Integer vector or list mapping term(s) to column indices.
# Create a sampling frame and event model sf <- fmrihrf::sampling_frame(blocklens = c(100, 100), TR = 2) events <- data.frame( onset = c(10, 30, 50, 70), condition = c("A", "B", "A", "B"), block = c(1, 1, 2, 2) ) model <- event_model(onset ~ hrf(condition), events, ~ block, sf) # Get design matrix and extract term indices dm <- design_matrix(model) indices <- term_indices(dm) print(indices) # Access indices for specific term condition_indices <- indices[["condition"]] print(condition_indices)# Create a sampling frame and event model sf <- fmrihrf::sampling_frame(blocklens = c(100, 100), TR = 2) events <- data.frame( onset = c(10, 30, 50, 70), condition = c("A", "B", "A", "B"), block = c(1, 1, 2, 2) ) model <- event_model(onset ~ hrf(condition), events, ~ block, sf) # Get design matrix and extract term indices dm <- design_matrix(model) indices <- term_indices(dm) print(indices) # Access indices for specific term condition_indices <- indices[["condition"]] print(condition_indices)
Extract term matrices
term_matrices(x, ...)term_matrices(x, ...)
x |
The object. |
... |
Additional arguments. |
A list of matrices/tibbles, one per term.
# Create a simple experimental design with event model des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) # Extract term matrices - returns list with one matrix per term term_mats <- term_matrices(emod) names(term_mats) # Shows term names ncol(term_mats[[1]]) # Number of columns for first term # Create baseline model and extract its term matrices bmod <- baseline_model(sframe = sframe) baseline_mats <- term_matrices(bmod) names(baseline_mats) # Shows baseline term names# Create a simple experimental design with event model des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) # Extract term matrices - returns list with one matrix per term term_mats <- term_matrices(emod) names(term_mats) # Shows term names ncol(term_mats[[1]]) # Number of columns for first term # Create baseline model and extract its term matrices bmod <- baseline_model(sframe = sframe) baseline_mats <- term_matrices(bmod) names(baseline_mats) # Shows baseline term names
Extract term names
term_names(x, ...)term_names(x, ...)
x |
The object. |
... |
Additional arguments. |
Character vector of term names.
# Create sample event data des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) # Event model example emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) term_names(emod) # Returns "cond" # Baseline model example bmod <- baseline_model(basis = "poly", degree = 3, sframe = sframe) term_names(bmod) # Returns c("constant", "baseline_poly_3")# Create sample event data des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) # Event model example emod <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) term_names(emod) # Returns "cond" # Baseline model example bmod <- baseline_model(basis = "poly", degree = 3, sframe = sframe) term_names(bmod) # Returns c("constant", "baseline_poly_3")
A restrained theme: left-aligned titles, recessive grid, no panel border, and small uppercase-free strip labels. All plotting methods in the package use it; add it to your own plots to match.
theme_fmridesign(base_size = 11, base_family = "")theme_fmridesign(base_size = 11, base_family = "")
base_size |
Base font size in points. |
base_family |
Base font family. |
A ggplot2 theme object.
if (requireNamespace("ggplot2", quietly = TRUE)) { ggplot2::ggplot(mtcars, ggplot2::aes(wt, mpg)) + ggplot2::geom_point() + theme_fmridesign() }if (requireNamespace("ggplot2", quietly = TRUE)) { ggplot2::ggplot(mtcars, ggplot2::aes(wt, mpg)) + ggplot2::geom_point() + theme_fmridesign() }
Generate one regressor per trial (plus an optional grand-mean column)
by delegating everything to hrf().
trialwise( basis = "spmg1", lag = 0, nbasis = 1, add_sum = FALSE, label = "trial", durations = NULL, normalize = FALSE )trialwise( basis = "spmg1", lag = 0, nbasis = 1, add_sum = FALSE, label = "trial", durations = NULL, normalize = FALSE )
basis, lag, nbasis
|
Passed straight to |
add_sum |
If TRUE, append a column that is the average of all trialwise columns (useful as a conventional main effect). |
label |
Term label / prefix for the generated columns. |
durations |
Optional durations override (passed to |
normalize |
logical; if TRUE, each trialwise regressor column is peak-normalized
so that |
Use it only on the RHS of an event-model formula:
onset ~ trialwise(basis = "spmg1", add_sum = TRUE)
An hrfspec term to be used on the RHS of an event-model formula.
# Create example trial data for beta-series analysis trial_data <- data.frame( onset = c(2, 8, 14, 20, 26), run = c(1, 1, 1, 1, 1) ) # Create sampling frame (30 TRs, TR=2s) sframe <- fmrihrf::sampling_frame(blocklens = 30, TR = 2) # Basic trialwise model - creates one regressor per trial emod_trials <- event_model(onset ~ trialwise(), data = trial_data, block = ~run, sampling_frame = sframe) print(emod_trials) # Trialwise with different basis and grand mean emod_trials_mean <- event_model(onset ~ trialwise(basis = "spmg2", add_sum = TRUE), data = trial_data, block = ~run, sampling_frame = sframe) print(emod_trials_mean)# Create example trial data for beta-series analysis trial_data <- data.frame( onset = c(2, 8, 14, 20, 26), run = c(1, 1, 1, 1, 1) ) # Create sampling frame (30 TRs, TR=2s) sframe <- fmrihrf::sampling_frame(blocklens = 30, TR = 2) # Basic trialwise model - creates one regressor per trial emod_trials <- event_model(onset ~ trialwise(), data = trial_data, block = ~run, sampling_frame = sframe) print(emod_trials) # Trialwise with different basis and grand mean emod_trials_mean <- event_model(onset ~ trialwise(basis = "spmg2", add_sum = TRUE), data = trial_data, block = ~run, sampling_frame = sframe) print(emod_trials_mean)
Construct a contrast that sums to 1 and is used to define contrasts against the baseline.
unit_contrast(A, name, where = NULL)unit_contrast(A, name, where = NULL)
A |
A formula selecting the cells to average. A logical expression
(e.g. |
name |
A character string specifying the name of the contrast. |
where |
An optional formula specifying the subset of conditions to apply the contrast to. |
A unit_contrast_spec object containing the contrast that sums to 1.
# Test main effect of Face against baseline con <- unit_contrast(~ Face, name="Main_face") # Test main effect within specific blocks con2 <- unit_contrast(~ Face, name="Face_early", where = ~ block <= 3)# Test main effect of Face against baseline con <- unit_contrast(~ Face, name="Main_face") # Test main effect within specific blocks con2 <- unit_contrast(~ Face, name="Face_early", where = ~ block <= 3)
Provides basic diagnostics for t- and F-contrasts once the design matrix
is available. You can either pass an event_model (to validate all attached
contrasts) or a design matrix plus custom weights.
validate_contrasts(x, weights = NULL, tol = 1e-08)validate_contrasts(x, weights = NULL, tol = 1e-08)
x |
An |
weights |
Optional contrast weights. May be a numeric vector (t-contrast),
a numeric matrix (F-contrast with columns as contrast vectors), or a named
list mapping names to vectors/matrices. If |
tol |
Numeric tolerance for zero checks. Default |
Checks include:
Estimability: whether each contrast column lies in the row space of X.
Sum-to-zero: whether the weights sum to ~0 (t-contrasts only).
Intercept orthogonality: whether weights on intercept-like columns are ~0.
Full-rank (F only): whether an F-contrast matrix has full column rank.
A data.frame with one row per validated contrast column and the
following columns: name, type ("t" or "F"), estimable,
sum_to_zero, orthogonal_to_intercept, full_rank (F only), and
nonzero_weights.
# Create a simple event model des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) emodel <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) # Validate all attached contrasts on a model res <- validate_contrasts(emodel) # Validate a custom vector against a model v <- rep(0, ncol(design_matrix(emodel))) v[1] <- 1 v[2] <- -1 res2 <- validate_contrasts(emodel, weights = v)# Create a simple event model des <- data.frame( onset = c(0, 10, 20, 30), run = 1, cond = factor(c("A", "B", "A", "B")) ) sframe <- fmrihrf::sampling_frame(blocklens = 40, TR = 1) emodel <- event_model(onset ~ hrf(cond), data = des, block = ~run, sampling_frame = sframe) # Validate all attached contrasts on a model res <- validate_contrasts(emodel) # Validate a custom vector against a model v <- rep(0, ncol(design_matrix(emodel))) v[1] <- 1 v[2] <- -1 res2 <- validate_contrasts(emodel, weights = v)
Creates a generator function for use with the hrf_fun parameter in hrf().
The generator produces weighted impulse HRFs from columns containing lists
of sub-event times and weights.
weighted_hrf_gen( times_col = "sub_times", weights_col = "sub_weights", relative = FALSE, method = "constant", normalize = FALSE )weighted_hrf_gen( times_col = "sub_times", weights_col = "sub_weights", relative = FALSE, method = "constant", normalize = FALSE )
times_col |
Character; name of the column containing sub-event times (relative or absolute). |
weights_col |
Character; name of the column containing sub-event weights. |
relative |
Logical; if TRUE, times are relative to event onset; if FALSE, times are absolute and will be converted to relative by subtracting the onset. Default FALSE (absolute times). |
method |
Character; interpolation method for |
normalize |
Logical; whether to normalize the weighted HRF. Default FALSE. |
A function that takes an event data frame and returns a list of HRF objects.
boxcar_hrf_gen() for duration-based boxcar HRFs
trial_data <- data.frame( onset = c(0, 20), sub_times = I(list(c(0, 1, 2), c(0, 3, 6))), sub_weights = I(list(c(0.2, 0.5, 0.3), c(0.1, 0.6, 0.3))), run = 1 ) sf <- fmrihrf::sampling_frame(blocklens = 50, TR = 2) emod <- event_model( onset ~ hrf(onset, hrf_fun = weighted_hrf_gen("sub_times", "sub_weights", relative = TRUE)), data = trial_data, block = ~run, sampling_frame = sf ) print(emod)trial_data <- data.frame( onset = c(0, 20), sub_times = I(list(c(0, 1, 2), c(0, 3, 6))), sub_weights = I(list(c(0.2, 0.5, 0.3), c(0.1, 0.6, 0.3))), run = 1 ) sf <- fmrihrf::sampling_frame(blocklens = 50, TR = 2) emod <- event_model( onset ~ hrf(onset, hrf_fun = weighted_hrf_gen("sub_times", "sub_weights", relative = TRUE)), data = trial_data, block = ~run, sampling_frame = sf ) print(emod)