This document outlines the plan to refactor the design matrix column naming scheme within the fmrireg package. The goal is to establish a consistent, deterministic, and unambiguous grammar for column names generated from event models.
Var.Level
(e.g., cond.A
, run.2
) - Sanitized variable name, dot, sanitized level name. Used as a component in condition_tag
.##
(e.g., 01
, 02
) - Zero-padded index for columns generated by functions like Poly
, BSpline
. Used as a component in condition_tag
.var
(e.g., RT1
, Age
) - Raw variable name used directly when passed via Ident()
. Used as a component in condition_tag
for these specific terms._b##
(e.g., _b01
, _b05
) - Underscore, 'b', dynamically zero-padded HRF basis index. Appended at the very end by make_column_names
if the HRF has nbasis > 1
.condition_tag
)hrf()
term, relative to its term_tag
.Var.Level
(e.g., cond.a
).Poly
, BSpline
): Just the zero-padded index (01
, 02
). The basis type and variable info are captured by the term_tag
.Ident()
variables (within an Ident()
-only term): The raw variable name (RT1
)._
(e.g., cond.a_01
for hrf(cond, Poly(RT,2))
).conditions.event_term
. For continuous/basis components, it relies on columns(event_object)
which ultimately (via columns.event
and levels(basis_object)
) sources these minimal indices from the levels.ParametricBasis
methods (e.g. levels.Poly
returning 01
, 02
). For factor components, it uses tokens from level_token()
.term_tag
)hrf(...)
term, acting as a namespace prefix for its columns.id=
argument in hrf()
, ORhrf()
(e.g., condition
, Poly_RT
, condition_RT
)..
-> _
).make_unique_tags
(e.g., condition
, condition#1
).Ident
-only): For hrf(Ident(V1, V2, ...))
without an explicit id=
, the term_tag
is intentionally set to NULL
by make_term_tag
. This signals that these variables should not be prefixed.General Case:
term_tag
+ _
+ condition_tag
+ [_b##
HRF suffix]
Special Case (Ident
-only, no id
): (term_tag
is NULL
)
condition_tag
+ [_b##
HRF suffix]
(Where condition_tag
is the raw variable name, e.g., RT1
)
This single canonical structure (with the Ident
exception) replaces previous compact
/qualified
styles.
make_column_names
, called by convolve.event_term
.hrf(condition)
-> condition_cond.a
, condition_cond.b
hrf(condition, id="Cond")
-> Cond_cond.a
, Cond_cond.b
hrf(condition, basis="spmg3")
-> condition_cond.a_b01
, condition_cond.a_b02
, condition_cond.a_b03
, condition_cond.b_b01
, ...hrf(Ident(RT1, RT2))
-> RT1
, RT2
hrf(Ident(RT1, RT2), id="myID")
-> myID_RT1
, myID_RT2
hrf(Ident(RT1, RT2), basis="spmg2")
-> RT1_b01
, RT1_b02
, RT2_b01
, RT2_b02
hrf(Ident(RT1, Age)) + hrf(Ident(RT1, RT2))
-> RT1
, Age
, RT1.1
, RT2
(warning issued by make.names
)hrf(Poly(RT, 2))
-> Poly_RT_01
, Poly_RT_02
hrf(Poly(RT, 2), id="MyPoly")
-> MyPoly_01
, MyPoly_02
hrf(Poly(RT, 2), basis="spmg2")
-> Poly_RT_01_b01
, Poly_RT_01_b02
, Poly_RT_02_b01
, Poly_RT_02_b02
hrf(condition, Poly(RT, 2), id="MyInt")
-> MyInt_cond.a_01
, MyInt_cond.a_02
, MyInt_cond.b_01
, MyInt_cond.b_02
hrf(condition)
+ hrf(condition)
-> Term tags condition
and condition#1
. Columns: condition_cond.a
, condition_cond.b
, condition#1_cond.a
, condition#1_cond.b
.term_tag
s (when not NULL
) is handled preemptively by make_term_tag
using #
suffixes.build_event_model_design_matrix
, which applies make.names(..., unique = TRUE)
as a final step. This resolves any remaining clashes (e.g., from multiple Ident()
terms proposing the same raw variable name) by appending suffixes like .1
, .2
.make.names
for uniqueness).Ident
) with necessary namespacing (via term_tag
) for more complex terms or explicit user IDs.A step-by-step refactoring process targeting specific functions in order:
R/naming-utils.R
with core helper functions.hrf()
/ hrfspec()
: Ensure hrfspec$id
is only set if explicitly provided by user.realise_event_terms()
: Generate and store term_tag
(potentially NULL
for Ident
-only) via make_term_tag
. Attach term_tag
attribute to event_term
objects.levels.ParametricBasis
methods: Ensure levels.Poly
, levels.BSpline
, etc. (when called on a basis object, typically via columns(event_object)
-> columns.event
in the naming pipeline) return only zero-padded indices. Ensure levels.Ident
returns raw variable names. (Dedicated columns.BasisType
S3 methods should also align if used directly elsewhere).conditions.event_term()
: Rewrite to assemble condition_tag
s using tokens from level_token
and (indirectly, as described above) levels.ParametricBasis
methods, handling interactions.convolve.event_term()
: Simplify. Use make_column_names()
helper, passing the term_tag
attribute (which might be NULL
) and base condition names. This is the sole place final proposed names for a term are constructed.event_term()
): Internal legacy column naming logic for basis functions within event_term
objects (if any existed beyond what design_matrix
and convolve.event_term
now handle) is removed/superseded. The primary naming construction occurs in later stages.build_event_model_design_matrix()
: Apply make.names(..., unique=TRUE)
to the combined column names before returning the final matrix.expand_basis
Flag Handlingconditions()
. Used only to control whether conditions()
returns basis-collapsed (cond.a
) or basis-expanded (cond.a_b01
, cond.a_b02
) condition tags.convolve.event_term
(and thus the final design matrix) always includes the HRF basis suffix (_b##
) if nbasis > 1
, regardless of this flag's value passed to conditions()
.naming-utils.R
SpecificationDefines helper functions. Key decisions:
Exports: Only sanitize
, zeropad
, basis_suffix
are exported.
Internal Helpers: make_unique_tags
, make_term_tag
, level_token
, continuous_token
, make_cond_tag
, add_basis
, make_column_names
marked internal (@keywords internal
).
Padding: zeropad
used for both HRF basis suffix (_b##
) and generative basis indices (01
, 02
).
Sanitization: sanitize(allow_dot=FALSE)
used for term tags; sanitize(allow_dot=TRUE)
generally used elsewhere.
Basis Condition Tags: levels.Poly
, levels.BSpline
(called via columns(event_object_with_basis)
in the naming pipeline) return only the zero-padded index (e.g., "01"
) as the condition_tag
component. Info about basis type/variable captured in term_tag
.
Ident Handling: make_term_tag
returns NULL
for hrf(Ident(V1,V2,...))
without explicit id=
. make_column_names
detects this and produces final column names directly from the Ident
variable names (V1
, V2
), plus any HRF basis suffix.
* Global Uniqueness: Guaranteed by build_event_model_design_matrix
applying make.names(..., unique=TRUE)
.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.