Correlation-based dynFC methods characterise how functional connectivity evolves over time by either windowing the timeseries into short segments and computing Pearson correlations within each window, or by analysing the instantaneous co-activation of parcel pairs as a continuous edge time series — no windowing required.
dynR implements three correlation-based functions:
| Function | Output | Method |
|---|---|---|
corr_slide() |
FC matrices \[N × N × windows\] | Sliding-window Pearson correlation |
cofluct() |
Edge time series \[n\_edges × Tmax\] + RSS | Edge-centric cofluctuation |
corr_corr() |
FC recurrence matrix \[Tmax × Tmax\] | Hansen et al. (2015) |
Although this vignette uses BOLD fMRI data throughout, these methods apply to any multivariate timeseries where pairwise correlations carry meaningful information, including EEG and LFP.
Unlike phase-based methods, sliding-window FC requires you to commit to a window length. The trade-off is fundamental:
For this dataset (TR = 2 s, 600 timepoints), a few window choices look like:
A single window spanning the full timeseries must recover the static FC matrix exactly.
The standard deviation of each edge across windows — its FC variability — reveals which connections drive the dynamic signal. Edges with high variability are the ones that genuinely fluctuate; edges with near-zero variability are essentially static.
n_parcels <- dim(sw$corr_mats)[1]
ut <- which(upper.tri(diag(n_parcels)), arr.ind = TRUE)
edge_by_window <- apply(sw$corr_mats, 3, function(m) m[ut])
edge_sd <- apply(edge_by_window, 1, sd)
ggplot(data.frame(sd = edge_sd), aes(x = sd)) +
geom_histogram(bins = 60, fill = "#8D9FD7", colour = "#341C5D",
linewidth = 0.3) +
geom_vline(xintercept = mean(edge_sd),
colour = "#9E3C30", linetype = "dashed", linewidth = 0.9) +
labs(x = "SD across windows", y = "Number of edges",
title = "FC variability distribution",
subtitle = paste0("Mean edge SD = ", round(mean(edge_sd), 4))) +
theme_minimal(base_size = 13) +
theme(panel.grid.minor = element_blank())The edge-centric framework (Esfahlani et al., 2020; Faskowitz et al., 2020) abandons the window entirely. Instead, each parcel’s timeseries is z-standardised and the element-wise product of every unique parcel pair is computed at every timepoint:
\[\text{ets}_{ij}(t) = z_i(t) \cdot z_j(t)\]
The result is an edge time series — a continuous, frame-by-frame estimate of co-activation for every pair.
ec <- cofluct(ts)
n_edges <- nrow(ec$edge_ts)
cat("Edges (N*(N-1)/2):", n_edges, "\n")
#> Edges (N*(N-1)/2): 19900
cat("Timepoints: ", ncol(ec$edge_ts), "\n")
#> Timepoints: 600The RSS vector summarises the total co-activation amplitude across all edges at each timepoint:
\[\text{RSS}(t) = \sqrt{\sum_{(i,j)} \text{ets}_{ij}(t)^2}\]
High-RSS frames are moments of unusually strong, synchronised co-activation across the whole brain. These high-amplitude events have been shown to disproportionately drive the structure of the static FC matrix — a small fraction of timepoints accounts for most of the long-run average connectivity (Esfahlani et al., 2020).
thr <- mean(ec$rss) + 2 * sd(ec$rss)
df_rss <- data.frame(t = seq_along(ec$rss), rss = ec$rss,
high = ec$rss > thr)
ggplot(df_rss, aes(x = t, y = rss)) +
geom_line(colour = "#8D9FD7", linewidth = 0.6) +
geom_hline(yintercept = thr,
colour = "#9E3C30", linetype = "dashed", linewidth = 0.9) +
annotate("text",
x = max(df_rss$t) * 0.02, y = thr + 0.8,
label = paste0("Mean + 2 SD (n = ",
sum(df_rss$high), " frames)"),
colour = "#9E3C30", size = 3.5, hjust = 0) +
labs(x = "Timepoint", y = "RSS",
title = "Root-sum-square cofluctuation",
subtitle = paste0(round(mean(df_rss$high) * 100, 1),
"% of timepoints exceed threshold")) +
theme_minimal(base_size = 13) +
theme(panel.grid.minor = element_blank())corr_corr() computes a \[Tmax
× Tmax\] matrix of pairwise correlations between edge time
series. Entry (t1, t2) answers: how similar
was the brain’s whole-network co-activation pattern at timepoint
t1 to that at t2?
This makes it a temporal recurrence matrix — a fingerprint of how often the brain revisits similar FC configurations. Key features to look for:
pal <- colorRampPalette(c("#341C5D", "#E8ECF8", "#9E3C30"))(256)
par(mar = c(4, 4, 3, 2))
image(seq_len(nrow(cc)), seq_len(ncol(cc)), cc,
col = pal,
xlab = "Timepoint", ylab = "Timepoint",
main = "FC recurrence (correlation of correlations)")Warm colours indicate timepoints where the brain was in similar connectivity configurations; cool colours indicate dissimilar states. Visible block structure along the diagonal suggests sustained, recurring FC patterns.
The upper triangle of each window’s FC matrix can be vectorised and clustered with K-means to identify recurring connectivity states.
features <- t(apply(sw$corr_mats, 3, function(m) m[ut]))
set.seed(42)
K <- 5
km <- kmeans(features, centers = K, nstart = 100, iter.max = 500)Note on dimensionality: each feature vector has N(N−1)/2
entries — 19,900 for 200 parcels. This high dimensionality makes K-means
convergence slower and noisier than in the LEiDA case, where each
feature vector has only N entries. For smaller datasets or
single-subject analyses, the LEiDA approach (see
vignette("phase-based-fc")) is often preferable.
state_cols <- c("#8D9FD7", "#9E3C30", "#754D71", "#341C5D", "#E19A8F")
ggplot(data.frame(t = seq_along(km$cluster),
state = factor(km$cluster)),
aes(x = t, y = 1, fill = state)) +
geom_tile(height = 1) +
scale_fill_manual(values = state_cols, name = "State") +
labs(x = "Window", y = NULL,
title = "Sliding-window brain state sequence (K = 5)") +
theme_minimal(base_size = 13) +
theme(axis.text.y = element_blank(),
axis.ticks.y = element_blank(),
panel.grid = element_blank())The state sequence feeds directly into stateR for
fractional occupancy, dwell time, and Markov transition analysis.
Hutchison, R. M. et al. (2013). Dynamic functional connectivity: Promise, issues, and interpretations. NeuroImage, 80, 360–378. https://doi.org/10.1016/j.neuroimage.2013.05.079
Leonardi, N. & Van De Ville, D. (2015). On spurious and real fluctuations of dynamic functional connectivity during rest. NeuroImage, 104, 430–436. https://doi.org/10.1016/j.neuroimage.2014.09.007
Hansen, E. C. A. et al. (2015). Functional connectivity dynamics: Modeling the switching behavior of the resting state. NeuroImage, 105, 525–535. https://doi.org/10.1016/j.neuroimage.2014.11.001
Esfahlani, F. Z. et al. (2020). High-amplitude cofluctuations in cortical activity drive functional connectivity. PNAS, 117(45), 28393–28401. https://doi.org/10.1073/pnas.2005531117
Faskowitz, J. et al. (2020). Edge-centric functional network representations of human cerebral cortex reveal overlapping system-level architecture. Nature Neuroscience, 23(12), 1644–1654. https://doi.org/10.1038/s41593-020-00719-y