| Title: | Lag Sequential Analysis, Dynamics, and Lag Transition Networks |
| Version: | 0.32 |
| Description: | 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) <doi:10.3758/BF03205679>. |
| License: | MIT + file LICENSE |
| URL: | https://github.com/mohsaqr/lagdynamics |
| BugReports: | https://github.com/mohsaqr/lagdynamics/issues |
| Language: | en-US |
| Encoding: | UTF-8 |
| RoxygenNote: | 7.3.3 |
| Depends: | R (≥ 4.1.0) |
| Imports: | cograph (≥ 2.3.6), ggplot2 (≥ 3.4.0), grDevices, grid, stats, utils |
| Suggests: | testthat (≥ 3.0.0), Nestimate, tna, knitr, rmarkdown |
| Config/testthat/edition: | 3 |
| LazyData: | true |
| VignetteBuilder: | knitr |
| NeedsCompilation: | no |
| Packaged: | 2026-07-11 19:40:45 UTC; mohammedsaqr |
| Author: | Mohammed Saqr [aut, cre, cph], Sonsoles López-Pernas [aut] |
| Maintainer: | Mohammed Saqr <saqr@saqr.me> |
| Repository: | CRAN |
| Date/Publication: | 2026-07-21 10:20:07 UTC |
lagdynamics: Lag Sequential Analysis, Dynamics, and Lag Transition Networks
Description
A unified, pipe-friendly interface for lag sequential analysis (LSA) of
categorical event sequences. Provides classical, two-cell,
bidirectional, parallel-dominance, and non-parallel-dominance engines
via a single lsa() constructor with a pluggable engine registry,
sequence-level bootstrap and permutation inference, case-drop
stability, and tidy edge tables ready for transition-network
visualization.
Design principles
Numerical methods are implemented from primary literature and
cross-validated against base-R primitives and hand-formula identities
(stats::loglin(), stats::chisq.test(), stats::pchisq()). See the
inst/REFERENCES.md file shipped with the package for the
formula-by-formula citation map.
The package returns S3 objects of class c("lsa", "cograph_network"),
which means fits inherit compatibility with the cograph package's
visualization layer when it is installed.
Main functions
Construction: lsa(), lsa_data(), lsa_transitions()
Convenience wrappers: lsa_classical(), lsa_two_cell(),
lsa_bidirectional(), lsa_parallel_dominance(),
lsa_nonparallel_dominance()
Engine registry: register_lsa_engine(), get_lsa_engine(),
list_lsa_engines()
Inference: bootstrap_lsa(), permute_lsa(), stability_lsa(),
reliability_lsa(), and analytic certainty via certainty_lsa().
Group comparison: compare_lsa() and bayes_compare_lsa() for
between-group differences in transition structure.
Reading a fit (tidy data frames): transitions(), nodes(),
tests(), initial(), and summary().
Transition and initial probabilities: transition_probabilities()
returns the row-stochastic transition-probability matrix and
initial() the initial-state probabilities.
Roadmap (not yet implemented)
Stationarity tests (stationarity_lsa()) are planned but not yet
exported. Multi-group fits are built with lsa(data, group = ...);
between-group differences are then tested with compare_lsa() or
bayes_compare_lsa().
Author(s)
Maintainer: Mohammed Saqr saqr@saqr.me [copyright holder]
Authors:
Sonsoles López-Pernas
References
Bakeman, R., & Quera, V. (1995). Analyzing interaction: Sequential analysis. Cambridge University Press.
Bakeman, R., & Gottman, J. M. (1997). Observing interaction: An introduction to sequential analysis (2nd ed.). Cambridge University Press.
Christensen, R. (1997). Log-linear models and logistic regression (2nd ed.). Springer.
Haberman, S. J. (1979). Analysis of qualitative data: Volume 2, New developments. Academic Press.
Sackett, G. P. (1979). The lag sequential analysis of contingency and cyclicity in behavioral interaction research. In J. D. Osofsky (Ed.), Handbook of infant development (pp. 623-649). Wiley.
Wampold, B. E. (1982). Sequential analysis: Stationarity, statistical procedures, and applications. Psychological Bulletin, 92(2), 380-387.
Wampold, B. E. (1984). Tests of dominance in sequential categorical data. Psychological Bulletin, 96(2), 424-429.
Wickens, T. D. (1989). Multiway contingency tables analysis for the social sciences. Lawrence Erlbaum.
See Also
Useful links:
Human-AI Vibe Coding Interaction Events
Description
A long-format event log of coded AI-side behaviours in human-AI vibe
coding sessions. Each row is one coded AI event, with project/session
identifiers, ordering variables, a fine-grained AI behaviour code, and a
broader behaviour cluster. It is useful for demonstrating lsa()'s
long-format event-log import path.
Usage
ai_long
Format
A data.frame with 8,551 rows and 9 columns:
- message_id
Integer message identifier.
- project
Project identifier.
- session_id
Session identifier.
- timestamp
Unix timestamp in seconds.
- session_date
Session date as
YYYY-MM-DD.- code
Fine-grained AI behaviour code.
- cluster
Broader AI behaviour cluster.
- code_order
Order of multiple codes within the same message.
- order_in_session
Event order within session.
Details
The eight AI behaviour codes are Ask, Delegate, Execute, Explain,
Investigate, Plan, Repair, and Report. The three clusters are
Action, Communication, and Repair.
Source
Derived without modification from Nestimate::ai_long
(Nestimate version 0.7.7, MIT license).
Examples
fit <- lsa(ai_long, session = "session_id",
action = "code", order = "order_in_session")
transitions(fit, significant = TRUE)
Tidy a Group Comparison
Description
Returns the per-edge comparison table (the same data frame as
x$edges) so a comparison can be read with as.data.frame() like the
other result objects, without reaching into the object.
Usage
## S3 method for class 'lsa_comparison'
as.data.frame(x, row.names = NULL, optional = FALSE, ...)
## S3 method for class 'lsa_comparison_pairwise'
as.data.frame(x, row.names = NULL, optional = FALSE, ...)
Arguments
x |
An |
row.names, optional, ... |
Standard |
Value
The tidy per-edge data frame.
Examples
grp <- ifelse(group_regulation$T1 == "plan", "plan", "other")
g <- lsa(group_regulation, group = grp)
cmp <- compare_lsa(g, R = 200)
head(as.data.frame(cmp))
Tidy the Canonical Sequence Object
Description
Returns the canonical lsa_data as a tidy data frame: one row per
event (seq_id, within-sequence index, state) for event-level
input, or one row per from/to/count cell for transition-matrix
input.
Usage
## S3 method for class 'lsa_data'
as.data.frame(x, row.names = NULL, optional = FALSE, ...)
Arguments
x |
An |
row.names, optional, ... |
Standard |
Value
A tidy data frame.
Examples
d <- lsa_data(c("a", "b", "a", "c", "b"))
as.data.frame(d)
Tidy the per-replicate split-half correlations
Description
Tidy the per-replicate split-half correlations
Usage
## S3 method for class 'lsa_reliability'
as.data.frame(x, row.names = NULL, optional = FALSE, ...)
## S3 method for class 'lsa_reliability_group'
as.data.frame(x, row.names = NULL, optional = FALSE, ...)
Arguments
x |
An |
row.names, optional, ... |
Ignored (method signature compatibility). |
Value
A data.frame, one row per replicate, with columns
replicate and correlation (a grouped object gains a leading
group column). NA correlations from degenerate splits are kept.
Examples
fit <- lsa(group_regulation)
rel <- reliability_lsa(fit, R = 200)
head(as.data.frame(rel))
Bayesian Comparison of Group Transition Structures (Dirichlet-Multinomial)
Description
Closed-form Bayesian alternative to compare_lsa() for comparing the
transition structures of two (or, pairwise, more) groups. Each state's
outgoing transitions are modelled as Dirichlet-Multinomial with a
Jeffreys prior, so each transition probability is marginally Beta. The
per-edge posterior mean difference prob_a - prob_b is exact; a
credible interval, the probability of direction pd, and a two-sided
Bayesian p-equivalent 2 * (1 - pd) come from a Monte Carlo draw on the
Beta marginals.
Usage
bayes_compare_lsa(
x,
y = NULL,
prior = 0.5,
draws = 10000L,
ci = 0.95,
mean_threshold = 0.01,
bound_threshold = 0.001,
adjust = "none",
seed = NULL
)
Arguments
x |
An |
y |
The second group's |
prior |
Numeric > 0. Dirichlet prior concentration added to every
cell. Default |
draws |
Integer. Monte Carlo posterior draws for the credible
intervals. Default |
ci |
Numeric in (0, 1). Credible-interval mass. Default |
mean_threshold, bound_threshold |
An edge is flagged credibly
different only if its credible interval excludes zero, |
adjust |
Multiple-comparison correction applied to the two-sided
Bayesian p across edges (and family-wide across pairs); any method of
|
seed |
Optional integer for reproducible credible intervals. |
Details
This complements compare_lsa(): the permutation test asks whether a
difference is more extreme than chance; the Bayesian comparison asks for
the plausible range of the true difference and how precisely it is
estimated. An edge whose source state is rarely visited gets a wide
credible interval even when its row-normalised probability looks
decisive.
The result carries class c("lsa_bayes", "lsa_comparison") (and the
pairwise object c("lsa_bayes_pairwise", "lsa_comparison_pairwise")),
so plot() (barrel / heatmap) and
as.data.frame() work as for a permutation comparison.
Value
For two groups, class c("lsa_bayes", "lsa_comparison", "list")
with an edges data frame (from, to, prob_a, prob_b, diff,
ci_low, ci_high, pd, effect_size, p_value, p_adj,
significant), the two fits, and the Bayesian settings. For more
than two groups, an all-pairwise c("lsa_bayes_pairwise", "lsa_comparison_pairwise", "list").
References
Johnston, L. & Jendoubi, T. (2026). How Delivery Mode Reshapes Resource Engagement: A Bayesian Differential Network Analysis. TNA Workshop 2026.
See Also
compare_lsa(), certainty_lsa()
Examples
g <- lsa(group_regulation,
group = ifelse(group_regulation$T1 == "plan", "p", "o"))
bc <- bayes_compare_lsa(g, seed = 1)
head(as.data.frame(bc))
Bootstrap Confidence Intervals for an LSA Fit
Description
Non-parametric bootstrap for any LSA fit produced by lsa().
Resamples the underlying sequence data (whole sequences when more
than one is available; geometric-block stationary bootstrap on
events otherwise), refits the engine on each resample using the
immutable recipe stored in fit$params, and aggregates per-edge
statistics into a tidy data frame.
Usage
bootstrap_lsa(
fit,
R = 1000L,
level = c("auto", "sequence", "event"),
block_length = NULL,
level_alpha = 0.95,
indices = NULL,
parallel = FALSE,
n_cores = NULL,
verbose = FALSE,
...
)
Arguments
fit |
An |
R |
Integer. Number of bootstrap replicates. Default |
level |
Character. Resampling unit: |
block_length |
For event-level bootstrap, mean geometric
block length. Default |
level_alpha |
Numeric. Confidence level for percentile
intervals. Default |
indices |
Optional integer matrix of replay indices, one row
per resample (row |
parallel |
Logical. Use multi-core resampling. Default
|
n_cores |
Integer. Worker count when |
verbose |
Logical. Print progress every 100 replicates.
Default |
... |
Reserved for future use. |
Details
Sequence-level resampling (default for multi-sequence input).
Each resample draws S sequence indices with replacement from
seq_len(S) and rebuilds the multi-sequence input as the
corresponding list of event vectors. Preserves within-sequence
structure.
Event-level resampling (single-sequence input). Implements
the stationary block bootstrap of Politis & Romano (1994). Block
length is geometric with mean block_length; resampled blocks
wrap around the event stream and are concatenated until total
length equals the original T.
Reproducibility hook. Supply indices as an R x S integer
matrix of sequence indices (sequence-level) or an R x T matrix of
event positions (event-level) to deterministically replay the
bootstrap across sessions, processes, or languages. The event-level
matrix holds the fully expanded resampled positions, i.e. the same
form produced internally, so a captured indices_used can be fed
straight back in.
NA handling. Per-cell summary statistics (mean, se,
ci_low, ci_high, p_boot) are computed with na.rm = TRUE,
so replicates that produced NA for a given cell (for example
structural-zero cells, or cells whose row marginal collapsed to
zero in the resampled data) are excluded from that cell's
summary. The summary therefore reflects only the finite
replicates; cells whose every replicate was NA come back as
NA themselves.
Value
An object of class c("lsa_bootstrap", "list") with:
- edges
Tidy per-edge data frame with observed + bootstrap
mean,se,ci_low,ci_high,p_boot, andstableforcount,adj_res,prob, andyules_q.- boot_obs
R x K^2numeric matrix: cell-wise observed count from each replicate (flattened inas.vector(obs)order).- boot_adj_res
R x K^2matrix of adjusted residuals.- R, level, level_alpha, indices_used
Recipe metadata.
- fit
Reference to the original fit (for $params / labels).
References
Efron, B. (1979). Bootstrap methods: another look at the jackknife. Annals of Statistics, 7(1), 1-26.
Politis, D. N., & Romano, J. P. (1994). The stationary bootstrap. Journal of the American Statistical Association, 89(428), 1303-1313.
See Also
permute_lsa(), stability_lsa()
Examples
fit <- lsa(engagement, engine = "classical")
bs <- bootstrap_lsa(fit, R = 200)
head(bs$edges)
Analytic Certainty of Transition Edges (Dirichlet-Multinomial)
Description
Closed-form Bayesian alternative to bootstrap_lsa() for the
transition-probability edges of an lsa fit. Each state's outgoing
transitions are modelled as Dirichlet-Multinomial: with a Jeffreys
prior the posterior for a row is Dirichlet(count + prior), so each
edge probability is marginally Beta(a, b) and its posterior mean,
standard deviation, credible interval and stability decision are
available analytically. No resampling, so it runs in microseconds.
Usage
certainty_lsa(
fit,
prior = 0.5,
level_alpha = 0.95,
inference = c("stability", "threshold"),
consistency_range = c(0.75, 1.25),
edge_threshold = NULL
)
Arguments
fit |
An |
prior |
Numeric > 0. Dirichlet prior concentration added to every
cell. Default |
level_alpha |
Numeric in (0, 1). Credible-interval level. Default
|
inference |
|
consistency_range |
Length-2 multiplicative bounds for stability
inference. Default |
edge_threshold |
Numeric or |
Details
The result carries class c("lsa_certainty", "lsa_bootstrap") and an
edges table with the columns plot_forest() and
as.data.frame() expect, so it is a drop-in for a bootstrap result
(use metric = "prob").
Certainty vs bootstrap. Both answer "how precisely is this edge
pinned down?". They agree on homogeneous data. The Dirichlet posterior
treats transitions as independent, so on strongly heterogeneous data (a
mixture of latent classes with long sequences) it reports more
certainty than the sequence bootstrap – prefer bootstrap_lsa() then.
Value
An object of class c("lsa_certainty", "lsa_bootstrap", "list")
with an edges data frame (from, to, prob_observed,
prob_mean, prob_se, prob_ci_low, prob_ci_high, p_value,
stable, plus adj_res_observed/adj_res_stable for plotting), the
posterior matrices (mean, sd, ci_lower, ci_upper), and call
metadata (prior, level_alpha, inference, ...). For an
lsa_group, a named list of these (class lsa_certainty_group).
References
Johnston, L. & Jendoubi, T. (2026). How Delivery Mode Reshapes Resource Engagement: A Bayesian Differential Network Analysis. TNA Workshop 2026.
See Also
bootstrap_lsa(), stability_lsa(), plot_forest()
Examples
fit <- lsa(engagement)
cert <- certainty_lsa(fit)
cert
head(as.data.frame(cert))
Compare Groups' Transition Structures
Description
Permutation test for whether groups produce different LSA transition
structures. For each pair of groups it pools their sequences,
repeatedly reassigns the group label of whole sequences (preserving
the original group sizes), refits each pseudo-group, and builds a
permutation distribution of the per-edge difference in the chosen
measure. The two-sided p-value is
(1 + #{ |diff_perm| >= |diff_obs| }) / (1 + R) (Phipson & Smyth
2010). A single omnibus test of overall difference is reported from
the same permutations.
Usage
compare_lsa(
x,
y = NULL,
R = 1000L,
measure = c("log_or", "adj_res", "yules_q", "prob", "count", "lift"),
adjust = "none",
min_count = 5L,
parallel = FALSE,
n_cores = NULL,
verbose = FALSE,
...
)
Arguments
x |
Either an |
y |
When |
R |
Integer. Number of label permutations per comparison.
Default |
measure |
Character. The per-edge quantity compared between
groups. Default |
adjust |
Multiple-comparison correction; any method accepted by
|
min_count |
Integer. Minimum pooled observed count (group a +
group b) for a transition to be tested. Default |
parallel |
Logical. Use multi-core resampling. Default |
n_cores |
Integer. Worker count when |
verbose |
Logical. Print progress every 100 permutations. |
... |
Reserved. NA handling. Non-estimable cells (structural zeros, zero-margin
rows in a permuted pseudo-group) carry Interpretation caveats. The odds ratio is non-collapsible: the per-group log odds ratios are group-specific departure-from- independence measures and should not be pooled across groups that have different marginal state distributions. As with any LSA, a between-group difference can also be driven by subgroup composition (Simpson's paradox); confirm with subgroup analysis when a confound is plausible. |
Details
With exactly two groups a single comparison is returned. With more
than two groups every pairwise comparison is run and the requested
adjust correction is applied once across the whole family of
per-edge p-values (and separately across the per-pair omnibus tests),
giving family-wise control rather than per-pair control.
Value
For two groups, an object of class
c("lsa_comparison", "list") with:
- edges
Tidy per-edge data frame:
from,to, the measure in each group (<measure>_a,<measure>_b), their differencediff(= a - b), the permutation p-valuep_perm, the adjusted p-valuep_adj, and asignificantflag.- global
Omnibus test list:
statistic(observed sum of squared edge differences),p_value, andR.- perm_diff
R x K^2matrix of permuted edge differences.- measure, R, adjust, groups
Call metadata;
groupsis the length-two character vector of group labels (a, b).- fits
The two original fits, named by group.
For more than two groups, an object of class
c("lsa_comparison_pairwise", "list") with:
- edges
Tidy per-edge data frame across all pairs, prefixed by
group_a,group_b;p_adjandsignificantreflect the family-wide correction.- global
One row per pair:
group_a,group_b,statistic,p_value, and the across-pairs adjustedp_adj.- comparisons
Named list of the underlying two-group
lsa_comparisonobjects (each fit withadjust = "none"), for drill-down.- measure, R, adjust, groups
Call metadata;
groupslists all group labels.
References
Phipson, B., & Smyth, G. K. (2010). Permutation p-values should never be zero. Statistical Applications in Genetics and Molecular Biology, 9(1), Article 39.
van Borkulo, C. D., et al. (2022). Comparing network structures on three aspects: A permutation test. Psychological Methods.
See Also
permute_lsa(), bootstrap_lsa()
Examples
# group_regulation is wide sequences with no grouping column, so
# derive one: sessions whose first regulation act is planning vs not.
grp <- ifelse(group_regulation$T1 == "plan", "starts_plan", "other")
g <- lsa(group_regulation, group = grp)
cmp <- compare_lsa(g, R = 200)
head(cmp$edges)
cmp$global
Student Engagement Trajectories
Description
Wide-format categorical sequence data: 138 students observed over 15
weekly time points. Each row is one student; each column is a
week. Entries are the student's engagement state for that week,
one of "Active", "Average", "Disengaged", or NA for missing
weeks.
Usage
engagement
Format
A data frame with 138 rows and 15 character columns.
Details
This is a standard small-K, multi-sequence example for lag
sequential analysis: K = 3 states, S = 138 sequences, mean sequence
length about 15. It exercises the wide-data input path of
lsa_data() and produces a stable transition pattern with clear
adjusted-residual signals.
Source
Derived from the trajectories matrix in the Nestimate
package (https://github.com/mohsaqr/Nestimate), which is
MIT-licensed and produced by Saqr and collaborators as a synthetic
engagement trajectory example. The state values are preserved and
stored here as a data frame for compatibility with sequence-data
tooling.
Examples
fit <- lsa(engagement, engine = "classical")
fit
fit$adj_res
Retrieve a Registered LSA Engine
Description
Retrieve a Registered LSA Engine
Usage
get_lsa_engine(name)
Arguments
name |
Character scalar. The engine's identifier. |
Value
The registry entry: a list with elements name, fn,
description, requires.
See Also
register_lsa_engine(), list_lsa_engines()
Examples
classical <- get_lsa_engine("classical")
classical$description
Collaborative Learning Self-Regulation Sequences
Description
A wide-format dataset of group regulation during collaborative
learning: each row is one group's session, each column an ordered
time point, and each cell a coded regulation action. Shorter sessions
are padded with NA. It is the flagship example for the package
vignette: 9 states over 2,000 sequences gives a realistically rich
transition network.
Usage
group_regulation
Format
A data.frame with 2,000 rows (sequences) and 26 columns
(ordered time points), character-coded.
Details
The nine coded actions are adapt, cohesion, consensus,
coregulate, discuss, emotion, monitor, plan, and
synthesis.
Examples
fit <- lsa(group_regulation)
transitions(fit, significant = TRUE)
Group Regulation Long Event Log
Description
A long-format event log of collaborative-learning regulation actions, one row per coded event. It is the long companion to the wide group_regulation sequence matrix: the same nine regulation actions, recorded here with actor, session, timing, and grouping columns so the package's long-format import, grouping, and between-group comparison paths can be demonstrated on a single realistic data set.
Usage
group_regulation_long
Format
A data.frame with 27,533 rows and 6 columns:
- Actor
Integer student identifier (2,000 students).
- Achiever
Achievement group,
HighorLow.- Group
Numeric collaboration-group identifier.
- Course
Course identifier (
A,B, orC).- Time
Event timestamp (
POSIXct).- Action
The regulation action code.
Details
The nine actions are adapt, cohesion, consensus, coregulate,
discuss, emotion, monitor, plan, and synthesis. The Achiever
column (High / Low) is a recorded grouping variable suitable for
between-group analysis.
Source
Derived without modification from tna::group_regulation_long
(tna package, MIT license).
See Also
group_regulation (the wide sequence matrix of the same actions)
Examples
fit <- lsa(group_regulation_long, actor = "Actor",
action = "Action", time = "Time")
transitions(fit, significant = TRUE)
Initial-State Distribution of an LSA Fit (Tidy)
Description
The proportion of sequences starting in each state, as a tidy
data.frame. These are the initial-state probabilities (init P) that
complement the transition-probability matrix from
transition_probabilities().
Usage
initial(fit)
## S3 method for class 'lsa'
initial(fit)
## S3 method for class 'lsa_group'
initial(fit)
Arguments
fit |
An |
Value
A data.frame with columns state, init_prob; zero rows
when the fit came from a transition matrix (no initial states).
See Also
Examples
initial(lsa(group_regulation))
Lag Profile of a Single Transition
Description
How one from -> to transition behaves across lags, as a tidy
one-row-per-lag data frame. A clean shortcut for "track this
transition over lags 1, 2, 3, ...".
Usage
lag_profile(x, from, to, lags = 1:3, ...)
Arguments
x |
Sequence input (any form accepted by |
from, to |
State labels of the transition to profile. |
lags |
Integer vector of lags. Default |
... |
Passed to |
Value
A tidy data.frame, one row per lag, with columns lag,
from, to, count, prob, adj_res, p, and significant.
See Also
Examples
lag_profile(group_regulation, "plan", "consensus", lags = 1:3)
List All Registered LSA Engines
Description
List All Registered LSA Engines
Usage
list_lsa_engines()
Value
A data.frame with columns name, description, requires.
See Also
register_lsa_engine(), get_lsa_engine()
Examples
list_lsa_engines()
Lag Sequential Analysis
Description
Fits a lag sequential analysis (LSA) on categorical event sequence data using a registered engine. Returns a tidy S3 object with named slots for observed/expected/probability/residual matrices and a long-format edge table suitable for transition-network visualization.
Usage
lsa_classical(data, ...)
lsa_two_cell(data, ...)
lsa_bidirectional(data, ...)
lsa_parallel_dominance(data, ...)
lsa_nonparallel_dominance(data, ...)
lsa(
data,
lag = 1,
engine = "classical",
alternative = c("two.sided", "greater", "less"),
alpha = 0.05,
loops = TRUE,
structural_zeros = NULL,
labels = NULL,
group = NULL,
actor = NULL,
action = NULL,
time = NULL,
order = NULL,
session = NULL,
time_threshold = 900,
custom_format = NULL,
is_unix_time = FALSE,
unix_time_unit = "seconds",
params = list(),
...
)
Arguments
data |
Sequence input (any form accepted by |
... |
Additional engine-specific parameters (merged into
|
lag |
Integer. The transition lag. Default |
engine |
Character scalar. The engine name, registered via
|
alternative |
Character scalar. The alternative hypothesis for
adjusted-residual and kappa p-values: one of |
alpha |
Numeric. Significance threshold used to mark edges as
significant in |
loops |
Logical. Keep self-transitions (the diagonal)? Default
|
structural_zeros |
Optional |
labels |
Optional character vector of state labels. |
group |
Optional grouping for a multi-group fit. Either a vector
with one entry per input sequence (length |
actor, action, time, order, session |
Column names (each a single
string) for long-format event-log input. Supplying |
time_threshold |
Numeric. Maximum gap in seconds between
consecutive events before a new session is started in long-format
mode. Default |
custom_format |
Optional |
is_unix_time |
Logical. Treat the |
unix_time_unit |
Character. Unit of the Unix epoch when
|
params |
Optional named list of engine-specific parameters forwarded to the engine function. |
Value
An object of class c("lsa", "cograph_network"). Read it with
the verbs rather than by reaching into slots: transitions() for the
tidy edge table, nodes(), tests(), initial(), and summary()
for the other results, and plot()/plot_transitions() to draw it.
Every number a verb returns is backed by these slots:
- edges
The tidy one-row-per-transition frame that backs
transitions()(with extracograph_networkprotocol columns).- nodes
Data frame backing
nodes():id, label, name, outgoing, incoming.- obs, exp, prob, prob_col, adj_res, p, yules_q, kappa, kappa_z, kappa_p
The same per-cell quantities as
edges, inK x Kmatrix form (probis row-conditional P(to | from),prob_colcolumn-conditional P(from | to)). Convenient for matrix algebra; not the primary interface.- lrx2, x2
Lists
(statistic, df, p)backingtests(): the tablewise likelihood-ratio (G^2) and Pearson chi-square tests of independence;NULLfor engines without an expected table.- inits
Named numeric vector backing
initial()(proportion of sequences starting in each state, sums to 1);NULLfor transition-matrix input.- weights
K x Kmatrix used as the default edge weight for plotting. Equal toobs(counts) by default.- directed
Logical scalar;
TRUEfor directed engines,FALSEforbidirectional.- method
Engine name (the slot the
cograph_networkprotocol reads). Also recorded inparams$engine.- data
The canonical
lsa_dataobject (events + seq_id).- params
Immutable snapshot of all parameters used (recipe), including
params$engine.- meta
List with source, IPF info, version, and call.
When group is supplied, returns an object of class
c("lsa_group", "list"): a named list of lsa fits (one per group
level) carrying levels, group_sizes, labels, and engine
attributes. Downstream verbs (transitions(),
transition_probabilities(), reliability_lsa(), etc.) dispatch on
it and return grouped results.
See Also
lsa_data(), lsa_transitions(), register_lsa_engine(),
list_lsa_engines()
Examples
seq <- c("Question", "Explain", "Agree",
"Question", "Explain", "Elaborate",
"Agree", "Question", "Explain")
fit <- lsa(seq, engine = "classical")
fit
head(fit$edges)
Canonicalize Sequence Input for Lag Sequential Analysis
Description
Coerces a wide variety of user input shapes into a single canonical representation used by every downstream lagdynamics function (engines, bootstrap, permutation, grouping, plotting).
Usage
lsa_data(x, labels = NULL)
Arguments
x |
Sequence input. See Details. |
labels |
Optional character vector of label names for the
states. When |
Details
Accepted input forms:
An atomic vector of integer or character codes — treated as a single sequence.
A list of atomic vectors — treated as multiple independent sequences; transitions are not counted across sequence boundaries.
A wide matrix or data.frame with rows = sequences, columns = ordered time points. Missing values (
NA) and empty strings are treated as missingness, not as a state: they are dropped wherever they occur in a row and the surrounding events close up, so no transition is counted into or out of a gap. To model missingness as its own state, recode it (e.g.NA -> "missing") before callinglsa().A square numeric matrix of pre-computed transition counts. Row
i, columnjis the count ofi -> jtransitions. In this caseeventsandseq_idare not available and downstream resampling tools that need event-level data will error.A sequence-bearing object: a
tnaorgroup_tna(sequences read from its$dataslot), atna_dataornestimate_data($sequence_data), or anstslist. The stored event sequences are recovered and analysed. Atnabuilt from a bare matrix (no retained sequences) errors, because transition counts cannot be recovered from probability weights.
Value
An object of class c("lsa_data", "list") with elements:
- events
Integer vector of event codes (1-indexed), or
NULLif input was a transition matrix.- seq_id
Integer vector of sequence membership, same length as
events, orNULLif input was a transition matrix.- labels
Character vector of state labels.
- n_states
Number of distinct states (
K).- n_sequences
Integer count of independent sequences.
- n_events
Total number of events across all sequences.
- transitions_per_seq
Integer vector: number of transitions each sequence contributes at lag 1.
- source
One of
"events","transitions"— flags whether event-level data is available.- obs_input
If
source = "transitions", the originalK x Kcount matrix. OtherwiseNULL.
See Also
Examples
# Single character sequence
d1 <- lsa_data(c("a", "b", "a", "c", "b"))
d1$n_events
# Multiple sequences
d2 <- lsa_data(list(c("a", "b", "a"), c("b", "c", "a", "b")))
d2$n_sequences
# Pre-computed transition matrix
tm <- matrix(c(0, 3, 1, 2, 0, 4, 5, 1, 0), 3, 3,
dimnames = list(c("a","b","c"), c("a","b","c")))
d3 <- lsa_data(tm)
d3$source
Iterative Proportional Fitting for Two-Way Tables with Structural Zeros
Description
Fits expected cell frequencies under the row + column independence
model when some cells are constrained to be exactly zero
(structural zeros). The fitted table has the same row and column
marginals as obs, satisfies E[i, j] = 0 wherever
structure[i, j] = 0, and is the maximum likelihood estimate under
the independence model restricted to the non-zero pattern.
Usage
lsa_ipf(obs, structure = NULL, tol = 1e-08, max_iter = 200L)
Arguments
obs |
Numeric |
structure |
Numeric |
tol |
Numeric. Convergence tolerance on marginal differences.
Default |
max_iter |
Integer. Maximum number of row+column scaling
passes. Default |
Details
Implementation follows Wickens (1989), pp. 107-112: alternately
scale rows then columns of an initialized expected table until row
and column marginals converge to those of obs within tol.
Value
A list with elements:
- fit
The fitted
K x Kexpected-frequency matrix.- iterations
Number of row+column passes used.
- converged
Logical scalar: whether convergence was reached within
max_iter.- max_margin_diff
Maximum absolute difference between observed and fitted marginals at termination.
References
Wickens, T. D. (1989). Multiway contingency tables analysis for the social sciences, pp. 107-112. Lawrence Erlbaum.
Examples
obs <- matrix(c(0, 4, 6,
3, 0, 5,
7, 2, 0), nrow = 3, byrow = TRUE)
fit <- lsa_ipf(obs)
fit$fit # fitted expected counts
all.equal(rowSums(fit$fit), rowSums(obs)) # TRUE
all.equal(colSums(fit$fit), colSums(obs)) # TRUE
Lag Sequential Analysis Across Several Lags
Description
Fits lsa() at each requested lag and returns the fits together, so
you can compare a transition's strength across lags (a lag
profile). Each element is an ordinary lsa fit.
Usage
lsa_lags(data, lags = 1:3, ...)
Arguments
data |
Sequence input (any form accepted by |
lags |
Integer vector of lags. May include negative lags
(predecessors) and |
... |
Passed to |
Value
An object of class c("lsa_lags", "list"): a named list of
lsa fits (names "lag1", "lag2", ...), with a lags attribute.
as.data.frame() on it row-binds transitions() of every fit (each
already carries its lag column) into one tidy long frame with the
same columns as transitions().
See Also
Examples
prof <- lsa_lags(engagement, lags = 1:3)
prof
# Track one transition across lags with the dedicated verb:
lag_profile(engagement, from = "Active", to = "Average", lags = 1:3)
Convert an lsa Fit to a tna Network
Description
Convert an lsa fit to a tna-class network object usable by the
tna package's centrality, pruning, community, and bootstrap routines.
Usage
lsa_to_tna(x, ...)
## S3 method for class 'lsa'
lsa_to_tna(x, weights = c("prob", "count", "adj_res", "lift"), ...)
## S3 method for class 'lsa_group'
lsa_to_tna(x, weights = c("prob", "count", "adj_res", "lift"), ...)
Arguments
x |
An |
... |
Method-specific arguments. |
weights |
Character. Which matrix to expose as the tna edge
weights. One of |
Details
This function is deliberately named lsa_to_tna(), not as_tna(),
to avoid overlapping export names with sibling packages.
Value
For an lsa fit, a tna object with weights, inits,
labels, and, when available, data slots. For an lsa_group, a
group_tna object.
Examples
fit <- lsa(engagement)
net <- lsa_to_tna(fit, weights = "prob")
tna::centralities(net)
Tidy Transition Counts at a Given Lag
Description
Computes the K x K transition count matrix from canonical lag
sequential data, optionally returning a tidy long-format edge table
alongside the matrix.
Usage
lsa_transitions(x, lag = 1)
Arguments
x |
Either an lsa_data object or any input accepted by
|
lag |
Integer. The lag at which to count transitions; default
|
Details
Transitions are counted within sequences only; no transition spans a
sequence boundary. For input that was supplied as a pre-computed
transition matrix (source = "transitions" on the lsa_data
object), the input matrix is returned at lag 1 and an error is
raised for any other lag.
Value
An object of class c("lsa_transitions", "list") with
elements:
- obs
The
K x Kobserved transition count matrix withdimnamesset to the labels.- row_totals
Length-
KvectorrowSums(obs).- col_totals
Length-
KvectorcolSums(obs).- n_transitions
Scalar
sum(obs).- lag
The lag used.
- labels
Character vector of state labels.
- edges
Tidy long-format data.frame with one row per
(from, to)cell containing columnsfrom,to,lag,count,row_total,col_total,n_transitions.
See Also
Examples
d <- lsa_data(c("a", "b", "a", "c", "b", "a"))
tx <- lsa_transitions(d, lag = 1)
tx$obs
head(tx$edges)
Nodes of an LSA Fit (Tidy)
Description
The states and their incoming / outgoing transition totals, as a
tidy data.frame (one row per state).
Usage
nodes(fit)
## S3 method for class 'lsa'
nodes(fit)
## S3 method for class 'lsa_group'
nodes(fit)
Arguments
fit |
An |
Value
A data.frame with columns state (the state name, matching
the from/to endpoints of transitions()), outgoing, and
incoming (its total out- and in-transition counts).
See Also
Examples
nodes(lsa(group_regulation))
Permutation Test for an LSA Fit
Description
Empirical null-distribution p-values for every cell of an LSA
transition matrix. Repeatedly shuffles the input event vector
(within sequence boundaries) and recomputes the engine's residual
matrix, producing a permutation distribution for each cell. The
two-sided p-value is (1 + #{ |stat_perm| >= |stat_obs| }) / (1 + R)
(Phipson & Smyth 2010).
Usage
permute_lsa(
fit,
R = 1000L,
within_sequence = TRUE,
shuffles = NULL,
parallel = FALSE,
n_cores = NULL,
verbose = FALSE,
...
)
Arguments
fit |
An |
R |
Integer. Number of permutations. Default |
within_sequence |
Logical. When |
shuffles |
Optional list of length |
parallel |
Logical. Use multi-core resampling. Default
|
n_cores |
Integer. Worker count when |
verbose |
Logical. Print progress every 100 replicates. |
... |
Reserved. NA handling. The exceedance count that drives |
Value
An object of class c("lsa_permutation", "list") with:
- edges
Tidy per-edge data frame with observed counts and residuals, the empirical permutation p-value
p_perm, and asignificantflag at the recipe's alpha threshold.- perm_adj_res
R x K^2numeric matrix of permuted residuals (cells inas.vector(adj_res)order).- R, within_sequence
Recipe metadata.
- fit
Reference to the original fit.
References
Castellan, N. J. (1992). Shuffling arrays: appearances may be deceiving. Behavior Research Methods, Instruments, & Computers, 24(1), 72-77.
Phipson, B., & Smyth, G. K. (2010). Permutation p-values should never be zero: calculating exact p-values when permutations are randomly drawn. Statistical Applications in Genetics and Molecular Biology, 9(1), Article 39.
See Also
bootstrap_lsa(), stability_lsa()
Examples
fit <- lsa(engagement, engine = "classical")
pm <- permute_lsa(fit, R = 200)
head(pm$edges)
Plot an LSA Fit
Description
One entry point for every view of a fit; pick it with type:
"heatmap" (default, the from x to residual heatmap), "network"
(transition network via cograph::splot()), "chord" (chord diagram
via cograph::plot_chord()), or "sunburst" (polar rose). Extra
arguments are forwarded to the chosen view's worker
(plot_transitions(), plot_chords(), plot_polar()); see those for
view-specific options.
Usage
## S3 method for class 'lsa'
plot(x, type = c("heatmap", "network", "chord", "sunburst"), ...)
## S3 method for class 'lsa_group'
plot(
x,
type = c("heatmap", "network", "chord", "sunburst"),
combined = FALSE,
...
)
Arguments
x |
An |
type |
Which view to draw: |
... |
Forwarded to the chosen view. For |
combined |
Logical, for a grouped fit only. |
Value
A ggplot object for "heatmap" and "sunburst"; the
(invisible) cograph object for "network" and "chord". Drawn
when printed.
See Also
plot_transitions(), plot_chords(), plot_polar(),
plot_forest(), transitions()
Examples
fit <- lsa(group_regulation)
plot(fit) # residual heatmap (default)
plot(fit, which = "prob") # heatmap of probabilities
plot(fit, type = "network") # transition network
plot(fit, type = "network", weights = "tna") # TNA probability network
plot(fit, type = "chord") # chord diagram
plot(fit, type = "sunburst") # polar sunburst
Plot an Analytic-Certainty Result
Description
Circular forest of the per-edge transition-probability credible
intervals from certainty_lsa() (delegates to plot_forest() with
metric = "prob").
Usage
## S3 method for class 'lsa_certainty'
plot(x, metric = "prob", ...)
Arguments
x |
An |
metric |
Which credible interval to draw. Default |
... |
Passed to |
Value
A ggplot object (drawn when printed). Needs ggplot2.
Examples
fit <- lsa(group_regulation)
cert <- certainty_lsa(fit)
plot(cert)
Plot a Group Comparison
Description
Two views of a compare_lsa() result. The default "barrel" is a
back-to-back pyramid (one row per transition): the first group's bar
runs left and the second's right, bar length is each group's
transition probability, bar colour is each group's log odds ratio
(blue = over-represented, red = avoided, following the vcd / mosaic
convention), bar ends show the observed count, and the centre chip
shows the difference p-value (bold and starred when significant). The
bar of the group with the higher value gets a border that darkens with
the size of the difference (faint = small, dark = large). For more
than two groups, one
barrel is drawn per pair via facets. The "heatmap" style draws the
signed difference as a from x to grid on the same diverging scale.
Usage
## S3 method for class 'lsa_comparison'
plot(
x,
style = c("barrel", "heatmap"),
value = c("prob", "count"),
rank = c("frequency", "effect"),
top_n = 12L,
...
)
## S3 method for class 'lsa_comparison_pairwise'
plot(
x,
style = c("barrel", "heatmap"),
value = c("prob", "count"),
rank = c("frequency", "effect"),
top_n = 12L,
...
)
Arguments
x |
An |
style |
|
value |
For |
rank |
For |
top_n |
For |
... |
Reserved. |
Value
A ggplot object (drawn when printed). Needs ggplot2.
See Also
Examples
grp <- ifelse(group_regulation$T1 == "plan", "starts_plan", "other")
g <- lsa(group_regulation, group = grp)
cmp <- compare_lsa(g, R = 200)
plot(cmp) # back-to-back barrel
plot(cmp, style = "heatmap") # difference heatmap
Circular (Chord) Diagram of an LSA Fit
Description
Draws the transition structure as a chord diagram via
cograph::plot_chord(): states are arcs on an outer ring and each
transition is a curved ribbon whose width is its frequency (or
probability) and whose fill colour is its adjusted residual
(warm = over-represented, cool = avoided). Supply a second fit as
compare to fill each ribbon by the difference in the colour metric
between the two fits.
Usage
plot_chords(
fit,
compare = NULL,
width = c("count", "prob"),
color = c("residuals", "lift", "prob", "count"),
significant = FALSE,
self_loops = TRUE,
alpha = 0.6,
...
)
Arguments
fit |
An |
compare |
Optional second |
width |
Which non-negative quantity sets ribbon width: |
color |
Which quantity fills the ribbons: |
significant |
Logical. Keep only significant transitions (drops
the others' ribbons). Ignored when |
self_loops |
Logical. Draw self-transition ribbons. Default
|
alpha |
Ribbon fill opacity. Default |
... |
Passed to |
Details
This is the circular companion to the plot.lsa() heatmap and the
plot_transitions() network. Like them it delegates the drawing to
cograph; it needs the cograph package installed.
Value
Invisibly, the list returned by cograph::plot_chord()
(segments and chords data frames). Drawn as a side effect.
See Also
plot.lsa() (heatmap), plot_transitions() (network),
transitions()
Examples
fit <- lsa(group_regulation)
plot_chords(fit) # ribbons filled by residual
plot_chords(fit, width = "prob") # width = probability
plot_chords(fit, significant = TRUE, ticks = TRUE)
# Compare two groups: ribbon colour = difference in residuals.
g <- lsa(group_regulation,
group = rep(c("A", "B"), length.out = nrow(group_regulation)))
plot_chords(g$A, compare = g$B)
Circular Bootstrap Forest of an LSA Fit
Description
Draws a radial forest of an bootstrap_lsa() result: each transition
is a spoke around a ring, spanning its bootstrap confidence interval,
with a square at the observed estimate and a dashed reference ring at
the null. Spokes whose adjusted residual is significant across
resamples are coloured by direction (warm = over-represented, cool =
avoided); non-significant ones are grey. Needs ggplot2.
Usage
plot_forest(
boot,
metric = c("residuals", "count", "prob", "yules_q"),
n_top = NULL,
show_nonsig = TRUE,
label_size = 2.6
)
## S3 method for class 'lsa_bootstrap'
plot(x, ...)
Arguments
boot |
An |
metric |
Which bootstrapped quantity to plot: |
n_top |
Optional integer: keep only the |
show_nonsig |
Logical. Draw non-significant edges (grey). Default
|
label_size |
Edge-label text size. Default |
x |
An |
... |
Passed to |
Value
A ggplot object (drawn when printed).
See Also
bootstrap_lsa(), plot.lsa() (heatmap),
plot_polar() (sunburst)
Examples
fit <- lsa(group_regulation)
b <- bootstrap_lsa(fit, R = 500)
plot_forest(b) # residual CIs, circular
plot_forest(b, metric = "prob") # probability CIs
plot_forest(b, show_nonsig = FALSE) # significant transitions only
Polar Sunburst of an LSA Fit
Description
Draws the transition structure as a polar sunburst with the source
states named along a large inner ring. Two styles: "rose" (default)
gives every target an equal angular slot and encodes frequency as the
radial bar height (so nothing crams); "wedge" sizes each
transition's angular width by its frequency share (the classic
look), omitting tiny wedges. Both fill by the adjusted residual (warm
= over-represented, cool = avoided), sharing the plot.lsa() heatmap
colour scale. Needs ggplot2.
Usage
plot_polar(
fit,
style = c("rose", "wedge"),
fill = c("residuals", "prob", "lift"),
size = c("count", "prob"),
significant = FALSE,
labels = c("all", "auto", "none"),
min_show = 0.01,
label_size = 3,
...
)
Arguments
fit |
An |
style |
|
fill |
Which quantity fills the bars/wedges: |
size |
For |
significant |
Logical. Grey out non-significant cells (keeping
their size). Default |
labels |
Which target cells to name: |
min_show |
For |
label_size |
Label text size. Default |
... |
Ignored; accepted so |
Value
A ggplot object (drawn when printed).
See Also
plot.lsa() (heatmap), plot_chords() (chord),
plot_forest() (bootstrap forest)
Examples
fit <- lsa(group_regulation)
plot_polar(fit) # rose: bars filled by residual
plot_polar(fit, style = "wedge") # classic frequency wedges
plot_polar(fit, significant = TRUE) # non-significant cells greyed
Plot the Transition Network
Description
Draws the directed transition network of an lsa fit with
cograph::splot(). Pick the edge weight with weights; optionally
keep only significant edges. Nodes are white and edges are labelled
by default. Returns the cograph network invisibly.
Usage
plot_transitions(
fit,
weights = c("residuals", "tna", "relative", "count", "prob", "lift", "yules_q"),
significant = FALSE,
top = NULL,
decimals = 1,
node_fill = "white",
edge_labels = TRUE,
...
)
Arguments
fit |
An |
weights |
Which matrix becomes the edge weight, and how it is drawn:
|
significant |
Logical. Keep only edges whose adjusted-residual
p-value is below the fit's alpha; weaker cells are set to 0 (no
edge). Default |
top |
Numeric or |
decimals |
Number of decimal places for edge labels. Default |
node_fill |
Node fill colour. Default |
edge_labels |
Logical (or a label vector). Show edge weights as
labels. Default |
... |
Passed to |
Value
The cograph_network object, invisibly (drawn as a side
effect).
See Also
plot.lsa() (heatmap), transitions(),
transition_probabilities()
Examples
fit <- lsa(group_regulation)
plot_transitions(fit) # residual network
plot_transitions(fit, weights = "tna") # TNA probabilities
plot_transitions(fit, weights = "relative") # same as "tna"
plot_transitions(fit, weights = "prob") # same matrix
plot_transitions(fit, weights = "residuals", # residual network,
significant = TRUE) # significant only
plot_transitions(fit, top = 12) # 12 strongest edges
plot_transitions(fit, top = 0.5) # strongest 50%
plot_transitions(fit, decimals = 2) # 2-dp edge labels
plot_transitions(fit, node_shape = "square") # splot passthrough
Register a Lag Sequential Analysis Engine
Description
Adds a new engine to the lagdynamics registry so it can be referenced by
name via lsa(..., engine = "<name>"). Built-in engines
("classical", "two_cell", "bidirectional",
"parallel_dominance", "nonparallel_dominance") are registered
automatically when the package loads.
Usage
register_lsa_engine(name, fn, description, requires = character())
Arguments
name |
Character scalar. The engine's identifier as used in
|
fn |
A function. Must accept a |
description |
Character scalar. One-line human-readable
description shown by |
requires |
Character vector. Names of packages the engine depends on. Empty by default. |
Value
Invisibly returns name.
See Also
get_lsa_engine(), list_lsa_engines(),
unregister_lsa_engine(), lsa()
Examples
my_engine <- function(transitions, ...) {
get_lsa_engine("classical")$fn(transitions, ...)
}
register_lsa_engine("my_classical", my_engine, "Classical test alias")
fit <- lsa(engagement, engine = "my_classical")
unregister_lsa_engine("my_classical")
fit
Split-Half Reliability for an LSA Fit
Description
Estimates the reliability of an LSA network by repeated random split-half resampling of sequences. Each replicate draws two disjoint halves of the sequences without replacement, refits the engine on each half, and computes the correlation between the two half-network edge-weight vectors. Returns the distribution of replicate correlations plus a point summary.
Usage
reliability_lsa(fit, ...)
## S3 method for class 'lsa'
reliability_lsa(
fit,
R = 100L,
weights = c("prob", "count", "adj_res"),
method = c("pearson", "spearman"),
parallel = FALSE,
n_cores = NULL,
verbose = FALSE,
...
)
## S3 method for class 'lsa_group'
reliability_lsa(fit, ...)
Arguments
fit |
An |
... |
Reserved. |
R |
Integer. Number of split-half replicates. Default |
weights |
Character. Which edge matrix to correlate across
halves: |
method |
Character. Correlation method: |
parallel |
Logical. Use multi-core resampling. Default |
n_cores |
Integer. Worker count when |
verbose |
Logical. Print progress every 100 replicates. |
Value
An object of class c("lsa_reliability", "list") with:
- correlations
Numeric vector of length
R: the split-half correlation of each replicate.- mean, sd
Mean and standard deviation of the finite replicate correlations.
- ci_low, ci_high
Empirical 2.5% and 97.5% quantiles.
- R, weights, method, n_sequences
Recipe metadata.
- fit
Reference to the original fit.
References
Epskamp, S., Borsboom, D., & Fried, E. I. (2018). Estimating psychological networks and their accuracy: A tutorial paper. Behavior Research Methods, 50(1), 195-212.
For a grouped fit (lsa_group), reliability is estimated separately
within each group and the per-group lsa_reliability objects are
returned in an lsa_reliability_group container with its own print
method.
See Also
bootstrap_lsa(), stability_lsa(), permute_lsa()
Examples
fit <- lsa(engagement, engine = "classical")
rel <- reliability_lsa(fit, R = 50)
rel
Case-Drop Stability for an LSA Fit
Description
Resamples the underlying sequence data without replacement at
a specified retention proportion, refits the engine on each
subsample, and records which edges remain significant at the
recipe's alpha threshold. Returns a per-edge "stability"
proportion: the fraction of subsamples in which the edge was
significant. Edges with stability >= min_stable (default
0.95) are flagged as robust.
Usage
stability_lsa(
fit,
R = 500L,
proportion = 0.8,
min_stable = 0.95,
parallel = FALSE,
n_cores = NULL,
verbose = FALSE,
...
)
Arguments
fit |
An |
R |
Integer. Number of subsamples. Default |
proportion |
Numeric in (0, 1). Fraction of cases retained
per subsample. Default |
min_stable |
Numeric in (0, 1). Stability threshold for
the |
parallel |
Logical. Use multi-core resampling. Default
|
n_cores |
Integer. Worker count when |
verbose |
Logical. Print progress every 100 replicates. |
... |
Reserved. |
Value
An object of class c("lsa_stability", "list") with:
- edges
Tidy per-edge data frame with
observed_sig(whether the cell was significant in the original fit),stability(fraction of subsamples in which the cell was significant), andstable(stability >= min_stable).- stability_matrix
R x K^20/1 matrix recording per-cell significance across replicates.- R, proportion, min_stable
Recipe metadata.
- fit
Reference to the original fit.
See Also
bootstrap_lsa(), permute_lsa()
Examples
fit <- lsa(engagement, engine = "classical")
st <- stability_lsa(fit, R = 100)
head(as.data.frame(st))
Tablewise Independence Tests of an LSA Fit (Tidy)
Description
The global tests of independence (likelihood-ratio G^2 and Pearson
chi-square) as a one-row-per-test data.frame.
Usage
tests(fit)
## S3 method for class 'lsa'
tests(fit)
## S3 method for class 'lsa_group'
tests(fit)
Arguments
fit |
An |
Value
A data.frame with columns test ("lrx2" / "x2"),
statistic, df, p. Tests the engine did not compute are
omitted.
See Also
Examples
tests(lsa(group_regulation))
Directed transfer entropy for categorical sequences (experimental)
Description
Experimental. Transfer entropy (Schreiber, 2000) measures directed predictive coupling: how much knowing the source's past reduces uncertainty about the target's future, beyond what the target's own past already explains. Because it conditions on the target's own history, transfer entropy is immune to the autocorrelation confound that inflates plain lagged association when a process has strong momentum.
Unlike lsa()'s Yule's Q / adjusted residuals, transfer entropy is
sign-blind: a large value means "strong directed predictive structure",
which may be facilitating or suppressing. Read it alongside the signed
measures from transitions() to interpret direction of effect.
Two modes:
-
State-flow network (default,
y = NULL): given categorical sequences, returns directed transfer entropy between every ordered pair of states, via a binary occupancy decomposition. Note: with very few states the non-target source channels become redundant; prefer the bivariate mode or a larger alphabet when that matters. -
Bivariate (
ysupplied): full-alphabet transfer entropy between two aligned categorical series, in both directions.
Usage
transfer_entropy(
x,
y = NULL,
lag = 1L,
history = 1L,
test = c("surrogate", "none"),
R = 199L,
normalize = TRUE,
seed = NULL
)
Arguments
x |
Categorical sequence data: a vector (one sequence), or a matrix /
data.frame with one sequence per row and one time-step per column
( |
y |
Optional second series, same shape as |
lag |
Integer >= 1. Prediction horizon: the target's future is taken
|
history |
Integer >= 1. Order of the target's own history conditioned
on (and combined into a composite symbol). Default |
test |
|
R |
Integer. Number of surrogate permutations. Default |
normalize |
Logical. Add |
seed |
Optional integer seed for the surrogate test. |
Value
A tidy data.frame, one row per ordered pair, with columns
from, to, te (bits), te_effective (surrogate-debiased),
te_normalised (0-1, if normalize), p (surrogate p-value), and
n (pooled transitions used). Rows are ordered by descending te.
References
Schreiber, T. (2000). Measuring information transfer. Physical Review Letters, 85(2), 461-464.
Examples
# Directed information-flow network over engagement states
transfer_entropy(engagement, test = "none")
# Bivariate transfer entropy between two aligned series
a <- c("calm", "calm", "tense", "tense", "calm", "tense", "tense", "calm")
b <- c("low", "low", "low", "high", "high", "low", "high", "high")
transfer_entropy(a, b, test = "none")
Transition-Probability Matrix of an LSA Fit
Description
The row-stochastic transition-probability matrix P(\text{to} \mid
\text{from}): each row holds the distribution over next states out of
a state, so the entries in a row sum to 1 (up to structural zeros).
This is the transition-probability matrix a Transition Network Analysis
reads; pair it with initial() for the initial-state probabilities.
Usage
transition_probabilities(fit)
## S3 method for class 'lsa'
transition_probabilities(fit)
## S3 method for class 'lsa_group'
transition_probabilities(fit)
Arguments
fit |
An |
Value
A square numeric matrix with from states in rows and to
states in columns. For an lsa_group, a named list of such matrices,
one per group.
See Also
initial() (initial-state probabilities), transitions()
(the tidy per-edge view), nodes()
Examples
transition_probabilities(lsa(group_regulation))
Transitions of an LSA Fit or an Inference Result (Tidy)
Description
The canonical way to read the per-transition table of a fit or of any
inference result as a tidy one-row-per-transition data.frame.
transitions(x) returns every transition; the arguments narrow it.
Usage
transitions(fit, ...)
## S3 method for class 'lsa'
transitions(
fit,
significant = FALSE,
direction = c("any", "over", "under"),
min_count = NULL,
alpha = NULL,
sort = c("none", "strength", "count", "prob"),
...
)
## S3 method for class 'lsa_group'
transitions(
fit,
significant = FALSE,
direction = c("any", "over", "under"),
min_count = NULL,
alpha = NULL,
sort = c("none", "strength", "count", "prob"),
...
)
## S3 method for class 'lsa_bootstrap'
transitions(fit, significant = FALSE, sort = c("none", "strength"), ...)
## S3 method for class 'lsa_certainty'
transitions(fit, significant = FALSE, sort = c("none", "strength"), ...)
## S3 method for class 'lsa_stability'
transitions(fit, significant = FALSE, sort = c("none", "strength"), ...)
## S3 method for class 'lsa_permutation'
transitions(fit, significant = FALSE, sort = c("none", "strength"), ...)
## S3 method for class 'lsa_comparison'
transitions(fit, significant = FALSE, sort = c("none", "strength"), ...)
## S3 method for class 'lsa_comparison_pairwise'
transitions(fit, significant = FALSE, sort = c("none", "strength"), ...)
## S3 method for class 'lsa_lags'
transitions(
fit,
significant = FALSE,
direction = c("any", "over", "under"),
min_count = NULL,
alpha = NULL,
sort = c("none", "strength", "count", "prob"),
...
)
Arguments
fit |
An |
... |
Arguments passed to the method. |
significant |
Logical. Keep only the transitions the method flags
as significant or stable. Default |
direction |
One of |
min_count |
Optional integer. Keep only transitions observed at
least this many times. Default |
alpha |
Significance threshold. Default |
sort |
Row ordering. |
Details
Applied to a fit from lsa() the table holds the estimated transition
statistics. Applied to the result of bootstrap_lsa(),
certainty_lsa(), stability_lsa(), permute_lsa(), compare_lsa()
or bayes_compare_lsa() the table holds that method's per-transition
quantities, and significant = TRUE keeps the transitions the method
itself flags: resampling-stable for bootstrap_lsa() and
certainty_lsa(), stable across replicates for stability_lsa(), and
below the significance threshold for permute_lsa(), compare_lsa()
and bayes_compare_lsa().
Value
A data.frame, one row per transition. For a fit the columns are
from, to (the source and target state names), lag, count,
expected, prob (row-conditional), prob_col (column-
conditional), adj_res, p, yules_q, kappa, kappa_z,
kappa_p, lift, sign, significant. Engines that compute extra
per-cell statistics append them as further columns (e.g. the two-cell
engine adds odds_ratio, log_or, log_or_se). An inference result
carries from, to and that method's own quantities. A grouped fit
gains a leading group column. Row names are reset.
See Also
Examples
fit <- lsa(group_regulation)
transitions(fit) # all transitions
transitions(fit, significant = TRUE) # significant ones
transitions(fit, direction = "over") # over-represented
transitions(fit, min_count = 500) # frequently observed
transitions(certainty_lsa(fit)) # analytic CIs per edge
transitions(certainty_lsa(fit), significant = TRUE) # the certain ones
Remove a Registered LSA Engine
Description
Remove a Registered LSA Engine
Usage
unregister_lsa_engine(name)
Arguments
name |
Character scalar. The engine's identifier. |
Value
Invisibly NULL.
See Also
Examples
my_engine <- function(transitions, ...) {
get_lsa_engine("classical")$fn(transitions, ...)
}
register_lsa_engine("temporary_engine", my_engine, "Temporary alias")
unregister_lsa_engine("temporary_engine")