Construct a Feature Regressor from a Sampled Time Series
Source:R/feature-regressor.R
feature_regressor.RdCreates a regressor from a continuously sampled feature (for example RMS energy of an acoustic stimulus) by treating each sample as a zero-order-hold bin of width \(\Delta t\). The result is the Riemann-sum / ZOH approximation of convolving the feature with an HRF, not a train of unit-mass impulses.
Usage
feature_regressor(
values,
hrf = HRF_SPMG1,
times = NULL,
dt = NULL,
start = 0,
center = TRUE,
scale = c("none", "sd"),
mask = NULL,
span = NULL
)Arguments
- values
Numeric vector of feature samples.
- hrf
The hemodynamic response function to convolve with the feature. Same types as [regressor()], except a list of per-event HRFs is not allowed. Defaults to `HRF_SPMG1`.
- times
Numeric vector of sample times in seconds, same length as `values`. Mutually exclusive with `dt`. Times must be strictly increasing and non-negative. The last bin width is the last inter-sample gap.
- dt
Positive sampling interval in seconds. Mutually exclusive with `times`. Sample times are `start + seq(0, by = dt, length.out = length(values))`.
- start
Start time in seconds used only when `dt` is supplied. Defaults to 0.
- center
Logical; if `TRUE` (default), subtract the mean of the (masked) samples before convolution.
- scale
Character; `"none"` (default) leaves native units, `"sd"` divides by the standard deviation of the (masked) samples after centering.
- mask
Optional logical vector the same length as `values`. Center and scale statistics are computed on `mask == TRUE` samples only; off-mask samples are set to 0 after that (block-centered modulator).
- span
Temporal window in seconds for the HRF, passed to [regressor()]. If `NULL`, the HRF's own span is used.
Value
An S3 object of class `c("FeatureReg", "Reg", "list")`. Evaluation uses the same convolution path as [regressor()].
Details
Centering and scaling are applied to the feature **before** convolution. The default is to demean and leave the native units unchanged. This is the usual choice when the feature is defined for a whole run: the mean aliases into the intercept, and the edge transients of a non-zero mean are rarely of interest. If the feature is a within-block modulator, pass a `mask` for the on-period (and typically a separate boxcar for "stimulus on") rather than demeaning the concatenated series.
This is **not** parametric modulation of discrete events. No unmodulated companion regressor is added. Zeros are valid samples and are retained.
Evaluate with `precision` less than or equal to the feature sampling interval so that several samples are not collapsed into one convolution bin. Compared with `regressor(times, amplitude = values, duration = 0)`, the predicted BOLD is smaller by about \(\Delta t\) (the missing integral measure of a continuous signal).
Examples
# 10 Hz envelope over 8 seconds, demeaned
dt <- 0.1
t <- seq(0, 8, by = dt)
rms <- abs(sin(2 * pi * t / 4))
feat <- feature_regressor(rms, dt = dt, hrf = HRF_SPMG1)
grid <- seq(0, 12, by = 1)
y <- evaluate(feat, grid, precision = dt)
# Same ZOH encoding as a duration-dt event regressor (no centering)
feat_raw <- feature_regressor(rms, dt = dt, center = FALSE, scale = "none")
ev <- regressor(t, HRF_SPMG1, duration = dt, amplitude = rms)
all.equal(evaluate(feat_raw, grid, precision = dt),
evaluate(ev, grid, precision = dt))
#> [1] TRUE