A modern, tidy toolkit for lag sequential
analysis and lag transition networks of categorical event and sequence
data. It provides an accessible, unified workflow for fitting, inspecting,
visualising, and comparing lagged transition patterns, with tidy outputs
throughout. Includes confirmatory tools for uncertainty, robustness, and
group differences, including bootstrap intervals, analytic certainty,
split-half reliability, case-drop stability, permutation tests, and
Bayesian group comparisons. Supports long-format event-log import,
import from common sequence and state-sequence objects, multi-lag
analysis, structural-zero constraints, transition and initial
probabilities, plotting of transition structures, and a directed
transfer-entropy measure. The lag sequential analysis framework
follows Sackett and others (1979)
Modern, tidy lag sequential analysis for categorical event sequences.
Lag sequential analysis (LSA) is a statistical method for detecting temporal contingencies in categorical, time-ordered data. For every ordered pair of states, it tests whether one follows another at a given lag more — or less — often than expected under sequential independence, quantifying each contingency with the adjusted (standardized) residual of observed against expected transition frequencies. It is widely used to study how categorical processes unfold over time — in behavioral and dyadic interaction, conversation and group discourse, psychotherapy process research, human–computer interaction, and learning analytics — wherever the order of events, not merely their frequency, carries the meaning.
lagdynamics implements LSA as a modern, tidy workflow. A single lsa()
constructor fits the classical and extended engine family — classical,
two-cell, bidirectional, and parallel / non-parallel dominance — and every
result is read through a verb that returns a one-row-per-observation
data.frame. Its distinguishing commitment is evidence: each transition is
treated as a tested departure from independence, backed by a confirmatory
battery of bootstrap intervals, analytic Bayesian certainty, split-half
reliability, case-drop stability, and permutation tests.
Beyond the classical test, the package adds multi-lag analysis, structural-zero
constraints under quasi-independence, and grouped fits that estimate one model
per group in a shared state space, with formal group comparison by permutation
or Bayesian Dirichlet–Multinomial contrast. It is designed to interoperate
across the sequence-analysis ecosystem: lsa() ingests long event logs, wide
matrices, lists of sequences, and objects from tna, Nestimate, and
TraMineR, while fitted objects carry a cograph network class and expose
transition and initial probabilities for downstream tooling. A single plot()
verb renders any fit as a residual heatmap, transition network, chord diagram,
polar sunburst, or uncertainty forest.
# CRAN (after acceptance)
install.packages("lagdynamics")
# r-universe (pre-built binaries, no compiler needed)
install.packages("lagdynamics",
repos = c("https://mohsaqr.r-universe.dev",
"https://cloud.r-project.org"))
# development version
# install.packages("remotes")
remotes::install_github("mohsaqr/lagdynamics")
The analytical core depends only on base R; plotting adds ggplot2 and
cograph, which install automatically. Interoperability packages (tna,
Nestimate) stay optional Suggests.
| Task | Functions |
|---|---|
| Fit a model | lsa(), lsa_lags(), lag_profile() |
| Read results (tidy) | transitions(), nodes(), tests(), initial(), as.data.frame() |
| Weigh the evidence | bootstrap_lsa(), certainty_lsa(), permute_lsa(), stability_lsa(), reliability_lsa() |
| Compare groups | compare_lsa(), bayes_compare_lsa() |
| Plot | plot(fit, type = ), plot_transitions(), plot_chords(), plot_polar(), plot_forest() |
| Probabilities | transition_probabilities(), initial() |
| Engines | lsa(engine = ), register_lsa_engine(), list_lsa_engines() |
library(lagdynamics)
seq <- c("Question", "Explain", "Agree",
"Question", "Explain", "Elaborate",
"Agree", "Question", "Explain")
fit <- lsa(seq, engine = "classical")
fit
transitions(fit, significant = TRUE) # tidy table of tested transitions
plot(fit, type = "network") # residual transition network
# quantify the evidence behind each edge
boot <- bootstrap_lsa(fit, R = 1000)
plot(boot) # circular bootstrap CI forest
| Vignette | Topic |
|---|---|
vignette("lagdynamics") |
Get started: the method, why lagdynamics, and a hands-on tour |
vignette("interop") |
Interoperability with wide data, long logs, tna, Nestimate, and cograph |
vignette("workflow") |
A complete analysis from sequences to a group comparison |
vignette("confirmatory") |
The confirmatory testing battery: matching claims to evidence |
vignette("lag-transition-networks") |
Lag transition networks |
vignette("plotting") |
The full plotting gallery |
MIT © 2026 Mohammed Saqr