install.packages("tna")1 Introduction
Transition Network Analysis (TNA) has emerged as a methodologically rigorous framework for modeling behavioral processes as weighted directed networks, combining the temporal resolution of stochastic process mining with the structural analytic capacity of graph theory (Saqr, López-Pernas, Törmänen, et al., 2025). Since its introduction at LAK 2025, the framework has expanded rapidly: it now supports multiple model types—first-order Markov models, frequency-based transition models, co-occurrence.
This is the companion tutorial to the main TNA tutorial, focusing on pairwise model comparison using the compare() function. We assume you have already worked through the main tutorial and understand the basics of building a TNA model.
A single TNA model describes one set of transition dynamics. But most research questions involve two models — high vs. low achievers, pre vs. post intervention, treatment vs. control. Visual inspection can suggest differences, but cannot tell you whether a 3% weight gap is meaningful or which of two nearly-equal edges is actually stronger. compare() quantifies what changed, by how much, and where, so that you can report precise differences rather than eyeball them.
This tutorial works through comparison at three levels of resolution:
- Network-level properties — are the two networks structurally different? One might be denser, more centralized, or more reciprocal, and these whole-network differences would be invisible if you only compared individual edges.
- Edge-level differences — which specific transitions changed and by how much? This includes the raw difference matrix, 16 per-edge metrics, summary statistics that condense overall divergence into reportable numbers, and visualizations (heatmaps, scatterplots, density plots).
- Centrality — did states change roles? A state that acts as a bridge in one group may be peripheral in the other, and centrality differences reveal these structural role shifts.
The compare() function returns seven components that map onto these levels:
| Component | What It Contains |
|---|---|
$network_metrics |
13 network-level structural properties |
$difference_matrix |
Element-wise difference (x - y) |
$edge_metrics |
16 edge-level comparison metrics |
$summary_metrics |
22 aggregate divergence metrics across 5 categories |
$matrices |
The (optionally scaled) input matrices |
$centrality_differences |
Per-node centrality differences across 9 measures |
$centrality_correlations |
Cross-model centrality rank correlations |
Companion tutorials:
- TNA Main Tutorial — building and analyzing a single TNA model
- TNA Group Analysis — group comparisons, permutation testing, and bootstrapping
- TNA Clustering — data-driven clustering of sequences
- Preparing Data for TNA — data import and preparation
1.1 Installation
The tna package is the only package required. Install from CRAN:
Or install the development version from GitHub:
# install.packages("remotes")
remotes::install_github("sonsoleslp/tna")2 Setup: Building Two Models to Compare
We use the built-in group_regulation_long dataset and build group-level TNA models for High and Low achievers. This gives us two models with different transition structures.
# Load the built-in collaborative regulation dataset
data("group_regulation_long")
# Convert to sequences, preserving the Achiever metadata column
prepared_data <- prepare_data(
group_regulation_long,
action = "Action",
actor = "Actor",
time = "Time"
)
# Build separate TNA models for High and Low achievers
gtna <- group_tna(prepared_data, group = "Achiever")The simplest way to call compare() is to pass the group TNA object directly. If the object has more than two groups, it picks the first two by default. You can also specify which groups to compare with i and j (by name or index):
# Pass the group object directly; compares the first two groups
comp <- compare(gtna)# Pick specific groups by name or index
comp <- compare(gtna, i = "High", j = "Low")
# Compare two individual tna models directly
comp <- compare(gtna$High, gtna$Low)3 Network Plots
Plotting the two networks side by side is the fastest way to get a sense of whether they look similar or different — before committing to any specific metric. Look for which transitions are strongest, which states are most active, and whether the two networks share the same dominant pathways. The minimum argument hides edges below a threshold, and cut fades edges below a second threshold, so the dominant structure stands out.
# Side-by-side network plots
plot(gtna, minimum = 0.05, cut = 0.1)