| Title: | Network Estimation, Bootstrap, and Higher-Order Analysis |
|---|---|
| Description: | Estimate, compare, and analyze dynamic and psychological networks using a unified interface. Provides transition network analysis estimation (transition, frequency, co-occurrence, attention-weighted) Saqr et al. (2025) <doi:10.1145/3706468.3706513>, psychological network methods (correlation, partial correlation, 'graphical lasso', 'Ising') Saqr, Beck, and Lopez-Pernas (2024) <doi:10.1007/978-3-031-54464-4_19>, and higher-order network methods including higher-order networks, higher-order network embedding, hyper-path anomaly, and multi-order generative model. Supports bootstrap inference, permutation testing, split-half reliability, centrality stability analysis, mixed Markov models, multi-cluster multi-layer networks and clustering. |
| Authors: | Mohammed Saqr [aut, cre, cph], Sonsoles López-Pernas [aut], Kamila Misiejuk [aut] |
| Maintainer: | Mohammed Saqr <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.6.2 |
| Built: | 2026-06-03 21:52:20 UTC |
| Source: | https://github.com/mohsaqr/Nestimate |
Convert a categorical Action column to one-hot (binary indicator) columns.
action_to_onehot( data, action_col = "Action", states = NULL, drop_action = TRUE, sort_states = FALSE, prefix = "" )action_to_onehot( data, action_col = "Action", states = NULL, drop_action = TRUE, sort_states = FALSE, prefix = "" )
data |
Data frame containing an action column. |
action_col |
Character. Name of the action column. Default: "Action". |
states |
Character vector or NULL. States to include as columns. If NULL, uses all unique values. Default: NULL. |
drop_action |
Logical. Remove the original action column. Default: TRUE. |
sort_states |
Logical. Sort state columns alphabetically. Default: FALSE. |
prefix |
Character. Prefix for state column names. Default: "". |
Data frame with one-hot encoded columns (0/1 integers).
long_data <- data.frame( Actor = rep(1:3, each = 4), Time = rep(1:4, 3), Action = sample(c("A", "B", "C"), 12, replace = TRUE) ) onehot_data <- action_to_onehot(long_data) head(onehot_data)long_data <- data.frame( Actor = rep(1:3, each = 4), Time = rep(1:4, 3), Action = sample(c("A", "B", "C"), 12, replace = TRUE) ) onehot_data <- action_to_onehot(long_data) head(onehot_data)
For each actor (row), reports the first and last observed states,
the time indices at which they appear, the number of observed
steps, and a dropped_out flag that is TRUE when the actor
has a terminal-NA pattern (after the final observed step,
every remaining cell is NA).
actor_endpoints(data, cols = NULL)actor_endpoints(data, cols = NULL)
data |
A wide-format matrix or data.frame where rows are
actors and columns are time steps. Cells are state labels;
|
cols |
Optional character vector of state-column names. If
|
A tidy data.frame with one row per actor and columns:
actorRow number (or row name if present).
first_stateFirst non-NA state.
last_stateLast non-NA state.
first_stepColumn index of the first observed state.
last_stepColumn index of the last observed state.
n_observedNumber of non-NA cells.
dropped_outTRUE iff every cell after last_step
is NA and last_step < ncol(data).
mark_terminal_state(), chain_structure()
actor_endpoints(trajectories) |> head()actor_endpoints(trajectories) |> head()
Converts a cluster_summary object to proper tna objects that can be
used with all functions from the tna package. Creates both a between-cluster
tna model (cluster-level transitions) and within-cluster tna models (internal
transitions within each cluster).
as_tna(x) ## S3 method for class 'mcml' as_tna(x) ## Default S3 method: as_tna(x)as_tna(x) ## S3 method for class 'mcml' as_tna(x) ## Default S3 method: as_tna(x)
x |
A |
This is the final step in the MCML workflow, enabling full integration with the tna package for centrality analysis, bootstrap validation, permutation tests, and visualization.
The tna package must be installed. If not available, the function throws an error with installation instructions.
# Full MCML workflow net <- build_network(data, method = "relative") net$nodes$clusters <- group_assignments cs <- cluster_summary(net) tna_models <- as_tna(cs) # Now use tna package functions plot(tna_models$macro) tna::centralities(tna_models$macro) tna::bootstrap(tna_models$macro, iter = 1000) # Analyze within-cluster patterns plot(tna_models$clusters$ClusterA) tna::centralities(tna_models$clusters$ClusterA)
A within-cluster network is dropped only when row-normalisation would
fail. Specifically, when the recorded net_method is
"relative" (row-stochastic transitions) and any node in the
cluster has zero outgoing weight, that cluster is excluded from
$clusters and a warning() is emitted listing the dropped
cluster names. For net_method = "frequency" (raw counts), a
zero-row node is a legitimate sink and the cluster is retained.
The macro / between-cluster network always includes every cluster
regardless of the per-cluster drop decisions.
If a cluster you expect to see is missing from the returned
$clusters, check the warning output and consider building with
type = "raw" (which carries through to a frequency-method
netobject and skips the drop) or inspect rowSums(x$clusters[[cl]]$weights).
A cluster_tna object (S3 class) containing:
A tna object representing cluster-level transitions.
Contains $weights (k x k transition matrix), $inits
(initial distribution), and $labels (cluster names).
Use this for analyzing how learners/entities move between high-level
groups or phases.
Named list of tna objects, one per cluster. Each tna object
represents internal transitions within that cluster. Contains
$weights (n_i x n_i matrix), $inits (initial distribution),
and $labels (node labels). Clusters with single nodes or zero-row
nodes are excluded (tna requires positive row sums).
A netobject_group with data preserved from each sub-network.
A tna object constructed from the input.
cluster_summary to create the input object,
plot() for visualization without conversion,
tna::tna for the underlying tna constructor
mat <- matrix(runif(36), 6, 6) rownames(mat) <- colnames(mat) <- LETTERS[1:6] clusters <- list(G1 = c("A", "B"), G2 = c("C", "D"), G3 = c("E", "F")) cs <- cluster_summary(mat, clusters) tna_models <- as_tna(cs) tna_models tna_models$macro$weightsmat <- matrix(runif(36), 6, 6) rownames(mat) <- colnames(mat) <- LETTERS[1:6] clusters <- list(G1 = c("A", "B"), G2 = c("C", "D"), G3 = c("E", "F")) cs <- cluster_summary(mat, clusters) tna_models <- as_tna(cs) tna_models tna_models$macro$weights
Discovers association rules using the Apriori algorithm with proper
candidate pruning. Accepts netobject (extracts sequences as
transactions), data frames, lists, or binary matrices.
Support counting is vectorized via crossprod() for 2-itemsets
and logical matrix indexing for k-itemsets.
association_rules( x, min_support = 0.1, min_confidence = 0.5, min_lift = 1, max_length = 5L )association_rules( x, min_support = 0.1, min_confidence = 0.5, min_lift = 1, max_length = 5L )
x |
Input data. Accepts:
|
min_support |
Numeric. Minimum support threshold. Default: 0.1. |
min_confidence |
Numeric. Minimum confidence threshold. Default: 0.5. |
min_lift |
Numeric. Minimum lift threshold. Default: 1.0. |
max_length |
Integer. Maximum itemset size. Default: 5. |
Uses level-wise Apriori (Agrawal & Srikant, 1994) with the full pruning step: after the join step generates k-candidates, all (k-1)-subsets are verified as frequent before support counting. This is critical for efficiency at k >= 4.
P(A and B). Fraction of transactions containing both antecedent and consequent.
P(B | A). Fraction of antecedent transactions that also contain the consequent.
P(A and B) / (P(A) * P(B)). Values > 1 indicate positive association; < 1 indicate negative association.
(1 - P(B)) / (1 - confidence). Measures departure from independence. Higher = stronger implication.
An object of class "net_association_rules" containing:
Data frame with columns: antecedent (list), consequent (list), support, confidence, lift, conviction, count, n_transactions.
List of frequent itemsets per level k.
Character vector of all items.
Integer.
Integer.
List of min_support, min_confidence, min_lift, max_length.
Agrawal, R. & Srikant, R. (1994). Fast algorithms for mining association rules. In Proc. 20th VLDB Conference, 487–499.
# From a list of transactions trans <- list( c("plan", "discuss", "execute"), c("plan", "research", "analyze"), c("discuss", "execute", "reflect"), c("plan", "discuss", "execute", "reflect"), c("research", "analyze", "reflect") ) rules <- association_rules(trans, min_support = 0.3, min_confidence = 0.5) print(rules) # From a netobject (sequences as transactions) seqs <- data.frame( V1 = sample(LETTERS[1:5], 50, TRUE), V2 = sample(LETTERS[1:5], 50, TRUE), V3 = sample(LETTERS[1:5], 50, TRUE) ) net <- build_network(seqs, method = "relative") rules <- association_rules(net, min_support = 0.1)# From a list of transactions trans <- list( c("plan", "discuss", "execute"), c("plan", "research", "analyze"), c("discuss", "execute", "reflect"), c("plan", "discuss", "execute", "reflect"), c("research", "analyze", "reflect") ) rules <- association_rules(trans, min_support = 0.3, min_confidence = 0.5) print(rules) # From a netobject (sequences as transactions) seqs <- data.frame( V1 = sample(LETTERS[1:5], 50, TRUE), V2 = sample(LETTERS[1:5], 50, TRUE), V3 = sample(LETTERS[1:5], 50, TRUE) ) net <- build_network(seqs, method = "relative") rules <- association_rules(net, min_support = 0.1)
Computes Betti numbers: (components),
(loops), (voids), etc.
betti_numbers(sc)betti_numbers(sc)
sc |
A |
Named integer vector c(b0 = ..., b1 = ..., ...).
mat <- matrix(c(0,.6,.5,.6,0,.4,.5,.4,0), 3, 3) colnames(mat) <- rownames(mat) <- c("A","B","C") sc <- build_simplicial(mat, threshold = 0.3) betti_numbers(sc)mat <- matrix(c(0,.6,.5,.6,0,.4,.5,.4,0), 3, 3) colnames(mat) <- rownames(mat) <- c("A","B","C") sc <- build_simplicial(mat, threshold = 0.3) betti_numbers(sc)
Constructs a net_hypergraph from long-format event
data in which each row records a player participating in a group
(a session, team, project, transaction, or any group context). Each
unique group becomes one hyperedge spanning the players that appeared in
it. Optional weight column produces a weighted incidence matrix.
bipartite_groups(data, player, group, weight = NULL)bipartite_groups(data, player, group, weight = NULL)
data |
Data frame in long format. Must contain |
player |
Character. Name of the column whose values become the hypergraph's nodes (players, participants, actors). |
group |
Character. Name of the column whose values become the hypergraph's hyperedges (groups, sessions, teams). |
weight |
Character or |
The bipartite representation preserves the full group structure without projecting to a pairwise network. A group of three players A, B, C produces a single 3-hyperedge containing all three, not three pairwise edges AB, AC, BC. This avoids information loss when group interactions are the primary unit of analysis (Perc et al. 2013).
Unlike build_hypergraph() (which derives hyperedges from a network's
clique structure), bipartite_groups() takes group memberships
directly. The two functions are complementary:
bipartite_groups() — when group membership is observed
(sessions, transactions, co-authorships).
build_hypergraph() — when only pairwise interactions are
observed and triadic structure must be inferred from triangles.
Rows with NA in either the player or group column (or, when
supplied, the weight column) are dropped silently.
A net_hypergraph object with the same structure produced by
build_hypergraph() (hyperedges, incidence, nodes, n_nodes,
n_hyperedges, size_distribution, params). The params list
records source = "bipartite_groups" and the original column names.
(experimental) Validated against a hand-computed table() incidence
reference only; no independent R package exposes the
long-format-to-binary-incidence primitive, because the operation is
definitionally table(). The code path is a direct one-to-one
restatement of its definition.
Perc, M., Gomez-Gardenes, J., Szolnoki, A., Floria, L. M., & Moreno, Y. (2013). Evolutionary dynamics of group interactions on structured populations: a review. Journal of the Royal Society Interface 10(80), 20120997. doi:10.1098/rsif.2012.0997
build_hypergraph() for the clique-based constructor.
df <- data.frame( player = c("Alice", "Bob", "Carol", "Alice", "Bob", "Dave", "Carol", "Dave", "Eve"), session = c("S1", "S1", "S1", "S2", "S2", "S3", "S3", "S3", "S3") ) hg <- bipartite_groups(df, player = "player", group = "session") print(hg) summary(hg)df <- data.frame( player = c("Alice", "Bob", "Carol", "Alice", "Bob", "Dave", "Carol", "Dave", "Eve"), session = c("S1", "S1", "S1", "S2", "S2", "S3", "S3", "S3", "S3") ) hg <- bipartite_groups(df, player = "player", group = "session") print(hg) summary(hg)
Fast, single-call bootstrap for EBICglasso partial correlation networks. Combines nonparametric edge/centrality bootstrap, case-dropping stability analysis, edge/centrality difference tests, predictability CIs, and thresholded network into one function. Designed as a faster alternative to bootnet with richer output.
boot_glasso( x, iter = 1000L, cs_iter = 500L, cs_drop = seq(0.1, 0.9, by = 0.1), alpha = 0.05, gamma = 0.5, nlambda = 100L, centrality = c("strength", "expected_influence", "betweenness", "closeness"), centrality_fn = NULL, cor_method = "pearson", ncores = 1L, seed = NULL )boot_glasso( x, iter = 1000L, cs_iter = 500L, cs_drop = seq(0.1, 0.9, by = 0.1), alpha = 0.05, gamma = 0.5, nlambda = 100L, centrality = c("strength", "expected_influence", "betweenness", "closeness"), centrality_fn = NULL, cor_method = "pearson", ncores = 1L, seed = NULL )
x |
A data frame, numeric matrix (observations x variables), or
a |
iter |
Integer. Number of nonparametric bootstrap iterations (default: 1000). |
cs_iter |
Integer. Number of case-dropping iterations per drop proportion (default: 500). |
cs_drop |
Numeric vector. Drop proportions for CS-coefficient
computation (default: |
alpha |
Numeric. Significance level for CIs (default: 0.05). |
gamma |
Numeric. EBIC hyperparameter (default: 0.5). |
nlambda |
Integer. Number of lambda values in the regularization path (default: 100). |
centrality |
Character vector. Centrality measures to compute.
All four built-in measures ( |
centrality_fn |
Optional function. A custom centrality function
that takes a weight matrix and returns a named list of centrality
vectors. When |
cor_method |
Character. Correlation method: |
ncores |
Integer. Number of parallel cores for mclapply (default: 1, sequential). |
seed |
Integer or NULL. RNG seed for reproducibility. |
An object of class "boot_glasso" containing:
Original partial correlation matrix.
Original precision matrix.
Named list of original centrality vectors.
Named numeric vector of node R-squared.
Data frame of edge CIs (edge, weight, ci_lower, ci_upper, inclusion).
Named numeric vector of edge inclusion probabilities.
Partial correlation matrix with non-significant edges zeroed.
Named list of data frames (node, value, ci_lower, ci_upper) per centrality measure.
Named numeric vector of CS-coefficients per centrality measure.
Data frame of case-dropping correlations (drop_prop, measure, correlation).
Symmetric matrix of pairwise edge difference p-values.
Named list of symmetric p-value matrices per centrality measure.
Data frame of node predictability CIs (node, r2, ci_lower, ci_upper).
iter x n_edges matrix of bootstrap edge weights.
Named list of iter x p bootstrap centrality matrices.
iter x p matrix of bootstrap R-squared.
Character vector of node names.
Sample size.
Number of variables.
Number of nonparametric iterations.
Number of case-dropping iterations.
Drop proportions used.
Significance level.
EBIC hyperparameter.
Lambda path length.
Character vector of centrality measures.
Correlation method.
Lambda sequence used.
Selected lambda for original data.
Named numeric vector with timing in seconds.
build_network, bootstrap_network
set.seed(1) dat <- as.data.frame(matrix(rnorm(60), ncol = 3)) net <- build_network(dat, method = "glasso") bg <- boot_glasso(net, iter = 10, cs_iter = 5, centrality = "strength") set.seed(42) mat <- matrix(rnorm(60), ncol = 4) colnames(mat) <- LETTERS[1:4] net <- build_network(as.data.frame(mat), method = "glasso") boot <- boot_glasso(net, iter = 100, cs_iter = 50, seed = 42, centrality = c("strength", "expected_influence")) print(boot) summary(boot, type = "edges")set.seed(1) dat <- as.data.frame(matrix(rnorm(60), ncol = 3)) net <- build_network(dat, method = "glasso") bg <- boot_glasso(net, iter = 10, cs_iter = 5, centrality = "strength") set.seed(42) mat <- matrix(rnorm(60), ncol = 4) colnames(mat) <- LETTERS[1:4] net <- build_network(as.data.frame(mat), method = "glasso") boot <- boot_glasso(net, iter = 100, cs_iter = 50, seed = 42, centrality = c("strength", "expected_influence")) print(boot) summary(boot, type = "edges")
Non-parametric bootstrap for any network estimated by
build_network. Works with all built-in methods
(transition and association) as well as custom registered estimators.
For transition methods ("relative", "frequency",
"co_occurrence"), uses a fast pre-computation strategy:
per-sequence count matrices are computed once, and each bootstrap
iteration only resamples sequences via colSums (C-level)
plus lightweight post-processing. Data must be in wide format for
transition bootstrap; use convert_sequence_format to
convert long-format data first.
For association methods ("cor", "pcor", "glasso",
and custom estimators), the full estimator is called on resampled rows
each iteration.
If a transition network contains only one sequence, the function warns that such a network is not recommended for bootstrap or other confirmatory testing.
bootstrap_network( x, iter = 1000L, ci_level = 0.05, inference = "stability", consistency_range = c(0.75, 1.25), edge_threshold = NULL, seed = NULL, boundary = c("inclusive", "strict") )bootstrap_network( x, iter = 1000L, ci_level = 0.05, inference = "stability", consistency_range = c(0.75, 1.25), edge_threshold = NULL, seed = NULL, boundary = c("inclusive", "strict") )
x |
A |
iter |
Integer. Number of bootstrap iterations (default: 1000). |
ci_level |
Numeric. Significance level for CIs and p-values (default: 0.05). |
inference |
Character. |
consistency_range |
Numeric vector of length 2. Multiplicative
bounds for stability inference (default: |
edge_threshold |
Numeric or NULL. Fixed threshold for
|
seed |
Integer or NULL. RNG seed for reproducibility. |
boundary |
Character. Comparison rule when computing the consistency-range
p-value. |
An object of class "net_bootstrap" containing:
The original netobject.
Bootstrap mean weight matrix.
Bootstrap SD matrix.
P-value matrix.
Original weights where p < ci_level, else 0.
Lower CI bound matrix.
Upper CI bound matrix.
Consistency range lower bound (stability only).
Consistency range upper bound (stability only).
Long-format data frame of edge-level statistics.
Pruned netobject (non-significant edges zeroed).
Bootstrap config.
Inference parameters.
build_network, print.net_bootstrap,
summary.net_bootstrap
net <- build_network(data.frame(V1 = c("A","B","C"), V2 = c("B","C","A")), method = "relative") boot <- bootstrap_network(net, iter = 10) seqs <- data.frame( V1 = sample(LETTERS[1:4], 30, TRUE), V2 = sample(LETTERS[1:4], 30, TRUE), V3 = sample(LETTERS[1:4], 30, TRUE), V4 = sample(LETTERS[1:4], 30, TRUE) ) net <- build_network(seqs, method = "relative") boot <- bootstrap_network(net, iter = 100) print(boot) summary(boot)net <- build_network(data.frame(V1 = c("A","B","C"), V2 = c("B","C","A")), method = "relative") boot <- bootstrap_network(net, iter = 10) seqs <- data.frame( V1 = sample(LETTERS[1:4], 30, TRUE), V2 = sample(LETTERS[1:4], 30, TRUE), V3 = sample(LETTERS[1:4], 30, TRUE), V4 = sample(LETTERS[1:4], 30, TRUE) ) net <- build_network(seqs, method = "relative") boot <- bootstrap_network(net, iter = 100) print(boot) summary(boot)
Computes the bottleneck distance between two persistence diagrams. For finite pairs, the bottleneck distance is
where ranges over bijections and is the diagonal. Each
point may match a point in the other diagram or its projection onto
the diagonal at cost . Computed via binary search on
plus a Kuhn bipartite-matching feasibility check.
Essential classes (death = Inf in VR mode, or death = 0 in clique mode)
are matched one-to-one within each dimension. If the diagrams have
different numbers of essential classes in some dimension, the
bottleneck distance for that dimension is Inf.
bottleneck_distance(d1, d2, dimension = NULL, tol = .Machine$double.eps^0.5)bottleneck_distance(d1, d2, dimension = NULL, tol = .Machine$double.eps^0.5)
d1, d2
|
|
dimension |
Integer vector of dimensions to compare. |
tol |
Numerical tolerance for binary search (default
|
Named numeric vector. Names are "dim_<k>". Inf
indicates a structural mismatch (different essential counts in that
dimension); a self-distance is always 0.
Edelsbrunner, H. & Harer, J. (2010). Computational Topology: An Introduction. AMS. Section VIII.
mat1 <- matrix(c(0, .6, .5, .6, 0, .4, .5, .4, 0), 3, 3) rownames(mat1) <- colnames(mat1) <- c("A","B","C") ph1 <- persistent_homology(mat1, n_steps = 5) bottleneck_distance(ph1, ph1) # self-distance is 0mat1 <- matrix(c(0, .6, .5, .6, 0, .4, .5, .4, 0), 3, 3) rownames(mat1) <- colnames(mat1) <- c("A","B","C") ph1 <- persistent_homology(mat1, n_steps = 5) bottleneck_distance(ph1, ph1) # self-distance is 0
Convenience wrapper for build_network(method = "attention").
Computes decay-weighted transitions from sequence data.
build_atna(data, start = FALSE, end = FALSE, ...)build_atna(data, start = FALSE, end = FALSE, ...)
data |
Data frame (sequences or per-observation frequencies) or a square symmetric matrix (correlation or covariance). |
start |
Boundary marker prepended to every sequence as an explicit
start state (a pure source: no incoming edges, every sequence's first
transition is |
end |
Boundary marker placed in the single cell after each sequence's
last observed (non- |
... |
Additional arguments passed to |
A netobject (see build_network).
seqs <- data.frame(V1 = c("A","B","C"), V2 = c("B","C","A")) net <- build_atna(seqs)seqs <- data.frame(V1 = c("A","B","C"), V2 = c("B","C","A")) net <- build_atna(seqs)
Clusters wide-format sequences using pairwise string dissimilarity and either PAM (Partitioning Around Medoids) or hierarchical clustering. Supports 9 distance metrics including temporal weighting for Hamming distance. When the stringdist package is available, uses C-level distance computation for 100-1000x speedup on edit distances.
build_clusters( data, k, dissimilarity = "hamming", method = "pam", na_syms = c("*", "%"), weighted = FALSE, lambda = 1, seed = NULL, q = 2L, p = 0.1, covariates = NULL, estimator = c("auto", "firth", "multinom", "chisq"), ... )build_clusters( data, k, dissimilarity = "hamming", method = "pam", na_syms = c("*", "%"), weighted = FALSE, lambda = 1, seed = NULL, q = 2L, p = 0.1, covariates = NULL, estimator = c("auto", "firth", "multinom", "chisq"), ... )
data |
Input data. Accepts multiple formats:
|
k |
Integer. Number of clusters (must be between 2 and
|
dissimilarity |
Character. Distance metric. One of |
method |
Character. Clustering method. |
na_syms |
Character vector. Symbols treated as missing values.
Default: Missing-value distance rule: after symbols are converted to
|
weighted |
Logical. Apply exponential decay weighting to Hamming
distance positions? Only valid when |
lambda |
Numeric. Non-negative decay rate for weighted Hamming. Higher values weight earlier positions more strongly. Default: 1. |
seed |
Integer or NULL. Random seed for reproducibility. Default:
|
q |
Integer. Size of q-grams for |
p |
Numeric. Winkler prefix penalty for Jaro-Winkler distance.
Must be between 0 and 0.25. Default: |
covariates |
Optional. Post-hoc covariate analysis of cluster membership. Accepts:
For |
estimator |
Multinomial logit fitter for the covariate analysis.
|
... |
Unsupported. Supplying unused arguments raises an error. |
An object of class "net_clustering" containing:
The original input data.
Number of clusters.
Named integer vector of cluster assignments.
Overall average silhouette width.
Named integer vector of cluster sizes.
Clustering method used.
Distance metric used.
The computed dissimilarity matrix (dist object).
Integer vector of medoid row indices (PAM only; NULL for hierarchical methods).
Seed used (or NULL).
Logical, whether weighted Hamming was used.
Lambda value used (0 if not weighted).
seqs <- data.frame(V1 = c("A","B","C","A","B"), V2 = c("B","C","A","B","A"), V3 = c("C","A","B","C","B")) cl <- build_clusters(seqs, k = 2) cl seqs <- data.frame( V1 = sample(LETTERS[1:3], 20, TRUE), V2 = sample(LETTERS[1:3], 20, TRUE), V3 = sample(LETTERS[1:3], 20, TRUE), V4 = sample(LETTERS[1:3], 20, TRUE) ) cl <- build_clusters(seqs, k = 2) print(cl) summary(cl)seqs <- data.frame(V1 = c("A","B","C","A","B"), V2 = c("B","C","A","B","A"), V3 = c("C","A","B","C","B")) cl <- build_clusters(seqs, k = 2) cl seqs <- data.frame( V1 = sample(LETTERS[1:3], 20, TRUE), V2 = sample(LETTERS[1:3], 20, TRUE), V3 = sample(LETTERS[1:3], 20, TRUE), V4 = sample(LETTERS[1:3], 20, TRUE) ) cl <- build_clusters(seqs, k = 2) print(cl) summary(cl)
Convenience wrapper for build_network(method = "co_occurrence").
Computes co-occurrence counts from binary or sequence data.
build_cna(data, start = FALSE, end = FALSE, ...)build_cna(data, start = FALSE, end = FALSE, ...)
data |
Data frame (sequences or per-observation frequencies) or a square symmetric matrix (correlation or covariance). |
start |
Boundary marker prepended to every sequence as an explicit
start state (a pure source: no incoming edges, every sequence's first
transition is |
end |
Boundary marker placed in the single cell after each sequence's
last observed (non- |
... |
Additional arguments passed to |
A netobject (see build_network).
build_network, cooccurrence for
delimited-field, bipartite, and other non-sequence co-occurrence formats.
seqs <- data.frame(V1 = c("A","B","C"), V2 = c("B","C","A")) net <- build_cna(seqs)seqs <- data.frame(V1 = c("A","B","C"), V2 = c("B","C","A")) net <- build_cna(seqs)
Convenience wrapper for build_network(method = "cor").
Computes Pearson correlations from numeric data.
build_cor(data, ...)build_cor(data, ...)
data |
Data frame (sequences or per-observation frequencies) or a square symmetric matrix (correlation or covariance). |
... |
Additional arguments passed to |
A netobject (see build_network).
data(srl_strategies) net <- build_cor(srl_strategies)data(srl_strategies) net <- build_cor(srl_strategies)
Convenience wrapper for build_network(method = "frequency").
Computes raw transition counts from sequence data.
build_ftna(data, start = FALSE, end = FALSE, ...)build_ftna(data, start = FALSE, end = FALSE, ...)
data |
Data frame (sequences or per-observation frequencies) or a square symmetric matrix (correlation or covariance). |
start |
Boundary marker prepended to every sequence as an explicit
start state (a pure source: no incoming edges, every sequence's first
transition is |
end |
Boundary marker placed in the single cell after each sequence's
last observed (non- |
... |
Additional arguments passed to |
A netobject (see build_network).
seqs <- data.frame(V1 = c("A","B","C"), V2 = c("B","C","A")) net <- build_ftna(seqs)seqs <- data.frame(V1 = c("A","B","C"), V2 = c("B","C","A")) net <- build_ftna(seqs)
Estimates person-specific directed networks from intensive longitudinal data using the unified Structural Equation Modeling (uSEM) framework. Implements a data-driven search that identifies:
Group-level paths: Directed edges present for a majority (default 75\
Individual-level paths: Additional edges specific to each person, found after group paths are established.
Uses lavaan for SEM estimation and modification indices.
Accepts a single data frame with an ID column (not CSV directories).
build_gimme( data, vars, id, time = NULL, ar = TRUE, standardize = FALSE, groupcutoff = 0.75, subcutoff = 0.5, paths = NULL, exogenous = NULL, hybrid = FALSE, rmsea_cutoff = 0.05, srmr_cutoff = 0.05, nnfi_cutoff = 0.95, cfi_cutoff = 0.95, n_excellent = 2L, seed = NULL )build_gimme( data, vars, id, time = NULL, ar = TRUE, standardize = FALSE, groupcutoff = 0.75, subcutoff = 0.5, paths = NULL, exogenous = NULL, hybrid = FALSE, rmsea_cutoff = 0.05, srmr_cutoff = 0.05, nnfi_cutoff = 0.95, cfi_cutoff = 0.95, n_excellent = 2L, seed = NULL )
data |
A |
vars |
Character vector of variable names to model. |
id |
Character string naming the person-ID column. |
time |
Character string naming the time/order column, or |
ar |
Logical. If |
standardize |
Logical. If |
groupcutoff |
Numeric between 0 and 1. Proportion of individuals for
whom a path must be significant to be added at group level.
Default |
subcutoff |
Numeric. Not used (reserved for future subgrouping). |
paths |
Character vector of lavaan-syntax paths to force into the model
(e.g., |
exogenous |
Character vector of variable names to treat as exogenous.
Default |
hybrid |
Logical. If |
rmsea_cutoff |
Numeric. RMSEA threshold for excellent fit (default 0.05). |
srmr_cutoff |
Numeric. SRMR threshold for excellent fit (default 0.05). |
nnfi_cutoff |
Numeric. NNFI/TLI threshold for excellent fit (default 0.95). |
cfi_cutoff |
Numeric. CFI threshold for excellent fit (default 0.95). |
n_excellent |
Integer. Number of fit indices that must be excellent to
stop individual search. Default |
seed |
Integer or |
An S3 object of class "net_gimme" containing:
temporalp x p matrix of group-level temporal (lagged)
path counts – entry [i,j] = number of individuals with path j(t-1)->i(t).
contemporaneousp x p matrix of group-level contemporaneous
path counts – entry [i,j] = number of individuals with path j(t)->i(t).
coefsList of per-person p x 2p coefficient matrices
(rows = endogenous, cols = [lagged, contemporaneous]).
psiList of per-person residual covariance matrices.
fitData frame of per-person fit indices (chisq, df, pvalue, rmsea, srmr, nnfi, cfi, bic, aic, logl, status).
path_countsp x 2p matrix: how many individuals have each path.
pathsList of per-person character vectors of lavaan path syntax.
group_pathsCharacter vector of group-level paths found.
individual_pathsList of per-person character vectors of individual-level paths (beyond group).
syntaxList of per-person full lavaan syntax strings.
labelsCharacter vector of variable names.
n_subjectsInteger. Number of individuals.
n_obsInteger vector. Time points per individual.
configList of configuration parameters.
# Create simple panel data (3 subjects, 4 variables, 50 time points). set.seed(42) n_sub <- 3; n_t <- 50; vars <- paste0("V", 1:4) rows <- lapply(seq_len(n_sub), function(i) { d <- as.data.frame(matrix(rnorm(n_t * 4), ncol = 4)) names(d) <- vars; d$id <- i; d }) panel <- do.call(rbind, rows) res <- build_gimme(panel, vars = vars, id = "id") print(res)# Create simple panel data (3 subjects, 4 variables, 50 time points). set.seed(42) n_sub <- 3; n_t <- 50; vars <- paste0("V", 1:4) rows <- lapply(seq_len(n_sub), function(i) { d <- as.data.frame(matrix(rnorm(n_t * 4), ncol = 4)) names(d) <- vars; d$id <- i; d }) panel <- do.call(rbind, rows) res <- build_gimme(panel, vars = vars, id = "id") print(res)
Convenience wrapper for build_network(method = "glasso").
Computes L1-regularized partial correlations with EBIC model selection.
build_glasso(data, ...)build_glasso(data, ...)
data |
Data frame (sequences or per-observation frequencies) or a square symmetric matrix (correlation or covariance). |
... |
Additional arguments passed to |
A netobject (see build_network).
data(srl_strategies) net <- build_glasso(srl_strategies)data(srl_strategies) net <- build_glasso(srl_strategies)
Constructs a Higher-Order Network from sequential data, faithfully implementing the BuildHON algorithm (Xu, Wickramarathne & Chawla, 2016).
The algorithm detects when a first-order Markov model is insufficient to capture sequential dependencies and automatically creates higher-order nodes. Uses KL-divergence to determine whether extending a node's history provides significantly different transition distributions.
build_hon( data, max_order = 5L, min_freq = 1L, collapse_repeats = FALSE, method = "hon+" )build_hon( data, max_order = 5L, min_freq = 1L, collapse_repeats = FALSE, method = "hon+" )
data |
One of:
|
max_order |
Integer. Maximum order of the HON. Default 5. The algorithm may produce lower-order nodes if the data do not justify higher orders. |
min_freq |
Integer. Minimum frequency for a transition to be
considered. Transitions observed fewer than |
collapse_repeats |
Logical. If |
method |
Character. Algorithm to use: |
Node naming convention: Higher-order nodes use readable arrow
notation. A first-order node is simply "A". A second-order node
representing the context "came from A, now at B" is "A -> B".
Third-order: "A -> B -> C", etc.
Algorithm overview:
Count all subsequence transitions up to max_order + 1.
Build probability distributions, filtering by min_freq.
For each first-order source, recursively test whether extending the history (adding more context) produces a significantly different distribution (via KL-divergence vs. an adaptive threshold).
Build the network from the accepted rules, rewiring edges so higher-order nodes are properly connected.
An S3 object of class "net_hon" containing:
Weighted adjacency matrix (rows = from, cols = to).
Rows and columns use readable arrow notation (e.g., "A -> B").
Data frame with columns: path (full state sequence,
e.g., "A -> B -> C"), from (context/conditioning states),
to (predicted next state), count (raw frequency),
probability (transition probability), from_order,
to_order.
data.frame with columns id, label,
name (one row per HON node; label/name are the
arrow-notation node names). Stored as a data.frame for
cograph_network compatibility.
Number of HON nodes.
Number of edges.
Character vector of unique original states.
The max_order parameter used.
Highest order actually present.
The min_freq parameter used.
Number of trajectories after parsing.
Logical. Always TRUE.
Xu, J., Wickramarathne, T. L., & Chawla, N. V. (2016). Representing higher-order dependencies in networks. Science Advances, 2(5), e1600028.
Saebi, M., Xu, J., Kaplan, L. M., Ribeiro, B., & Chawla, N. V. (2020). Efficient modeling of higher-order dependencies in networks: from algorithm to application for anomaly detection. EPJ Data Science, 9(1), 15.
seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) hon <- build_hon(seqs, max_order = 2) # From list of trajectories trajs <- list( c("A", "B", "C", "D", "A"), c("A", "B", "D", "C", "A"), c("A", "B", "C", "D", "A") ) hon <- build_hon(trajs, max_order = 3, min_freq = 1) print(hon) summary(hon) # From data.frame (rows = trajectories) df <- data.frame(T1 = c("A", "A"), T2 = c("B", "B"), T3 = c("C", "D"), T4 = c("D", "C")) hon <- build_hon(df, max_order = 2)seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) hon <- build_hon(seqs, max_order = 2) # From list of trajectories trajs <- list( c("A", "B", "C", "D", "A"), c("A", "B", "D", "C", "A"), c("A", "B", "C", "D", "A") ) hon <- build_hon(trajs, max_order = 3, min_freq = 1) print(hon) summary(hon) # From data.frame (rows = trajectories) df <- data.frame(T1 = c("A", "A"), T2 = c("B", "B"), T3 = c("C", "D"), T4 = c("D", "C")) hon <- build_hon(df, max_order = 2)
Constructs low-dimensional embeddings from a Higher-Order Network (HON) that preserve higher-order dependencies. Uses exponentially-decaying matrix powers of the HON transition matrix followed by truncated SVD.
build_honem(hon, dim = 32L, max_power = 10L)build_honem(hon, dim = 32L, max_power = 10L)
hon |
A |
dim |
Integer. Embedding dimension (default 32). |
max_power |
Integer. Maximum walk length for neighborhood computation (default 10). Higher values capture longer-range structure. |
HONEM is parameter-free and scalable — no random walks, skip-gram, or hyperparameter tuning required.
An object of class net_honem with components:
Numeric matrix (n_nodes x dim) of node embeddings.
Character vector of node names.
Numeric vector of top singular values.
Proportion of variance explained.
Embedding dimension used.
Maximum power used.
Number of nodes embedded.
Saebi, M., Ciampaglia, G. L., Kazemzadeh, S., & Meyur, R. (2020). HONEM: Learning Embedding for Higher Order Networks. Big Data, 8(4), 255–269.
seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) hem <- build_honem(build_hon(seqs, max_order = 2), dim = 2) trajs <- list(c("A","B","C","D"), c("A","B","D","C"), c("B","C","D","A"), c("C","D","A","B")) hon <- build_hon(trajs, max_order = 2) emb <- build_honem(hon, dim = 4) print(emb) plot(emb)seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) hem <- build_honem(build_hon(seqs, max_order = 2), dim = 2) trajs <- list(c("A","B","C","D"), c("A","B","D","C"), c("B","C","D","A"), c("C","D","A","B")) hon <- build_hon(trajs, max_order = 2) emb <- build_honem(hon, dim = 4) print(emb) plot(emb)
Constructs a k-th order De Bruijn graph from sequential trajectory data and uses a hypergeometric null model to detect paths with anomalous frequencies. Paths occurring more or less often than expected under the null model are flagged as over- or under-represented.
build_hypa( data, order = 2L, alpha = 0.05, min_count = 5L, p_adjust = "BH", k = NULL )build_hypa( data, order = 2L, alpha = 0.05, min_count = 5L, p_adjust = "BH", k = NULL )
data |
A data.frame (rows = trajectories), list of character vectors,
|
order |
Integer scalar or integer vector. Order(s) of the De Bruijn
graph (default |
alpha |
Numeric. Significance threshold for anomaly classification (default 0.05). Paths with HYPA score < alpha are under-represented; paths with score > 1-alpha are over-represented. |
min_count |
Integer. Minimum observed count for a path to be
classified as anomalous (default 5). Paths with fewer observations
are always classified as |
p_adjust |
Character. Method for multiple testing correction of
p-values. Default |
k |
Deprecated. Former name of |
An object of class c("net_hypa", "cograph_network") with
components:
Data frame with path, from, to, observed, expected,
ratio, p_value, p_under, p_over, p_adjusted_under,
p_adjusted_over, anomaly, order
columns (one block of rows per requested order). The path
column shows the full state sequence
(e.g., "A -> B -> C"); from is the context (conditioning
states); to is the next state; ratio is
observed / expected; p_value is retained as an alias for
p_under, the raw lower-tail hypergeometric CDF value;
p_over is the inclusive upper-tail probability
P(X >= observed); p_adjusted_under and
p_adjusted_over are the corrected p-values for under- and
over-representation tests respectively.
Alias for scores (all orders, arrow notation).
Subset of scores classified as over-represented.
Subset of scores classified as under-represented.
Weighted adjacency matrix of the lowest-order De Bruijn graph.
cograph weight matrix of the lowest-order graph.
Fitted propensity matrix of the lowest-order graph.
cograph edge data.frame of the lowest-order graph.
Named list of per-order result lists.
Integer vector of orders actually built (sorted ascending).
Back-compatibility alias for order.
Significance threshold used.
Multiple testing correction method used.
Number of anomalous paths detected (all orders).
Number of over-represented paths (all orders).
Number of under-represented paths (all orders).
Total number of edges (all orders).
data.frame (id, label, name) of the
lowest-order De Bruijn graph nodes (arrow notation).
Logical. Always TRUE.
cograph meta list of the lowest-order graph.
Always NULL.
LaRock, T., Nanumyan, V., Scholtes, I., Casiraghi, G., Eliassi-Rad, T., & Schweitzer, F. (2020). HYPA: Efficient Detection of Path Anomalies in Time Series Data on Networks. SDM 2020, 460-468.
seqs <- list(c("A","B","C"), c("B","C","A"), c("A","C","B"), c("A","B","C")) hyp <- build_hypa(seqs, order = 2) trajs <- list(c("A","B","C"), c("A","B","C"), c("A","B","C"), c("A","B","D"), c("C","B","D"), c("C","B","A")) h <- build_hypa(trajs, order = 2) print(h)seqs <- list(c("A","B","C"), c("B","C","A"), c("A","C","B"), c("A","B","C")) hyp <- build_hypa(seqs, order = 2) trajs <- list(c("A","B","C"), c("A","B","C"), c("A","B","C"), c("A","B","D"), c("C","B","D"), c("C","B","A")) h <- build_hypa(trajs, order = 2) print(h)
Takes a network and produces a hypergraph by promoting k-cliques (k >= 3)
to k-hyperedges. Each k-clique is independently included as a k-hyperedge
with probability p. Optionally retains the underlying pairwise edges as
2-hyperedges. Foundation for higher-order analyses.
build_hypergraph( net, p = 1, method = c("clique", "vr", "rips"), include_pairwise = TRUE, max_size = 3L, threshold = 0, seed = NULL ) ## S3 method for class 'net_hypergraph' print(x, ...) ## S3 method for class 'net_hypergraph' summary(object, ...)build_hypergraph( net, p = 1, method = c("clique", "vr", "rips"), include_pairwise = TRUE, max_size = 3L, threshold = 0, seed = NULL ) ## S3 method for class 'net_hypergraph' print(x, ...) ## S3 method for class 'net_hypergraph' summary(object, ...)
net |
A |
p |
Probability in |
method |
Hyperedge enumeration. |
include_pairwise |
Logical. Include 2-edges from the input network as
2-hyperedges. Default |
max_size |
Integer >= 2. Maximum hyperedge size to extract. Default
|
threshold |
Numeric. Edge weight cutoff used to binarise the
adjacency for clique enumeration. Default |
seed |
Optional integer for reproducible Bernoulli sampling when
|
x |
A |
... |
Additional arguments (ignored). |
object |
A |
The construction follows Burgio, Matamalas, Gomez & Arenas (2020) on
simplicial / hypergraph contagion. For each k-clique with k >= 3 found in
the underlying graph (via build_simplicial()), an independent
Bernoulli(p) trial decides whether that clique becomes a k-hyperedge.
Underlying pairwise edges are always retained when
include_pairwise = TRUE, so the resulting hypergraph contains both the
original 2-edge structure and the sampled higher-order interactions.
At the limits:
p = 0 with include_pairwise = TRUE reproduces the input
pairwise network as a hypergraph of size-2 edges.
p = 1 with include_pairwise = FALSE returns a fully
higher-order hypergraph containing only the k-hyperedges (k >= 3)
found in the network's clique complex.
A net_hypergraph object: a list with components
hyperedgesList of integer vectors. Each entry is a hyperedge given as the sorted node indices it spans.
incidenceNumeric matrix of size n_nodes x n_hyperedges.
incidence[i, j] = 1 iff node i belongs to hyperedge j. Row names
are node names; column names are h1, h2, ...
nodesCharacter vector of node names.
n_nodes, n_hyperedges
Scalar counts.
size_distributionNamed integer vector: number of hyperedges
of each size, named size_2, size_3, ...
paramsRecorded call parameters: method, p,
include_pairwise, max_size, threshold, seed.
The input x invisibly.
The input object invisibly.
Burgio, G., Matamalas, J. T., Gomez, S., & Arenas, A. (2020). Evolution of cooperation in the presence of higher-order interactions: from networks to hypergraphs. Entropy 22(7), 744. doi:10.3390/e22070744
build_simplicial() (underlying clique enumeration),
build_network().
set.seed(1) n <- 8 adj <- matrix(stats::rbinom(n * n, 1, 0.5), n, n) diag(adj) <- 0 adj <- (adj + t(adj)) > 0 rownames(adj) <- colnames(adj) <- LETTERS[seq_len(n)] hg <- build_hypergraph(adj, p = 1, max_size = 3L) print(hg) summary(hg)set.seed(1) n <- 8 adj <- matrix(stats::rbinom(n * n, 1, 0.5), n, n) diag(adj) <- 0 adj <- (adj + t(adj)) > 0 rownames(adj) <- colnames(adj) <- LETTERS[seq_len(n)] hg <- build_hypergraph(adj, p = 1, max_size = 3L) print(hg) summary(hg)
Convenience wrapper for build_network(method = "ising").
Computes L1-regularized logistic regression network for binary data.
build_ising(data, ...)build_ising(data, ...)
data |
Data frame (sequences or per-observation frequencies) or a square symmetric matrix (correlation or covariance). |
... |
Additional arguments passed to |
A netobject (see build_network).
if (requireNamespace("glmnet", quietly = TRUE)) { bin_data <- data.frame(matrix(rbinom(200, 1, 0.5), ncol = 5)) net <- build_ising(bin_data) }if (requireNamespace("glmnet", quietly = TRUE)) { bin_data <- data.frame(matrix(rbinom(200, 1, 0.5), ncol = 5)) net <- build_ising(bin_data) }
Builds a Multi-Cluster Multi-Level (MCML) model from raw transition data
(edge lists or sequences) by recoding node labels to cluster labels and
counting actual transitions. Unlike cluster_summary which
aggregates a pre-computed weight matrix, this function works from the
original transition data to produce the TRUE Markov chain over cluster states.
build_mcml( x, clusters = NULL, method = c("sum", "mean", "median", "max", "min", "density", "geomean"), type = c("tna", "frequency", "cooccurrence", "raw"), directed = TRUE, compute_within = TRUE, actor = NULL, action = NULL, time = NULL, order = NULL, session = NULL, time_threshold = 900, labels = NULL )build_mcml( x, clusters = NULL, method = c("sum", "mean", "median", "max", "min", "density", "geomean"), type = c("tna", "frequency", "cooccurrence", "raw"), directed = TRUE, compute_within = TRUE, actor = NULL, action = NULL, time = NULL, order = NULL, session = NULL, time_threshold = 900, labels = NULL )
x |
Input data. Accepts multiple formats:
|
clusters |
Cluster/group assignments. Accepts:
|
method |
Aggregation method for combining edge weights: "sum", "mean",
"median", "max", "min", "density", "geomean". Default "sum". For raw
sequence/event-log inputs the function is counting observed transitions,
so |
type |
Post-processing of the aggregated count matrix. One of:
|
directed |
Logical. If |
compute_within |
Logical. Compute within-cluster matrices? Default TRUE. |
actor, action, time, order, session, time_threshold
|
Long-format event-log
shortcut. When |
labels |
Optional name -> label remap applied to within-cluster nodes
(the macro layer is left untouched because its labels are cluster
names). Accepts a 2-column data.frame |
A cluster_summary object with meta$source = "transitions",
fully compatible with plot(), as_tna(), and
plot().
cluster_summary for matrix-based aggregation,
net_as_tna() to convert to tna objects,
plot() for visualization
# Edge list with clusters edges <- data.frame( from = c("A", "A", "B", "C", "C", "D"), to = c("B", "C", "A", "D", "D", "A"), weight = c(1, 2, 1, 3, 1, 2) ) clusters <- list(G1 = c("A", "B"), G2 = c("C", "D")) cs <- build_mcml(edges, clusters) cs$macro$weights # Sequence data with clusters seqs <- data.frame( T1 = c("A", "C", "B"), T2 = c("B", "D", "A"), T3 = c("C", "C", "D"), T4 = c("D", "A", "C") ) cs <- build_mcml(seqs, clusters, type = "raw") cs$macro$weights# Edge list with clusters edges <- data.frame( from = c("A", "A", "B", "C", "C", "D"), to = c("B", "C", "A", "D", "D", "A"), weight = c(1, 2, 1, 3, 1, 2) ) clusters <- list(G1 = c("A", "B"), G2 = c("C", "D")) cs <- build_mcml(edges, clusters) cs$macro$weights # Sequence data with clusters seqs <- data.frame( T1 = c("A", "C", "B"), T2 = c("B", "D", "A"), T3 = c("C", "C", "D"), T4 = c("D", "A", "C") ) cs <- build_mcml(seqs, clusters, type = "raw") cs$macro$weights
Estimates three networks from ESM/EMA panel data, matching
mlVAR::mlVAR() with estimator = "lmer", temporal = "fixed",
contemporaneous = "fixed" at machine precision: (1) a directed
temporal network of fixed-effect lagged regression coefficients, (2)
an undirected contemporaneous network of partial correlations among
residuals, and (3) an undirected between-subjects network of partial
correlations derived from the person-mean fixed effects.
#' @details The algorithm follows mlVAR's lmer pipeline exactly:
Drop rows with NA in id/day/beep and optionally grand-mean standardize each variable.
Expand the per-(id, day) beep grid and right-join original
values, producing the augmented panel (augData).
Add within-person lagged predictors (L1_*) and person-mean
predictors (PM_*).
For each outcome variable fit
lmer(y ~ within + between-except-own-PM + (1 | id)) with
REML = FALSE. Collect the fixed-effect temporal matrix B,
between-effect matrix Gamma, random-intercept SDs (mu_SD),
and lmer residual SDs.
Contemporaneous network:
cor2pcor(D %*% cov2cor(cor(resid)) %*% D).
Between-subjects network:
cor2pcor(pseudoinverse(forcePositive(D (I - Gamma)))).
Validated to machine precision (max_diff < 1e-10) against
mlVAR::mlVAR() on 25 real ESM datasets from openesm and 20 simulated
configurations (seeds 201-220). See tmp/mlvar_equivalence_real20.R and
tmp/mlvar_equivalence_20seeds.R.
build_mlvar( data, vars, id, day = NULL, beep = NULL, lag = 1L, standardize = FALSE )build_mlvar( data, vars, id, day = NULL, beep = NULL, lag = 1L, standardize = FALSE )
data |
A |
vars |
Character vector of variable column names to model. |
id |
Character string naming the person-ID column. |
day |
Character string naming the day/session column, or |
beep |
Character string naming the measurement-occasion column, or
|
lag |
Integer. The lag order (default 1). |
standardize |
Logical. If |
A dual-class c("net_mlvar", "netobject_group") object — a
named list of three full netobjects, one per network, plus
model-level metadata stored as attributes. Each element is a
standard c("netobject", "cograph_network") weight-matrix wrapper
(no raw $data), so print(), summary(), coefs(), and
cograph::splot(fit$temporal) work directly. The three constituents
are matrix-wrapped and carry no underlying panel data, so
data-resampling verbs such as bootstrap_network() (and
reliability/stability) cannot iterate over them — extract a single
constituent and rebuild via build_network() if you need those.
Structure:
fit$temporalDirected netobject for the d x d matrix of
fixed-effect lagged coefficients. $weights[i, j] is the effect
of variable j at t-lag on variable i at t. method = "mlvar_temporal", directed = TRUE.
fit$contemporaneousUndirected netobject for the d x d
partial-correlation network of within-person lmer residuals.
method = "mlvar_contemporaneous", directed = FALSE.
fit$betweenUndirected netobject for the d x d
partial-correlation network of person means, derived from
D (I - Gamma). method = "mlvar_between", directed = FALSE.
attr(fit, "coefs") / coefs()
Tidy data.frame with one
row per (outcome, predictor) pair and columns outcome,
predictor, beta, se, t, p, ci_lower, ci_upper,
significant. Filter, sort, or plot with base R or the tidyverse.
Retrieve with coefs(fit).
attr(fit, "n_obs")Number of rows in the augmented panel after na.omit.
attr(fit, "n_subjects")Number of unique subjects remaining.
attr(fit, "lag")Lag order used.
attr(fit, "standardize")Logical; whether pre-augmentation standardization was applied.
## Not run: d <- simulate_data("mlvar", seed = 1) fit <- build_mlvar(d, vars = attr(d, "vars"), id = "id", day = "day", beep = "beep") print(fit) summary(fit) ## End(Not run)## Not run: d <- simulate_data("mlvar", seed = 1) fit <- build_mlvar(d, vars = attr(d, "vars"), id = "id", day = "day", beep = "beep") print(fit) summary(fit) ## End(Not run)
Discovers latent subgroups with different transition dynamics using Expectation-Maximization. Each mixture component has its own transition matrix. Sequences are probabilistically assigned to components.
build_mmm( data, k = 2L, n_starts = 50L, max_iter = 200L, tol = 1e-06, smooth = 0.01, seed = NULL, covariates = NULL, covariate_effect = c("em", "posthoc"), estimator = c("auto", "firth", "multinom", "chisq") )build_mmm( data, k = 2L, n_starts = 50L, max_iter = 200L, tol = 1e-06, smooth = 0.01, seed = NULL, covariates = NULL, covariate_effect = c("em", "posthoc"), estimator = c("auto", "firth", "multinom", "chisq") )
data |
A data.frame (wide format), |
k |
Integer. Whole finite number of mixture components, >= 2. Default: 2. |
n_starts |
Integer. Positive whole finite number of random restarts. Default: 50. |
max_iter |
Integer. Positive whole finite maximum EM iterations per start. Default: 200. |
tol |
Numeric. Finite positive convergence tolerance. Default: 1e-6. |
smooth |
Numeric. Finite non-negative Laplace smoothing constant. Default: 0.01. |
seed |
Integer or NULL. Random seed. |
covariates |
Optional. Covariates integrated into the EM algorithm
to model covariate-dependent mixing proportions. Accepts a string,
character vector, formula, or data.frame (same forms as
|
covariate_effect |
How |
estimator |
Multinomial fitter for the post-hoc covariate
analysis (does not affect EM): |
An object of class net_mmm with components:
The full N-row sequence frame used for estimation.
List of netobjects, one per component. Each
component carries the rows assigned to that component in its
$data slot, while its transition matrix is the EM-estimated
component transition matrix.
Number of components.
Numeric vector of mixing proportions.
N x k matrix of posterior probabilities.
Integer vector of hard assignments (1..k).
List: avepp (per-class), avepp_overall,
entropy, relative_entropy,
classification_error.
Model fit statistics.
Character vector of state names.
The first sequence column has special status: it is read directly as
the per-sequence initial state (init_state[i] <-
match(raw_data[i, state_cols[1L]], states)). The function does
not scan forward to the first non-missing position, and it
does not apply any na_syms-style symbol conversion (unlike
build_clusters). The state vocabulary is built from the
unique non-NA values across all columns, so if your data uses
a sentinel character such as "*" or "%" for missing
cells, that sentinel becomes a real state and the first column reads
it as a valid initial state. If you want padded leading missings to
be treated as missing, recode them to NA before calling
build_mmm() (then match() returns NA, which the
EM treats as an uninformative initial distribution), or left-trim the
leading missings so each sequence's first column carries an observed
state.
seqs <- data.frame(V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE)) mmm <- build_mmm(seqs, k = 2, n_starts = 1, max_iter = 10, seed = 1) mmm seqs <- data.frame( V1 = sample(LETTERS[1:3], 30, TRUE), V2 = sample(LETTERS[1:3], 30, TRUE), V3 = sample(LETTERS[1:3], 30, TRUE), V4 = sample(LETTERS[1:3], 30, TRUE) ) mmm <- build_mmm(seqs, k = 2, seed = 42) print(mmm) summary(mmm)seqs <- data.frame(V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE)) mmm <- build_mmm(seqs, k = 2, n_starts = 1, max_iter = 10, seed = 1) mmm seqs <- data.frame( V1 = sample(LETTERS[1:3], 30, TRUE), V2 = sample(LETTERS[1:3], 30, TRUE), V3 = sample(LETTERS[1:3], 30, TRUE), V4 = sample(LETTERS[1:3], 30, TRUE) ) mmm <- build_mmm(seqs, k = 2, seed = 42) print(mmm) summary(mmm)
Constructs higher-order De Bruijn graphs from sequential trajectory data and selects the optimal Markov order using AIC, BIC, or likelihood ratio tests.
build_mogen( data, max_order = 5L, criterion = c("aic", "bic", "lrt"), lrt_alpha = 0.01 )build_mogen( data, max_order = 5L, criterion = c("aic", "bic", "lrt"), lrt_alpha = 0.01 )
data |
A data.frame (rows = trajectories, columns = time points) or a list of character/numeric vectors (one per trajectory). |
max_order |
Integer. Maximum Markov order to test (default 5).
Must be a whole number; a non-integer value (e.g. |
criterion |
Character. Model selection criterion: |
lrt_alpha |
Numeric. Significance threshold for LRT (default 0.01). |
At order k, nodes are k-tuples of states and edges represent transitions between overlapping k-tuples. The model tests increasingly complex Markov orders and selects the one that best balances fit and parsimony.
An object of class net_mogen with components:
Selected optimal Markov order.
Which criterion was used for selection.
Integer vector of tested orders (0 to max_order).
Named numeric vector of AIC values per order.
Named numeric vector of BIC values per order.
Named numeric vector of log-likelihoods.
Named integer vector of cumulative DOF per model.
Named integer vector of per-layer DOF.
List of transition matrices (index 1 = order 0).
Unique first-order states.
Number of trajectories.
Total number of state observations.
Scholtes, I. (2017). When is a Network a Network? Multi-Order Graphical Model Selection in Pathways and Temporal Networks. KDD 2017.
Gote, C. & Scholtes, I. (2023). Predicting variable-length paths in networked systems using multi-order generative models. Applied Network Science, 8, 62.
seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) mg <- build_mogen(seqs, max_order = 2) trajs <- list(c("A","B","C","D"), c("A","B","D","C"), c("B","C","D","A"), c("C","D","A","B")) m <- build_mogen(trajs, max_order = 3) print(m) plot(m)seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) mg <- build_mogen(seqs, max_order = 2) trajs <- list(c("A","B","C","D"), c("A","B","D","C"), c("B","C","D","A"), c("C","D","A","B")) m <- build_mogen(trajs, max_order = 3) print(m) plot(m)
Universal network estimation function that supports both transition networks (relative, frequency, co-occurrence) and association networks (correlation, partial correlation, graphical lasso). Uses the global estimator registry, so custom estimators can also be used.
build_network( data, method, actor = NULL, action = NULL, time = NULL, session = NULL, order = NULL, codes = NULL, group = NULL, format = "auto", window_size = 3L, mode = c("non-overlapping", "overlapping"), scaling = NULL, threshold = 0, level = NULL, time_threshold = 900, predictability = TRUE, state_cols = NULL, metadata_cols = NULL, start = FALSE, end = FALSE, params = list(), labels = NULL, ... )build_network( data, method, actor = NULL, action = NULL, time = NULL, session = NULL, order = NULL, codes = NULL, group = NULL, format = "auto", window_size = 3L, mode = c("non-overlapping", "overlapping"), scaling = NULL, threshold = 0, level = NULL, time_threshold = 900, predictability = TRUE, state_cols = NULL, metadata_cols = NULL, start = FALSE, end = FALSE, params = list(), labels = NULL, ... )
data |
Data frame (sequences or per-observation frequencies) or a square symmetric matrix (correlation or covariance). |
method |
Character. Required. Name of a registered estimator.
Built-in methods: |
actor |
Character. Name of the actor/person ID column for sequence
grouping. Default: |
action |
Character. Name of the action/state column (long format).
Default: |
time |
Character. Name of the time column (long format).
Default: |
session |
Character. Name of the session column. Default: |
order |
Character. Name of the ordering column. Default: |
codes |
Character vector. Column names of one-hot encoded states
(for onehot format). Default: |
group |
Character. Name of a grouping column for per-group networks.
Returns a |
format |
Character. Input format: |
window_size |
Integer. Window size for one-hot windowing.
Default: |
mode |
Character. Windowing mode for one-hot input only:
|
scaling |
Character vector or NULL. Post-estimation scaling to apply
(in order). Options: |
threshold |
Numeric. Absolute values below this are set to zero in the result matrix. Default: 0 (no thresholding). |
level |
Character or NULL. Multilevel decomposition for association
methods. One of |
time_threshold |
Numeric. Maximum time gap (seconds) for long format
session splitting. Default: |
predictability |
Logical. If |
state_cols |
Character vector or |
metadata_cols |
Character vector or |
start |
Boundary marker prepended to every sequence as an explicit
start state (a pure source: no incoming edges, every sequence's first
transition is |
end |
Boundary marker placed in the single cell after each sequence's
last observed (non- |
params |
Named list. Method-specific parameters passed to the estimator
function (e.g. |
labels |
Optional name -> label remap applied after construction.
Accepts a 2-column data.frame |
... |
Additional arguments passed to the estimator function. |
The function works as follows:
Resolves method aliases to canonical names.
Validates explicit column arguments before any format guessing.
Retrieves the estimator function from the global registry.
For association methods with level specified, decomposes
the data (between-person means or within-person centering).
Calls the estimator: do.call(fn, c(list(data = data), params)).
Applies scaling and thresholding to the result matrix.
Extracts edges and constructs the netobject.
For long-format transition data, supplying action without
actor is allowed and treats all rows as one sequence in row/time
order. The function warns because a one-sequence transition network is not
recommended and cannot be validated by bootstrap or other confirmatory
tests.
An object of class c("netobject", "cograph_network") containing:
The input data used for estimation, as a data frame.
The estimated network weight matrix.
Data frame with columns id, label, name,
x, y. Node labels are in $nodes$label.
Data frame of non-zero edges with integer from/to
(node IDs) and numeric weight.
Logical. Whether the network is directed.
The resolved method name.
The params list used (for reproducibility).
The scaling applied (or NULL).
The threshold applied.
Number of nodes.
Number of non-zero edges.
Decomposition level used (or NULL).
List with source, layout, and tna metadata
(cograph-compatible).
Node groupings data frame, or NULL.
Named numeric vector of R-squared predictability
values per node (for undirected association methods when
predictability = TRUE). NULL for directed methods.
Method-specific extras (e.g. precision_matrix, cor_matrix,
frequency_matrix, lambda_selected, etc.) are preserved
from the estimator output.
When level = "both", returns an object of class
"netobject_ml" with $between and $within
sub-networks and a $method field.
register_estimator, list_estimators,
bootstrap_network
seqs <- data.frame(V1 = c("A","B","C","A"), V2 = c("B","C","A","B")) net <- build_network(seqs, method = "relative") net # Transition network (relative probabilities) seqs <- data.frame( V1 = sample(LETTERS[1:4], 30, TRUE), V2 = sample(LETTERS[1:4], 30, TRUE), V3 = sample(LETTERS[1:4], 30, TRUE), V4 = sample(LETTERS[1:4], 30, TRUE) ) net <- build_network(seqs, method = "relative") print(net) # Association network (glasso) freq_data <- convert_sequence_format(seqs, format = "frequency") net_glasso <- build_network(freq_data, method = "glasso", params = list(gamma = 0.5, nlambda = 50)) # With scaling net_scaled <- build_network(seqs, method = "relative", scaling = c("rank", "minmax"))seqs <- data.frame(V1 = c("A","B","C","A"), V2 = c("B","C","A","B")) net <- build_network(seqs, method = "relative") net # Transition network (relative probabilities) seqs <- data.frame( V1 = sample(LETTERS[1:4], 30, TRUE), V2 = sample(LETTERS[1:4], 30, TRUE), V3 = sample(LETTERS[1:4], 30, TRUE), V4 = sample(LETTERS[1:4], 30, TRUE) ) net <- build_network(seqs, method = "relative") print(net) # Association network (glasso) freq_data <- convert_sequence_format(seqs, format = "frequency") net_glasso <- build_network(freq_data, method = "glasso", params = list(gamma = 0.5, nlambda = 50)) # With scaling net_scaled <- build_network(seqs, method = "relative", scaling = c("rank", "minmax"))
Convenience wrapper for build_network(method = "pcor").
Computes partial correlations from numeric data.
build_pcor(data, ...)build_pcor(data, ...)
data |
Data frame (sequences or per-observation frequencies) or a square symmetric matrix (correlation or covariance). |
... |
Additional arguments passed to |
A netobject (see build_network).
data(srl_strategies) net <- build_pcor(srl_strategies)data(srl_strategies) net <- build_pcor(srl_strategies)
Constructs a simplicial complex from a network or higher-order pathway object. Two construction methods are available:
Clique complex ("clique"): every clique in the
thresholded non-zero graph becomes a simplex. Edges with absolute
weight threshold are retained. The standard bridge
from graph theory to algebraic topology.
Pathway complex ("pathway"): each higher-order
pathway from a net_hon or net_hypa becomes a simplex.
For type = "vr" (or alias "rips"), the input is treated as
a non-negative distance / dissimilarity matrix and a Vietoris-Rips
filtration is constructed: each k-simplex enters at
. Use max_scale to cap the
filtration diameter; edges with d(i,j) > max_scale are excluded.
Filtration values are attached as $filtration on the returned
object so persistent_homology() can read them directly.
build_simplicial( x, type = "clique", threshold = 0, max_dim = 10L, max_pathways = NULL, anomaly = c("all", "over", "under"), max_scale = NULL, ... )build_simplicial( x, type = "clique", threshold = 0, max_dim = 10L, max_pathways = NULL, anomaly = c("all", "over", "under"), max_scale = NULL, ... )
x |
A square matrix, |
type |
Construction type: |
threshold |
For |
max_dim |
Maximum simplex dimension (default 10). Must be a single non-negative integer. A k-simplex has k+1 nodes. |
max_pathways |
For |
anomaly |
For HYPA pathway complexes, which anomaly direction to
include: |
max_scale |
For |
... |
Additional arguments passed to |
A simplicial_complex object. For type = "vr" an
additional $filtration numeric vector is attached (parallel to
$simplices).
betti_numbers, persistent_homology,
simplicial_degree, q_analysis
mat <- matrix(c(0,.6,.5,.6,0,.4,.5,.4,0), 3, 3) colnames(mat) <- rownames(mat) <- c("A","B","C") sc <- build_simplicial(mat, threshold = 0.3) print(sc) betti_numbers(sc) # Vietoris-Rips on a distance matrix: d <- 1 - mat diag(d) <- 0 sc_vr <- build_simplicial(d, type = "vr", max_scale = 0.6)mat <- matrix(c(0,.6,.5,.6,0,.4,.5,.4,0), 3, 3) colnames(mat) <- rownames(mat) <- c("A","B","C") sc <- build_simplicial(mat, threshold = 0.3) print(sc) betti_numbers(sc) # Vietoris-Rips on a distance matrix: d <- 1 - mat diag(d) <- 0 sc_vr <- build_simplicial(d, type = "vr", max_scale = 0.6)
Convenience wrapper for build_network(method = "relative").
Computes row-normalized transition probabilities from sequence data.
build_tna(data, start = FALSE, end = FALSE, ...)build_tna(data, start = FALSE, end = FALSE, ...)
data |
Data frame (sequences or per-observation frequencies) or a square symmetric matrix (correlation or covariance). |
start |
Boundary marker prepended to every sequence as an explicit
start state (a pure source: no incoming edges, every sequence's first
transition is |
end |
Boundary marker placed in the single cell after each sequence's
last observed (non- |
... |
Additional arguments passed to |
A netobject (see build_network).
seqs <- data.frame(V1 = c("A","B","C"), V2 = c("B","C","A")) net <- build_tna(seqs)seqs <- data.frame(V1 = c("A","B","C"), V2 = c("B","C","A")) net <- build_tna(seqs)
Computes a CS-coefficient for the edge-weight vector of a network:
the maximum proportion of cases (rows of x$data) that can be dropped
while the flattened edge-weight vector of the re-estimated network
still correlates with the original above threshold in at least
certainty of iterations.
Plots the four model-level reliability metrics across drop
proportions: correlation, mean_abs_dev, median_abs_dev,
max_abs_dev. Each panel shows the per-iteration mean with a ribbon
at mean +/- sd. The correlation panel includes a dashed horizontal
line at the user's threshold (default 0.7).
Overlay of per-cluster correlation curves across drop proportions. One colour per sub-network; ribbons show mean +/- sd across iterations. Dashed horizontal line marks the stability threshold (default 0.7).
casedrop_reliability( x, iter = 1000L, drop_prop = seq(0.1, 0.9, by = 0.1), threshold = 0.7, certainty = 0.95, method = c("spearman", "pearson", "kendall"), include_diag = FALSE, seed = NULL ) ## S3 method for class 'net_casedrop_reliability' print(x, digits = 3, ...) ## S3 method for class 'net_casedrop_reliability' summary(object, ...) ## S3 method for class 'net_casedrop_reliability_group' print(x, ...) ## S3 method for class 'net_casedrop_reliability_group' summary(object, drop_prop = NULL, ...) ## S3 method for class 'summary.net_casedrop_reliability_group' print(x, ...) ## S3 method for class 'net_casedrop_reliability' plot(x, combined = TRUE, ...) ## S3 method for class 'net_casedrop_reliability_group' plot( x, metric = c("correlation", "mean_abs_dev", "median_abs_dev", "max_abs_dev"), ... )casedrop_reliability( x, iter = 1000L, drop_prop = seq(0.1, 0.9, by = 0.1), threshold = 0.7, certainty = 0.95, method = c("spearman", "pearson", "kendall"), include_diag = FALSE, seed = NULL ) ## S3 method for class 'net_casedrop_reliability' print(x, digits = 3, ...) ## S3 method for class 'net_casedrop_reliability' summary(object, ...) ## S3 method for class 'net_casedrop_reliability_group' print(x, ...) ## S3 method for class 'net_casedrop_reliability_group' summary(object, drop_prop = NULL, ...) ## S3 method for class 'summary.net_casedrop_reliability_group' print(x, ...) ## S3 method for class 'net_casedrop_reliability' plot(x, combined = TRUE, ...) ## S3 method for class 'net_casedrop_reliability_group' plot( x, metric = c("correlation", "mean_abs_dev", "median_abs_dev", "max_abs_dev"), ... )
x |
A |
iter |
Integer. Iterations per drop proportion. Default |
drop_prop |
Drop proportion at which to report the four metrics
(mean +/- sd per network). Must be one of the drop proportions the
object was built with. Defaults to the object's median grid value
(the stored grid is used, not an assumed |
threshold |
Numeric in |
certainty |
Numeric in |
method |
Correlation method: |
include_diag |
Logical. Include diagonal (self-loop) edges in the
edge vector. Default |
seed |
Optional integer for reproducibility. |
digits |
Digits to display. Default |
... |
Additional arguments (ignored). |
object |
A |
combined |
When |
metric |
Which metric to plot. One of |
Complements centrality_stability(): that function asks whether
centrality rankings are stable; this one asks whether the edge-weight
structure itself is stable. For MCML-derived networks where each row
of $data is one transition, this is case-dropping of edges.
For each drop_prop p and each iteration, a size n_cases * (1 - p)
subset of $data rows is selected without replacement, the network
is re-estimated using the same method/scaling/threshold as the input,
and the upper/lower-triangle (directed: all off-diagonal entries) of
the new weight matrix is flattened and correlated with the
corresponding vector of the original matrix. The correlation method
defaults to Spearman for robustness to the wide dynamic range of
transition probabilities.
Unlike bootstrap CIs, case-dropping does not estimate sampling variance
and so does not rely on the i.i.d. assumption. This makes it the
appropriate robustness check for edgelist-derived networks (where
rows of $data lack actor grouping), since dropping rows at random is
a well-posed operation regardless of within-actor correlation.
An object of class net_casedrop_reliability with:
csScalar CS-coefficient — the maximum drop proportion for
which the edge-vector correlation remains >= threshold in at
least certainty of iterations. Zero if no proportion qualifies.
correlationsiter x length(drop_prop) matrix of per-
iteration correlations.
drop_prop, threshold, certainty, iter, method
Inputs.
The input x invisibly.
A tidy data frame with columns metric, drop_prop,
mean, sd summarising edge-weight stability across
case-dropping iterations.
A data frame with one row per network containing
cor, mean_abs_dev, median_abs_dev, max_abs_dev formatted as
"mean +/- sd".
A ggplot object, or a named list of four ggplots when
combined = FALSE.
A ggplot object.
Epskamp, S., Borsboom, D., & Fried, E. I. (2018). Estimating psychological networks and their accuracy: A tutorial paper. Behavior Research Methods 50(1), 195-212. doi:10.3758/s13428-017-0862-1
centrality_stability(), bootstrap_network().
seqs <- data.frame( V1 = sample(LETTERS[1:4], 30, TRUE), V2 = sample(LETTERS[1:4], 30, TRUE), V3 = sample(LETTERS[1:4], 30, TRUE) ) net <- build_network(seqs, method = "relative") es <- casedrop_reliability(net, iter = 50, drop_prop = c(0.1, 0.3, 0.5), seed = 1) print(es)seqs <- data.frame( V1 = sample(LETTERS[1:4], 30, TRUE), V2 = sample(LETTERS[1:4], 30, TRUE), V3 = sample(LETTERS[1:4], 30, TRUE) ) net <- build_network(seqs, method = "relative") es <- casedrop_reliability(net, iter = 50, drop_prop = c(0.1, 0.3, 0.5), seed = 1) print(es)
Estimates the stability of centrality indices under case-dropping.
For each drop proportion, sequences are randomly removed and the
network is re-estimated. The correlation between the original and
subset centrality values is computed. The CS-coefficient is the
maximum proportion of cases that can be dropped while maintaining
a correlation above threshold in at least certainty
of bootstrap samples.
For transition methods, uses pre-computed per-sequence count matrices for fast resampling. Strength centralities (InStrength, OutStrength) are computed directly from the matrix without igraph.
centrality_stability( x, measures = c("InStrength", "OutStrength", "Betweenness"), iter = 1000L, drop_prop = seq(0.1, 0.9, by = 0.1), threshold = 0.7, certainty = 0.95, method = "pearson", centrality_fn = NULL, loops = FALSE, seed = NULL )centrality_stability( x, measures = c("InStrength", "OutStrength", "Betweenness"), iter = 1000L, drop_prop = seq(0.1, 0.9, by = 0.1), threshold = 0.7, certainty = 0.95, method = "pearson", centrality_fn = NULL, loops = FALSE, seed = NULL )
x |
A |
measures |
Character vector. Centrality measures to assess.
Built-in: |
iter |
Integer. Number of bootstrap iterations per drop proportion (default: 1000). |
drop_prop |
Numeric vector. Proportions of cases to drop
(default: |
threshold |
Numeric. Minimum correlation to consider stable (default: 0.7). |
certainty |
Numeric. Required proportion of iterations above threshold (default: 0.95). |
method |
Character. Correlation method: |
centrality_fn |
Optional function. A custom centrality function
that takes a weight matrix and returns a named list of centrality
vectors. When |
loops |
Logical. If |
seed |
Integer or NULL. RNG seed for reproducibility. |
An object of class "net_stability" containing:
Named numeric vector of CS-coefficients per measure.
Named list of matrices (iter x n_prop) of correlation values per measure.
Character vector of measures assessed.
Drop proportions used.
Stability threshold.
Required certainty level.
Number of iterations.
Correlation method.
build_network, network_reliability
net <- build_network(data.frame(V1 = c("A","B","C","A"), V2 = c("B","C","A","B")), method = "relative") cs <- centrality_stability(net, iter = 10, drop_prop = 0.3) seqs <- data.frame( V1 = sample(LETTERS[1:4], 30, TRUE), V2 = sample(LETTERS[1:4], 30, TRUE), V3 = sample(LETTERS[1:4], 30, TRUE), V4 = sample(LETTERS[1:4], 30, TRUE) ) net <- build_network(seqs, method = "relative") cs <- centrality_stability(net, iter = 100, seed = 42, measures = c("InStrength", "OutStrength")) print(cs)net <- build_network(data.frame(V1 = c("A","B","C","A"), V2 = c("B","C","A","B")), method = "relative") cs <- centrality_stability(net, iter = 10, drop_prop = 0.3) seqs <- data.frame( V1 = sample(LETTERS[1:4], 30, TRUE), V2 = sample(LETTERS[1:4], 30, TRUE), V3 = sample(LETTERS[1:4], 30, TRUE), V4 = sample(LETTERS[1:4], 30, TRUE) ) net <- build_network(seqs, method = "relative") cs <- centrality_stability(net, iter = 100, seed = 42, measures = c("InStrength", "OutStrength")) print(cs)
Computes properties that depend only on the transition matrix support, not on any starting distribution: state classification, communicating classes, periods, irreducibility / aperiodicity / regularity / reversibility, hitting probabilities, and absorption analysis when absorbing states exist.
chain_structure(x, normalize = TRUE, tol = 1e-10)chain_structure(x, normalize = TRUE, tol = 1e-10)
x |
A |
normalize |
Logical. If |
tol |
Numerical tolerance for the reversibility check (detailed
balance) and for treating near-zero entries as zero when building the
support graph (which drives |
Built specifically as a diagnostic to run before trusting the output
of passage_time() or markov_stability(). Both implicitly assume a
regular chain (irreducible + aperiodic) so that the stationary
distribution is unique and meaningful. Use is_regular to check.
The fundamental-matrix absorption math follows Kemeny & Snell (1976); the hitting-probability linear system follows Norris (1997).
A chain_structure object: a list with elements
statesCharacter vector of state names.
classificationNamed character vector. One of "absorbing",
"recurrent", "transient" per state.
communicating_classesList of state-name vectors. Each sublist is a strongly connected component of the support graph.
recurrent_classesSubset of communicating_classes that are
closed (no transitions leaving the class).
transient_classesSubset that are not closed.
absorbing_statesCharacter vector of states with P[i, i] = 1
(tested exactly, to within .Machine$double.eps^0.5; the
user-facing tol does not relax this).
periodNamed integer vector. Period of each recurrent state;
NA for transient states.
is_irreducibleLogical. TRUE iff there is exactly one
communicating class.
is_aperiodicLogical. TRUE iff every recurrent state has
period 1.
is_regularLogical. is_irreducible && is_aperiodic.
is_reversibleLogical or NA. TRUE iff the chain
satisfies detailed balance against its stationary distribution.
NA for non-irreducible chains (no unique stationary).
hitting_probabilitiesn x n matrix. [i, j] = P(ever reach j starting from i), computed over the same tol-thresholded support
graph that drives classification so the two are mutually
consistent (a state classified "absorbing"/closed never shows
hitting probability to states outside its class).
absorption_probabilitiesn_transient x n_absorbing matrix
or NULL if no transient -> absorbing pathway exists. [i, j] = P(eventual absorption in j | start in i).
mean_absorption_timeNamed numeric vector or NULL. Expected
number of steps until absorption from each transient state.
PThe (possibly normalized) transition matrix used.
Kemeny, J. G. and Snell, J. L. (1976). Finite Markov Chains. Springer-Verlag.
Norris, J. R. (1997). Markov Chains. Cambridge University Press.
passage_time(), markov_stability(), build_network()
net <- build_network(as.data.frame(trajectories), method = "relative") cs <- chain_structure(net) print(cs) summary(cs)net <- build_network(as.data.frame(trajectories), method = "relative") cs <- chain_structure(net) print(cs) summary(cs)
Scale scores on five self-regulated learning (SRL) constructs for 1,000 responses generated by ChatGPT to a validated SRL questionnaire. Part of a larger dataset comparing LLM-generated responses to human norms across seven large language models.
chatgpt_srlchatgpt_srl
A data frame with 1,000 rows and 5 columns:
Numeric. Comprehension and Study Understanding scale mean.
Numeric. Intrinsic Value scale mean.
Numeric. Self-Efficacy scale mean.
Numeric. Self-Regulation scale mean.
Numeric. Task Avoidance scale mean.
Vogelsmeier, L.V.D.E., Oliveira, E., Misiejuk, K., Lopez-Pernas, S., & Saqr, M. (2025). Delving into the psychology of Machines: Exploring the structure of self-regulated learning via LLM-generated survey responses. Computers in Human Behavior, 173, 108769. doi:10.1016/j.chb.2025.108769
net <- build_network(chatgpt_srl, method = "glasso", params = list(gamma = 0.5)) netnet <- build_network(chatgpt_srl, method = "glasso", params = list(gamma = 0.5)) net
Projects a net_hypergraph to a standard pairwise
netobject (the clique expansion — also called the
"downgrade" of a hypergraph to a dyadic graph). Each hyperedge of size
k contributes 1 (or its weight) to every pair of its members. The
resulting edge weight W[i, j] equals the number of hyperedges
containing both i and j (binary incidence) or the sum of incidence
products (weighted incidence).
clique_expansion(hg, weighted = TRUE)clique_expansion(hg, weighted = TRUE)
hg |
A |
weighted |
Logical. If |
The clique expansion is the standard "loss-y but lossless-on-pairwise"
projection: it preserves which pairs co-occurred and how often but
discards the higher-order grouping. Comparing clique_expansion(hg) to
a directly-estimated pairwise network (e.g. via cooccurrence() on
the same data) quantifies how much information was carried by the
hyperedge structure.
Computed in one BLAS call via tcrossprod(incidence); runs in
O(n_nodes^2 * n_hyperedges) time, fast for typical sizes.
Closes the I/O cycle: event data -> bipartite_groups() ->
clique_expansion() -> any function that accepts a netobject
(centrality, bootstrap, clustering, plotting via cograph).
A netobject (also cograph_network) with method = "clique_expansion", undirected, with weighted symmetric adjacency
W = incidence %*% t(incidence) and zero diagonal.
(experimental) Validated against tcrossprod(incidence) with zero
diagonal. No external R package exposes clique expansion as a primitive;
the implementation is a direct one-line restatement of the definition.
Tian, Y., & Zafarani, R. (2024). Higher-order network analysis methods. SIGKDD Explorations 26(1), Section 5.1.5.
build_hypergraph(), bipartite_groups(), build_network().
df <- data.frame( player = c("A", "B", "C", "A", "B", "D", "C", "D", "E"), session = c("S1", "S1", "S1", "S2", "S2", "S3", "S3", "S3", "S3") ) hg <- bipartite_groups(df, player = "player", group = "session") net <- clique_expansion(hg) net$weightsdf <- data.frame( player = c("A", "B", "C", "A", "B", "D", "C", "D", "E"), session = c("S1", "S1", "S1", "S2", "S2", "S3", "S3", "S3", "S3") ) hg <- bipartite_groups(df, player = "player", group = "session") net <- clique_expansion(hg) net$weights
One-call sweep across any combination of k, dissimilarity metric, and
clustering algorithm for distance-based sequence clustering. Mirrors
compare_mmm for model-based clustering: returns a data
frame with one row per swept configuration, a best marker on
the silhouette-max row in the print method, and a plot() that
adapts to the swept axes.
cluster_choice( data, k = 2:5, dissimilarity = "hamming", method = "ward.D2", ... )cluster_choice( data, k = 2:5, dissimilarity = "hamming", method = "ward.D2", ... )
data |
Sequence data (data frame or matrix) – forwarded to
|
k |
Integer vector of cluster counts to sweep. Default
|
dissimilarity |
Character vector of dissimilarity metrics. Use
|
method |
Character vector of clustering algorithms. Use
|
... |
Other arguments forwarded to
|
A cluster_choice object (a data.frame subclass) with
one row per (k, dissimilarity, method) combination and columns:
The configuration for that row.
Overall average silhouette width (from
cluster::silhouette, computed inside
build_clusters).
Size-weighted mean of within-cluster distances, in the units of the row's dissimilarity.
Cluster-size balance bounds
and their ratio (max / min).
build_clusters, compare_mmm for
the model-based equivalent, cluster_diagnostics for
the post-fit diagnostic surface on a single clustering.
seqs <- data.frame(V1 = sample(c("A","B","C"), 40, TRUE), V2 = sample(c("A","B","C"), 40, TRUE)) cluster_choice(seqs, k = 2:4) # Sweep dissimilarities at fixed k cluster_choice(seqs, k = 3, dissimilarity = c("hamming", "lcs", "jaccard")) # Full grid of k x dissimilarity cluster_choice(seqs, k = 2:4, dissimilarity = c("hamming", "lcs")) # "all" sentinel cluster_choice(seqs, k = 3, dissimilarity = "all")seqs <- data.frame(V1 = sample(c("A","B","C"), 40, TRUE), V2 = sample(c("A","B","C"), 40, TRUE)) cluster_choice(seqs, k = 2:4) # Sweep dissimilarities at fixed k cluster_choice(seqs, k = 3, dissimilarity = c("hamming", "lcs", "jaccard")) # Full grid of k x dissimilarity cluster_choice(seqs, k = 2:4, dissimilarity = c("hamming", "lcs")) # "all" sentinel cluster_choice(seqs, k = 3, dissimilarity = "all")
Unified entry point for clustering quality information. Returns a
net_cluster_diagnostics object that normalises the diagnostic
surface across distance-based and model-based clusterings – you no
longer have to know which fields live on net_clustering vs.
net_mmm vs. the slim net_mmm_clustering attribute of a
netobject_group.
cluster_diagnostics(x, ...) ## S3 method for class 'net_cluster_diagnostics' as.data.frame(x, row.names = NULL, optional = FALSE, ...)cluster_diagnostics(x, ...) ## S3 method for class 'net_cluster_diagnostics' as.data.frame(x, row.names = NULL, optional = FALSE, ...)
x |
A |
... |
Unsupported. Supplying unused arguments raises an error. |
row.names, optional
|
Standard |
The returned object carries:
Either "distance" or "mmm".
Number of clusters, number of sequences, sizes vector.
A data.frame – one row per cluster, columns
differ by family. Distance: cluster, size,
pct, mean_within_dist, sil_mean. MMM:
cluster, size, pct, mix_pct,
avepp, class_err_pct.
A named list of family-specific summary metrics
(silhouette for distance; avepp_overall,
entropy, classification_error for MMM).
For MMM: a list with BIC, AIC, ICL.
NULL for distance.
Method / dissimilarity / weighted / lambda etc.
The original clustering object, kept by reference so
plot() can delegate without recomputing anything.
A net_cluster_diagnostics object.
print.net_cluster_diagnostics,
plot.net_cluster_diagnostics,
compare_mmm for k-sweep model selection (MMM only).
seqs <- data.frame(V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE)) cl <- build_clusters(seqs, k = 2, method = "ward.D2") cluster_diagnostics(cl) grp <- cluster_mmm(seqs, k = 2, n_starts = 1, max_iter = 20, seed = 1) cluster_diagnostics(grp) as.data.frame(cluster_diagnostics(grp))seqs <- data.frame(V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE)) cl <- build_clusters(seqs, k = 2, method = "ward.D2") cluster_diagnostics(cl) grp <- cluster_mmm(seqs, k = 2, n_starts = 1, max_iter = 20, seed = 1) cluster_diagnostics(grp) as.data.frame(cluster_diagnostics(grp))
Fits a mixture of Markov chains to sequence data and returns a
netobject_group containing per-cluster transition networks.
This is the MMM equivalent of cluster_network (which uses
distance-based clustering); both functions share the
cluster_by = ... surface argument so the call shape stays
uniform across clustering families.
cluster_mmm( data, k = 2L, n_starts = 50L, max_iter = 200L, tol = 1e-06, smooth = 0.01, seed = NULL, covariates = NULL, covariate_effect = c("em", "posthoc"), estimator = c("auto", "firth", "multinom", "chisq"), cluster_by = "mmm", ... )cluster_mmm( data, k = 2L, n_starts = 50L, max_iter = 200L, tol = 1e-06, smooth = 0.01, seed = NULL, covariates = NULL, covariate_effect = c("em", "posthoc"), estimator = c("auto", "firth", "multinom", "chisq"), cluster_by = "mmm", ... )
data |
A data.frame (wide format), |
k |
Integer. Whole finite number of mixture components, >= 2. Default: 2. |
n_starts |
Integer. Positive whole finite number of random restarts. Default: 50. |
max_iter |
Integer. Positive whole finite maximum EM iterations per start. Default: 200. |
tol |
Numeric. Finite positive convergence tolerance. Default: 1e-6. |
smooth |
Numeric. Finite non-negative Laplace smoothing constant. Default: 0.01. |
seed |
Integer or NULL. Random seed. |
covariates |
Optional. Covariates integrated into the EM algorithm
to model covariate-dependent mixing proportions. Accepts a string,
character vector, formula, or data.frame (same forms as
|
covariate_effect |
How |
estimator |
Multinomial fitter for the post-hoc covariate
analysis (does not affect EM): |
cluster_by |
Character. Accepted only as |
... |
Unsupported. Supplying unused arguments raises an error. |
For the full net_mmm object with posterior probabilities, model
fit statistics, and S3 methods, use build_mmm instead.
A netobject_group (list of netobjects, one per
cluster). MMM-specific information is stored in
attr(, "clustering") (class "net_mmm_clustering"):
Integer vector of cluster assignments.
Number of clusters.
N x k matrix of posterior probabilities.
Mixing proportions.
List with AvePP, entropy, classification error.
Model fit statistics.
The full N-row sequence frame, matching
$assignments – so sequence_plot and
distribution_plot can recover both.
build_mmm for the full MMM object,
cluster_network for distance-based clustering
seqs <- data.frame(V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE)) grp <- cluster_mmm(seqs, k = 2, n_starts = 1, max_iter = 10, seed = 1) grp[[1]]$weights attr(grp, "clustering")$assignments # Visualise with sequence_plot seqs <- data.frame( V1 = sample(LETTERS[1:3], 40, TRUE), V2 = sample(LETTERS[1:3], 40, TRUE), V3 = sample(LETTERS[1:3], 40, TRUE) ) grp <- cluster_mmm(seqs, k = 2) sequence_plot(grp, type = "index")seqs <- data.frame(V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE)) grp <- cluster_mmm(seqs, k = 2, n_starts = 1, max_iter = 10, seed = 1) grp[[1]]$weights attr(grp, "clustering")$assignments # Visualise with sequence_plot seqs <- data.frame( V1 = sample(LETTERS[1:3], 40, TRUE), V2 = sample(LETTERS[1:3], 40, TRUE), V3 = sample(LETTERS[1:3], 40, TRUE) ) grp <- cluster_mmm(seqs, k = 2) sequence_plot(grp, type = "index")
Combines sequence clustering and network estimation into a single call.
Clusters the data using the specified algorithm, then calls
build_network on each cluster subset.
cluster_network(data, k, cluster_by = "pam", dissimilarity = "hamming", ...)cluster_network(data, k, cluster_by = "pam", dissimilarity = "hamming", ...)
data |
Sequence data. Accepts a data frame, matrix, or
|
k |
Integer. Number of clusters. |
cluster_by |
Character. Clustering algorithm passed to
|
dissimilarity |
Character. Distance metric for sequence clustering.
Only valid when |
... |
Routed to two stages. For distance clustering
( |
If data is a netobject and method is not provided in
..., the original network method is inherited automatically so the
per-cluster networks match the type of the input network.
A netobject_group.
build_clusters, cluster_mmm,
build_network
seqs <- data.frame(V1 = c("A","B","C","A","B"), V2 = c("B","C","A","B","A"), V3 = c("C","A","B","C","B")) grp <- cluster_network(seqs, k = 2) grp set.seed(1) seqs <- data.frame( V1 = sample(LETTERS[1:4], 50, TRUE), V2 = sample(LETTERS[1:4], 50, TRUE), V3 = sample(LETTERS[1:4], 50, TRUE), V4 = sample(LETTERS[1:4], 50, TRUE) ) # Default: PAM clustering, relative (transition) networks grp <- cluster_network(seqs, k = 3) # Specify network method (cor requires numeric panel data) ## Not run: panel <- as.data.frame(matrix(rnorm(1500), nrow = 300, ncol = 5)) grp <- cluster_network(panel, k = 2, method = "cor") ## End(Not run) # MMM-based clustering grp <- cluster_network(seqs, k = 2, cluster_by = "mmm")seqs <- data.frame(V1 = c("A","B","C","A","B"), V2 = c("B","C","A","B","A"), V3 = c("C","A","B","C","B")) grp <- cluster_network(seqs, k = 2) grp set.seed(1) seqs <- data.frame( V1 = sample(LETTERS[1:4], 50, TRUE), V2 = sample(LETTERS[1:4], 50, TRUE), V3 = sample(LETTERS[1:4], 50, TRUE), V4 = sample(LETTERS[1:4], 50, TRUE) ) # Default: PAM clustering, relative (transition) networks grp <- cluster_network(seqs, k = 3) # Specify network method (cor requires numeric panel data) ## Not run: panel <- as.data.frame(matrix(rnorm(1500), nrow = 300, ncol = 5)) grp <- cluster_network(panel, k = 2, method = "cor") ## End(Not run) # MMM-based clustering grp <- cluster_network(seqs, k = 2, cluster_by = "mmm")
Aggregates node-level network weights to cluster-level summaries. Computes both between-cluster transitions (how clusters connect to each other) and within-cluster transitions (how nodes connect within each cluster).
cluster_summary( x, clusters = NULL, method = c("sum", "mean", "median", "max", "min", "density", "geomean"), directed = TRUE, compute_within = TRUE )cluster_summary( x, clusters = NULL, method = c("sum", "mean", "median", "max", "min", "density", "geomean"), directed = TRUE, compute_within = TRUE )
x |
Network input. Accepts multiple formats:
|
clusters |
Cluster/group assignments for nodes. Accepts multiple formats:
|
method |
Aggregation method for combining edge weights within/between clusters. Controls how multiple node-to-node edges are summarized:
|
directed |
Logical. If |
compute_within |
Logical. If |
This is the core function for Multi-Cluster Multi-Level (MCML) analysis.
Use as_tna() to convert results to tna objects for further
analysis with the tna package.
Typical MCML analysis workflow:
# 1. Create network net <- build_network(data, method = "relative") net$nodes$clusters <- group_assignments # 2. Compute cluster summary (arithmetic aggregation over edges) cs <- cluster_summary(net, method = "sum") # 3. Convert to tna models (normalization happens in as_tna) tna_models <- as_tna(cs) # 4. Analyze/visualize plot(tna_models$macro) tna::centralities(tna_models$macro)
The macro$weights matrix has clusters as both rows and columns:
Off-diagonal (row i, col j): Aggregated weight from cluster i to cluster j
Diagonal (row i, col i): Within-cluster total (aggregation of internal edges)
Rows are NOT normalized. Entries are elementwise aggregates produced by
method. If the caller wants probabilities, they should normalize
downstream (e.g. via as_tna()). Mixing an arithmetic aggregation
with row-normalization here (the old type = "tna" combined with
method = "min" / "mean" etc.) produces numbers that sum to 1
per row but are not a probability distribution over any process; that
silently-wrong combination is why type was removed from the matrix
path. The sequence and edgelist paths of build_mcml() keep
type, where the aggregation is always counts and the post-processing
chooses between well-defined network constructions.
| Input data | Recommended method | Reason |
| Edge counts | "sum" |
Preserves total flow between clusters |
| Transition matrix | "mean" |
Avoids cluster size bias |
| Correlation matrix | "mean" |
Average correlations |
| Dense weighted | "max" / "median" |
Robust summary |
A cluster_summary object (S3 class) containing:
List with two elements:
k x k matrix of cluster-to-cluster weights, where k is
the number of clusters. Row i, column j contains the elementwise
aggregation (per method) of all edges from nodes in cluster
i to nodes in cluster j. Diagonal contains within-cluster totals.
Pure arithmetic – no row normalization.
Numeric vector of length k. Initial state distribution across clusters, computed from column sums of the original matrix. Represents the proportion of incoming edges to each cluster.
Named list with one element per cluster. Each element contains:
n_i x n_i matrix for nodes within that cluster. Shows internal transitions between nodes in the same cluster.
Initial distribution within the cluster.
NULL if compute_within = FALSE.
Named list mapping cluster names to their member node labels.
Example: list(A = c("n1", "n2"), B = c("n3", "n4", "n5"))
List of metadata:
The method argument used ("sum", "mean", etc.)
Logical, whether network was treated as directed
Total number of nodes in original network
Number of clusters
Named vector of cluster sizes
as_tna() to convert results to tna objects,
plot() for two-layer visualization,
plot() for flat cluster visualization
# ----------------------------------------------------- # Basic usage with matrix and cluster vector # ----------------------------------------------------- mat <- matrix(runif(100), 10, 10) rownames(mat) <- colnames(mat) <- LETTERS[1:10] clusters <- c(1, 1, 1, 2, 2, 2, 3, 3, 3, 3) cs <- cluster_summary(mat, clusters) # Access results cs$macro$weights # 3x3 cluster transition matrix cs$macro$inits # Initial distribution cs$clusters$`1`$weights # Within-cluster 1 transitions cs$meta # Metadata # ----------------------------------------------------- # Named list clusters (more readable) # ----------------------------------------------------- clusters <- list( Alpha = c("A", "B", "C"), Beta = c("D", "E", "F"), Gamma = c("G", "H", "I", "J") ) cs <- cluster_summary(mat, clusters) cs$macro$weights # Rows/cols named Alpha, Beta, Gamma cs$clusters$Alpha # Within Alpha cluster # ----------------------------------------------------- # Auto-detect clusters from netobject # ----------------------------------------------------- seqs <- data.frame( V1 = sample(LETTERS[1:10], 30, TRUE), V2 = sample(LETTERS[1:10], 30, TRUE), V3 = sample(LETTERS[1:10], 30, TRUE) ) net <- build_network(seqs, method = "relative") cs2 <- cluster_summary(net, c(1, 1, 1, 2, 2, 2, 3, 3, 3, 3)) # ----------------------------------------------------- # Different aggregation methods # ----------------------------------------------------- cs_sum <- cluster_summary(mat, clusters, method = "sum") # Total flow cs_mean <- cluster_summary(mat, clusters, method = "mean") # Average cs_max <- cluster_summary(mat, clusters, method = "max") # Strongest # ----------------------------------------------------- # Skip within-cluster computation for speed # ----------------------------------------------------- cs_fast <- cluster_summary(mat, clusters, compute_within = FALSE) cs_fast$clusters # NULL # ----------------------------------------------------- # Convert to tna objects for tna package # (as_tna() applies its own row normalisation) # ----------------------------------------------------- cs <- cluster_summary(mat, clusters, method = "sum") tna_models <- as_tna(cs) # tna_models$macro # tna object # tna_models$clusters$Alpha # tna object# ----------------------------------------------------- # Basic usage with matrix and cluster vector # ----------------------------------------------------- mat <- matrix(runif(100), 10, 10) rownames(mat) <- colnames(mat) <- LETTERS[1:10] clusters <- c(1, 1, 1, 2, 2, 2, 3, 3, 3, 3) cs <- cluster_summary(mat, clusters) # Access results cs$macro$weights # 3x3 cluster transition matrix cs$macro$inits # Initial distribution cs$clusters$`1`$weights # Within-cluster 1 transitions cs$meta # Metadata # ----------------------------------------------------- # Named list clusters (more readable) # ----------------------------------------------------- clusters <- list( Alpha = c("A", "B", "C"), Beta = c("D", "E", "F"), Gamma = c("G", "H", "I", "J") ) cs <- cluster_summary(mat, clusters) cs$macro$weights # Rows/cols named Alpha, Beta, Gamma cs$clusters$Alpha # Within Alpha cluster # ----------------------------------------------------- # Auto-detect clusters from netobject # ----------------------------------------------------- seqs <- data.frame( V1 = sample(LETTERS[1:10], 30, TRUE), V2 = sample(LETTERS[1:10], 30, TRUE), V3 = sample(LETTERS[1:10], 30, TRUE) ) net <- build_network(seqs, method = "relative") cs2 <- cluster_summary(net, c(1, 1, 1, 2, 2, 2, 3, 3, 3, 3)) # ----------------------------------------------------- # Different aggregation methods # ----------------------------------------------------- cs_sum <- cluster_summary(mat, clusters, method = "sum") # Total flow cs_mean <- cluster_summary(mat, clusters, method = "mean") # Average cs_max <- cluster_summary(mat, clusters, method = "max") # Strongest # ----------------------------------------------------- # Skip within-cluster computation for speed # ----------------------------------------------------- cs_fast <- cluster_summary(mat, clusters, compute_within = FALSE) cs_fast$clusters # NULL # ----------------------------------------------------- # Convert to tna objects for tna package # (as_tna() applies its own row normalisation) # ----------------------------------------------------- cs <- cluster_summary(mat, clusters, method = "sum") tna_models <- as_tna(cs) # tna_models$macro # tna object # tna_models$clusters$Alpha # tna object
Generic accessor for the tidy coefficient table stored on a
build_mlvar() result. Returns a data.frame with one row per
(outcome, predictor) pair and columns outcome, predictor,
beta, se, t, p, ci_lower, ci_upper, significant.
coefs(x, ...) ## S3 method for class 'net_mlvar' coefs(x, ...) ## Default S3 method: coefs(x, ...)coefs(x, ...) ## S3 method for class 'net_mlvar' coefs(x, ...) ## Default S3 method: coefs(x, ...)
x |
A fitted model object — currently only |
... |
Unused. |
Only the within-person (temporal) coefficients are tabulated —
these are the lagged fixed effects that populate fit$temporal.
The between-subjects effects that go into fit$between are handled
via the D (I - Gamma) transformation and are not exposed as a
separate tidy table.
A tidy data.frame of coefficient estimates.
## Not run: d <- simulate_data("mlvar", seed = 1) fit <- build_mlvar(d, vars = attr(d, "vars"), id = "id", day = "day", beep = "beep") print(fit) summary(fit) ## End(Not run)## Not run: d <- simulate_data("mlvar", seed = 1) fit <- build_mlvar(d, vars = attr(d, "vars"), id = "id", day = "day", beep = "beep") print(fit) summary(fit) ## End(Not run)
Compare MMM fits across different k
compare_mmm(data, k = 2:5, return_fits = FALSE, ...)compare_mmm(data, k = 2:5, return_fits = FALSE, ...)
data |
Data frame, netobject, or tna model. |
k |
Integer vector of component counts. Values must be whole finite numbers >= 2. Default: 2:5. |
return_fits |
Logical. When |
... |
Arguments passed to |
A mmm_compare data frame with BIC, AIC, ICL, AvePP,
entropy per k. When return_fits = TRUE, the fitted models are
attached as attr(result, "fits").
seqs <- data.frame(V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE)) comp <- compare_mmm(seqs, k = 2:3, n_starts = 1, max_iter = 10, seed = 1) comp seqs <- data.frame( V1 = sample(LETTERS[1:3], 30, TRUE), V2 = sample(LETTERS[1:3], 30, TRUE), V3 = sample(LETTERS[1:3], 30, TRUE), V4 = sample(LETTERS[1:3], 30, TRUE) ) comp <- compare_mmm(seqs, k = 2:3, seed = 42) print(comp) # Retain fits to avoid a re-fit after picking the BIC-min model. comp_with_fits <- compare_mmm(seqs, k = 2:3, seed = 42, return_fits = TRUE) best_k <- comp_with_fits$k[which.min(comp_with_fits$BIC)] best_fit <- attr(comp_with_fits, "fits")[[as.character(best_k)]]seqs <- data.frame(V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE)) comp <- compare_mmm(seqs, k = 2:3, n_starts = 1, max_iter = 10, seed = 1) comp seqs <- data.frame( V1 = sample(LETTERS[1:3], 30, TRUE), V2 = sample(LETTERS[1:3], 30, TRUE), V3 = sample(LETTERS[1:3], 30, TRUE), V4 = sample(LETTERS[1:3], 30, TRUE) ) comp <- compare_mmm(seqs, k = 2:3, seed = 42) print(comp) # Retain fits to avoid a re-fit after picking the BIC-min model. comp_with_fits <- compare_mmm(seqs, k = 2:3, seed = 42, return_fits = TRUE) best_k <- comp_with_fits$k[which.min(comp_with_fits$BIC)] best_fit <- attr(comp_with_fits, "fits")[[as.character(best_k)]]
Computes a battery of descriptive comparison metrics between two networks or two weight matrices: weight deviations (mean / median / RMS / max absolute difference, relative mean absolute difference, coefficient-of- variation ratio), four correlation measures (Pearson, Spearman, Kendall, distance correlation), five dissimilarity measures (Euclidean, Manhattan, Canberra, Bray-Curtis, Frobenius), five similarity measures (Cosine, Jaccard, Dice, Overlap, RV), pattern agreements, and side-by-side network metrics. Optionally adds centrality differences and centrality correlations.
compare_model(x, ...) ## S3 method for class 'netobject' compare_model( x, y, scaling = "none", measures = character(0), network = TRUE, ... ) ## S3 method for class 'cograph_network' compare_model( x, y, scaling = "none", measures = character(0), network = TRUE, ... ) ## S3 method for class 'matrix' compare_model( x, y, scaling = "none", measures = character(0), network = TRUE, ... )compare_model(x, ...) ## S3 method for class 'netobject' compare_model( x, y, scaling = "none", measures = character(0), network = TRUE, ... ) ## S3 method for class 'cograph_network' compare_model( x, y, scaling = "none", measures = character(0), network = TRUE, ... ) ## S3 method for class 'matrix' compare_model( x, y, scaling = "none", measures = character(0), network = TRUE, ... )
x |
A |
... |
Ignored. |
y |
A |
scaling |
Scaling applied to both weight matrices before comparison. One of:
Scalings that produce negative weights ( |
measures |
Character vector of centrality measures to compare. Empty
by default (no centrality block). Valid names are |
network |
Logical. Include side-by-side network metrics from
|
Mirrors tna::compare() numerically. Inputs are converted to weight
matrices and scaled before comparison; the choice of scaling determines
how weights from different estimators are placed on a common footing.
A net_comparison object: a named list with matrices,
difference_matrix, edge_metrics, summary_metrics, optionally
network_metrics, centrality_differences, centrality_correlations.
Selects two members of a netobject_group (by index or name) and
dispatches to compare_model.netobject().
## S3 method for class 'netobject_group' compare_model( x, i = 1L, j = 2L, scaling = "none", measures = character(0), network = TRUE, ... )## S3 method for class 'netobject_group' compare_model( x, i = 1L, j = 2L, scaling = "none", measures = character(0), network = TRUE, ... )
x |
A |
i |
Integer or character. Index or name of the first network.
Default |
j |
Integer or character. Index or name of the second network.
Default |
scaling |
See |
measures |
See |
network |
See |
... |
Passed to |
A net_comparison object.
Convert wide or long sequence data into frequency counts, one-hot encoding, edge lists, or follows format.
convert_sequence_format( data, seq_cols = NULL, id_col = NULL, action = NULL, time = NULL, format = c("frequency", "onehot", "edgelist", "follows") )convert_sequence_format( data, seq_cols = NULL, id_col = NULL, action = NULL, time = NULL, format = c("frequency", "onehot", "edgelist", "follows") )
data |
Data frame containing sequence data. |
seq_cols |
Character vector. Names of columns containing sequential
states (for wide format input). If NULL, all columns except |
id_col |
Character vector. Name(s) of the ID column(s). For long
format, required. For wide format, optional: if NULL, the first column
is used as the id only when it is a genuine identifier (its values are
disjoint from the states in the remaining columns); for canonical wide
sequence data with no id column (e.g. |
action |
Character or NULL. Name of the column containing actions/states (for long format input). If provided, data is treated as long format. Default: NULL. |
time |
Character or NULL. Name of the time column for ordering actions within sequences (for long format). Default: NULL. |
format |
Character. Output format:
|
A data frame in the requested format:
ID columns + one integer column per state with counts.
ID columns + one binary column per state (0/1).
ID columns + from and to columns.
ID columns + act and follows columns.
frequencies for building transition frequency matrices.
# Wide format input seqs <- data.frame(V1 = c("A","B","A"), V2 = c("B","A","C"), V3 = c("A","C","B")) convert_sequence_format(seqs, format = "frequency") convert_sequence_format(seqs, format = "edgelist")# Wide format input seqs <- data.frame(V1 = c("A","B","A"), V2 = c("B","A","C"), V3 = c("A","C","B")) convert_sequence_format(seqs, format = "frequency") convert_sequence_format(seqs, format = "edgelist")
Constructs an undirected co-occurrence network from various input formats. Entities that appear together in the same transaction, document, or record are connected, with edge weights reflecting raw counts or a similarity measure. Argument names follow the citenets convention.
cooccurrence( data, field = NULL, by = NULL, sep = NULL, similarity = c("none", "jaccard", "cosine", "inclusion", "association", "dice", "equivalence", "relative"), threshold = 0, min_occur = 1L, diagonal = TRUE, top_n = NULL, ... )cooccurrence( data, field = NULL, by = NULL, sep = NULL, similarity = c("none", "jaccard", "cosine", "inclusion", "association", "dice", "equivalence", "relative"), threshold = 0, min_occur = 1L, diagonal = TRUE, top_n = NULL, ... )
data |
Input data. Accepts:
|
field |
Character. The entity column — determines what the nodes are.
For delimited format, a single column whose values are split by |
by |
Character or |
sep |
Character or |
similarity |
Character. Similarity measure applied to the raw co-occurrence counts. One of:
|
threshold |
Numeric. Minimum edge weight to retain. Edges below this value are set to zero. Applied after similarity normalization. Default 0. |
min_occur |
Integer. Minimum entity frequency (number of transactions an entity must appear in). Entities below this threshold are dropped before computing co-occurrence. Default 1 (keep all). |
diagonal |
Logical. If |
top_n |
Integer or |
... |
Currently unused. |
Six input formats are supported, auto-detected from the combination of
field, by, and sep:
Delimited: field + sep (single column).
Each cell is split by sep, trimmed, and de-duplicated per row.
Multi-column delimited: field (vector) + sep.
Values from multiple columns are split, pooled, and de-duplicated per row.
Long bipartite: field + by.
Groups by by; unique values of field within each group
form a transaction.
Binary matrix: No field/by/sep, all
values 0/1. Columns are items, rows are transactions.
Wide sequence: No field/by/sep,
non-binary. Unique values across each row form a transaction.
List: A plain list of character vectors.
The pipeline converts all formats into a list of character vectors
(transactions), optionally filters by min_occur, builds a binary
transaction matrix, computes crossprod(B) for the raw co-occurrence
counts, normalizes via the chosen similarity, then applies
threshold and top_n filtering.
A netobject (undirected) with method = "co_occurrence_fn".
The $weights matrix contains similarity (or raw) co-occurrence values.
The $params list stores the similarity method, threshold, and
the number of transactions.
van Eck, N. J., & Waltman, L. (2009). How to normalize co-occurrence data? An analysis of some well-known similarity measures. Journal of the American Society for Information Science and Technology, 60(8), 1635–1651.
build_cna for sequence-positional co-occurrence via
build_network().
# Delimited field (e.g., keyword co-occurrence) df <- data.frame( id = 1:4, keywords = c("network; graph", "graph; matrix; network", "matrix; algebra", "network; algebra; graph") ) net <- cooccurrence(df, field = "keywords", sep = ";") # Long/bipartite long_df <- data.frame( paper = c(1, 1, 1, 2, 2, 3, 3), keyword = c("network", "graph", "matrix", "graph", "algebra", "network", "algebra") ) net <- cooccurrence(long_df, field = "keyword", by = "paper") # List of transactions transactions <- list(c("A", "B"), c("B", "C"), c("A", "B", "C")) net <- cooccurrence(transactions, similarity = "jaccard") # Binary matrix bin <- matrix(c(1,0,1, 1,1,0, 0,1,1), nrow = 3, byrow = TRUE, dimnames = list(NULL, c("X", "Y", "Z"))) net <- cooccurrence(bin)# Delimited field (e.g., keyword co-occurrence) df <- data.frame( id = 1:4, keywords = c("network; graph", "graph; matrix; network", "matrix; algebra", "network; algebra; graph") ) net <- cooccurrence(df, field = "keywords", sep = ";") # Long/bipartite long_df <- data.frame( paper = c(1, 1, 1, 2, 2, 3, 3), keyword = c("network", "graph", "matrix", "graph", "algebra", "network", "algebra") ) net <- cooccurrence(long_df, field = "keyword", by = "paper") # List of transactions transactions <- list(c("A", "B"), c("B", "C"), c("A", "B", "C")) net <- cooccurrence(transactions, similarity = "jaccard") # Binary matrix bin <- matrix(c(1,0,1, 1,1,0, 0,1,1), nrow = 3, byrow = TRUE, dimnames = list(NULL, c("X", "Y", "Z"))) net <- cooccurrence(bin)
Draws how state proportions (or counts) evolve across time points. For
each time column, tabulates how many sequences are in each state and
renders the result as a stacked area (default) or stacked bar chart.
Accepts the same inputs as sequence_plot.
distribution_plot( x, group = NULL, scale = c("proportion", "count"), geom = c("area", "bar"), na = TRUE, state_colors = NULL, na_color = "grey90", frame = FALSE, width = NULL, height = NULL, main = NULL, show_n = TRUE, time_label = "Time", xlab = NULL, y_label = NULL, ylab = NULL, tick = NULL, ncol = NULL, nrow = NULL, combined = TRUE, legend = c("right", "bottom", "none"), legend_size = NULL, legend_title = NULL, legend_ncol = NULL, legend_border = NA, legend_bty = "n" )distribution_plot( x, group = NULL, scale = c("proportion", "count"), geom = c("area", "bar"), na = TRUE, state_colors = NULL, na_color = "grey90", frame = FALSE, width = NULL, height = NULL, main = NULL, show_n = TRUE, time_label = "Time", xlab = NULL, y_label = NULL, ylab = NULL, tick = NULL, ncol = NULL, nrow = NULL, combined = TRUE, legend = c("right", "bottom", "none"), legend_size = NULL, legend_title = NULL, legend_ncol = NULL, legend_border = NA, legend_bty = "n" )
x |
Wide-format sequence data. Accepts the same inputs as
|
group |
Optional grouping vector (length |
scale |
|
geom |
|
na |
If |
state_colors |
Vector of colours, one per state. Defaults to Okabe-Ito. |
na_color |
Colour for the |
frame |
If |
width, height
|
Optional device dimensions. See
|
main |
Plot title. |
show_n |
Append |
time_label |
X-axis label. |
xlab |
Alias for |
y_label |
Y-axis label. Defaults to |
ylab |
Alias for |
tick |
Show every Nth x-axis label. |
ncol, nrow
|
Facet grid dimensions. |
combined |
When |
legend |
Legend position: |
legend_size |
Legend text size. |
legend_title |
Optional legend title. |
legend_ncol |
Number of legend columns. |
legend_border |
Swatch border colour. |
legend_bty |
|
Invisibly, a list with counts, proportions,
levels, palette, and groups.
distribution_plot(as.data.frame(trajectories))distribution_plot(as.data.frame(trajectories))
This function is deprecated. Use build_network instead.
estimate_network( data, method = "relative", params = list(), scaling = NULL, threshold = 0, level = NULL, ... )estimate_network( data, method = "relative", params = list(), scaling = NULL, threshold = 0, level = NULL, ... )
data |
Data frame (sequences or per-observation frequencies) or a square symmetric matrix (correlation or covariance). |
method |
Character. Defaults to |
params |
Named list. Method-specific parameters passed to the estimator
function (e.g. |
scaling |
Character vector or NULL. Post-estimation scaling to apply
(in order). Options: |
threshold |
Numeric. Absolute values below this are set to zero in the result matrix. Default: 0 (no thresholding). |
level |
Character or NULL. Multilevel decomposition for association
methods. One of |
... |
Additional arguments passed to |
A netobject (see build_network).
data <- data.frame(A = c("x","y","z","x"), B = c("y","x","z","y")) net <- estimate_network(data, method = "relative")data <- data.frame(A = c("x","y","z","x"), B = c("y","x","z","y")) net <- estimate_network(data, method = "relative")
Computes where is the
number of k-simplices. By the Euler-Poincare theorem,
.
euler_characteristic(sc)euler_characteristic(sc)
sc |
A |
Integer.
mat <- matrix(c(0,.6,.5,.6,0,.4,.5,.4,0), 3, 3) colnames(mat) <- rownames(mat) <- c("A","B","C") sc <- build_simplicial(mat, threshold = 0.3) euler_characteristic(sc)mat <- matrix(c(0,.6,.5,.6,0,.4,.5,.4,0), 3, 3) colnames(mat) <- rownames(mat) <- c("A","B","C") sc <- build_simplicial(mat, threshold = 0.3) euler_characteristic(sc)
Computes AUC-ROC, precisionk, and average precision for link
predictions against a set of known true edges.
evaluate_links(pred, true_edges, k = c(5L, 10L, 20L))evaluate_links(pred, true_edges, k = c(5L, 10L, 20L))
pred |
A |
true_edges |
A data frame with columns |
k |
Integer vector. Values of k for precision |
A data frame with columns: method, auc, average_precision, and one precision_at_k column per k value.
set.seed(42) seqs <- data.frame( V1 = sample(LETTERS[1:5], 50, TRUE), V2 = sample(LETTERS[1:5], 50, TRUE), V3 = sample(LETTERS[1:5], 50, TRUE) ) net <- build_network(seqs, method = "relative") pred <- predict_links(net, exclude_existing = FALSE) # Evaluate: predict the network's own edges true <- data.frame(from = pred$predictions$from[1:5], to = pred$predictions$to[1:5]) evaluate_links(pred, true)set.seed(42) seqs <- data.frame( V1 = sample(LETTERS[1:5], 50, TRUE), V2 = sample(LETTERS[1:5], 50, TRUE), V3 = sample(LETTERS[1:5], 50, TRUE) ) net <- build_network(seqs, method = "relative") pred <- predict_links(net, exclude_existing = FALSE) # Evaluate: predict the network's own edges true <- data.frame(from = pred$predictions$from[1:5], to = pred$predictions$to[1:5]) evaluate_links(pred, true)
Extract an edge list from a TNA model, representing the network as a data frame of from-to-weight tuples.
extract_edges(model, threshold = 0, include_self = FALSE, sort_by = "weight")extract_edges(model, threshold = 0, include_self = FALSE, sort_by = "weight")
model |
A TNA model object or a matrix of weights. |
threshold |
Numeric. Minimum weight to include an edge. Default: 0. |
include_self |
Logical. Whether to include self-loops. Default: FALSE. |
sort_by |
Character. Column to sort by: "weight" (descending), "from", "to", or NULL for no sorting. Default: "weight". |
This function converts the transition matrix into an edge list format, which is useful for visualization, analysis with igraph, or export to other network tools.
A data frame with columns:
Source state name.
Target state name.
Edge weight (transition probability).
extract_transition_matrix for the full matrix,
build_network for network estimation.
seqs <- data.frame(V1 = c("A","B","A"), V2 = c("B","A","C"), V3 = c("A","C","B")) net <- build_network(seqs, method = "relative") edges <- extract_edges(net, threshold = 0.05) head(edges)seqs <- data.frame(V1 = c("A","B","A"), V2 = c("B","A","C"), V3 = c("A","C","B")) net <- build_network(seqs, method = "relative") edges <- extract_edges(net, threshold = 0.05) head(edges)
Extract the initial state probability vector from a TNA model object.
extract_initial_probs(model)extract_initial_probs(model)
model |
A TNA model object or a list containing an 'initial' element. |
Initial probabilities represent the probability of starting a sequence in each state. If the model doesn't have explicit initial probabilities, this function attempts to estimate them from the data or use uniform probabilities.
A named numeric vector of initial state probabilities.
extract_transition_matrix for extracting the transition matrix,
extract_edges for extracting an edge list.
seqs <- data.frame(V1 = c("A","B","A"), V2 = c("B","A","C"), V3 = c("A","C","B")) net <- build_network(seqs, method = "relative") init_probs <- extract_initial_probs(net) print(init_probs)seqs <- data.frame(V1 = c("A","B","A"), V2 = c("B","A","C"), V3 = c("A","C","B")) net <- build_network(seqs, method = "relative") init_probs <- extract_initial_probs(net) print(init_probs)
Extract the transition probability matrix from a TNA model object.
extract_transition_matrix(model, type = c("raw", "scaled"))extract_transition_matrix(model, type = c("raw", "scaled"))
model |
A TNA model object or a list containing a 'weights' element. |
type |
Character. Type of matrix to return:
Default: "raw". |
TNA models store transition weights in different locations depending on the model type. This function handles the extraction automatically.
For "scaled" type, each row is divided by its sum to create valid transition probabilities. This is useful when the original weights don't sum to 1.
A square numeric matrix with row and column names as state names.
extract_initial_probs for extracting initial probabilities,
extract_edges for extracting an edge list.
seqs <- data.frame(V1 = c("A","B","A"), V2 = c("B","A","C"), V3 = c("A","C","B")) net <- build_network(seqs, method = "relative") trans_mat <- extract_transition_matrix(net) print(trans_mat)seqs <- data.frame(V1 = c("A","B","A"), V2 = c("B","A","C"), V3 = c("A","C","B")) net <- build_network(seqs, method = "relative") trans_mat <- extract_transition_matrix(net) print(trans_mat)
Retrieve a registered network estimator by name.
get_estimator(name)get_estimator(name)
name |
Character. Name of the estimator to retrieve. |
A list with elements fn, description, directed.
register_estimator, list_estimators
est <- get_estimator("relative")est <- get_estimator("relative")
Students' regulation strategies during collaborative learning, in long format. Contains 27,533 timestamped action records from multiple students working in groups across two courses.
group_regulation_longgroup_regulation_long
A data frame with 27,533 rows and 6 columns:
Integer. Student identifier.
Character. Achievement level: "High" or "Low".
Numeric. Collaboration group identifier.
Character. Course identifier ("A", "B", or "C").
POSIXct. Timestamp of the action.
Character. Regulation action (e.g., cohesion, consensus, discuss, synthesis).
Synthetically generated from the group_regulation dataset
in the tna package.
learning_activities, srl_strategies
net <- build_network(group_regulation_long, method = "relative", actor = "Actor", action = "Action", time = "Time") netnet <- build_network(group_regulation_long, method = "relative", actor = "Actor", action = "Action", time = "Time") net
Computes one or more eigenvector-style centralities on a net_hypergraph: clique-motif (CEC), Z-eigenvector (ZEC), and H-eigenvector (HEC). Each variant captures influence differently — CEC flattens group structure via clique expansion, while ZEC and HEC propagate through the higher-order groups directly.
hypergraph_centrality( hg, type = c("clique", "Z", "H"), max_iter = 1000L, tol = 1e-08, normalize = TRUE )hypergraph_centrality( hg, type = c("clique", "Z", "H"), max_iter = 1000L, tol = 1e-08, normalize = TRUE )
hg |
A |
type |
Character vector, any subset of |
max_iter |
Maximum number of power-iteration steps. Default
|
tol |
Convergence tolerance on the L1 change between successive
iterates. Default |
normalize |
Logical. If |
Clique-motif eigenvector centrality (CEC): forms the
clique-expanded pairwise graph where
and returns the leading
eigenvector of . Equivalent to running
igraph::eigen_centrality() on clique_expansion() output.
Z-eigenvector centrality (ZEC): solves the linear eigen-equation on the hyperedge tensor,
via power iteration. Works for hypergraphs with mixed edge sizes.
H-eigenvector centrality (HEC): solves the power-k-1 eigen-equation,
For uniform hypergraphs (all hyperedges of size ), this is
equivalent to normalizing the ZEC update by the geometric-mean
exponent . For mixed sizes, the effective exponent is
taken from the largest hyperedge; expect slightly different rankings
from ZEC in the mixed case.
A named list; one component per requested type. Each
component is a named numeric vector of length hg$n_nodes.
The "clique" (CEC) variant is validated against
igraph::eigen_centrality (cosine ~ 1). The "Z" and "H" variants are
(experimental) — validated only against a clean-room list-based
tensor power iteration (same operator, different loop structure); no
R package exposes tensor eigenvectors as a primitive for independent
comparison.
Benson, A. R. (2019). Three hypergraph eigenvector centralities. SIAM Journal on Mathematics of Data Science 1(2), 293-312. arXiv:1807.09644.
build_hypergraph(), clique_expansion(),
hypergraph_measures().
df <- data.frame( player = c("A", "B", "C", "A", "B", "D", "C", "D", "E"), session = c("S1", "S1", "S1", "S2", "S2", "S3", "S3", "S3", "S3") ) hg <- bipartite_groups(df, "player", "session") cent <- hypergraph_centrality(hg) # Compare rankings across the three variants do.call(cbind, cent)df <- data.frame( player = c("A", "B", "C", "A", "B", "D", "C", "D", "E"), session = c("S1", "S1", "S1", "S2", "S2", "S3", "S3", "S3", "S3") ) hg <- bipartite_groups(df, "player", "session") cent <- hypergraph_centrality(hg) # Compare rankings across the three variants do.call(cbind, cent)
Computes a comprehensive structural-statistics suite for a net_hypergraph: node-level, hyperedge-level, and global measures. All measures are derived in a few BLAS calls on the incidence matrix.
hypergraph_measures(hg) ## S3 method for class 'hypergraph_measures' print(x, ...)hypergraph_measures(hg) ## S3 method for class 'hypergraph_measures' print(x, ...)
hg |
A |
x |
A |
... |
Additional arguments (ignored). |
All measures are computed via standard matrix operations on the binary
incidence where iff node
is in hyperedge :
hyperdegree = rowSums(B),
edge_sizes = colSums(B)
co_degree = tcrossprod(B) (with zero diagonal)
edge_pairwise_overlap = crossprod(B) (with zero diagonal)
overlap_coefficient[i, j] = overlap[i, j] / min(edge_sizes[i], edge_sizes[j])
jaccard[i, j] = overlap[i, j] / (edge_sizes[i] + edge_sizes[j] - overlap[i, j])
Empty hypergraph (n_hyperedges == 0) returns trivial zeros and
empty matrices.
An object of class hypergraph_measures (a named list) with
components:
n_nodes)hyperdegreeNumber of hyperedges containing each node.
node_strengthTotal participation: for node ,
. A node in many large hyperedges has
high strength.
max_edge_sizeSize of the largest hyperedge containing each node.
co_degreen_nodes x n_nodes matrix:
co_degree[i, j] = |{e : i, j in e}| (number of hyperedges
co-containing nodes and ). Diagonal is zero.
n_hyperedges or m x m)edge_sizesHyperedge sizes .
edge_pairwise_overlapm x m matrix:
|e_i intersect e_j|. Diagonal is zero.
overlap_coefficientm x m:
|e_i and e_j| / min(|e_i|, |e_j|). Measures how much the
smaller hyperedge is contained in the larger.
jaccardm x m: symmetric overlap index
|e_i and e_j| / |e_i union e_j|.
densityFor k-uniform hypergraphs: m / choose(n, k).
For mixed sizes: sum(|e|) / (n * m) (mean fraction of nodes
per hyperedge).
avg_edge_sizeMean of edge_sizes.
size_distributionTabulation of hyperedge sizes (passed
through from hg).
intersection_profileDistribution of pairwise hyperedge intersection sizes — useful for spotting whether hyperedges overlap mostly trivially or share substantial cores (Do et al. 2020).
pairwise_participationFraction of node pairs co-appearing in at least one hyperedge.
n_nodes, n_hyperedges
Convenience scalars.
The input x invisibly.
Lee, G., Choe, M., & Shin, K. (2024). A survey on hypergraph representation, learning and mining. Data Mining & Knowledge Discovery 37, 1-39.
Do, M. T., Yoon, S., Hooi, B., & Shin, K. (2020). Structural patterns and generative models of real-world hypergraphs. arXiv:2006.07060.
build_hypergraph(), bipartite_groups(),
clique_expansion().
df <- data.frame( player = c("A", "B", "C", "A", "B", "D", "C", "D"), session = c("S1", "S1", "S1", "S2", "S2", "S3", "S3", "S3") ) hg <- bipartite_groups(df, "player", "session") m <- hypergraph_measures(hg) print(m) m$hyperdegree # how many sessions each player joined m$co_degree # pairwise co-membership counts m$jaccard # symmetric overlap between sessionsdf <- data.frame( player = c("A", "B", "C", "A", "B", "D", "C", "D"), session = c("S1", "S1", "S1", "S2", "S2", "S3", "S3", "S3") ) hg <- bipartite_groups(df, "player", "session") m <- hypergraph_measures(hg) print(m) m$hyperdegree # how many sessions each player joined m$co_degree # pairwise co-membership counts m$jaccard # symmetric overlap between sessions
Simulated binary time-series data for 200 students across 30 time points. At each time point, one or more learning activities may be active (1) or inactive (0). Activities: Reading, Video, Forum, Quiz, Coding, Review. Includes temporal persistence (activities tend to continue across adjacent time points).
learning_activitieslearning_activities
A data frame with 6,000 rows and 7 columns:
Integer. Student identifier (1–200).
Integer (0/1). Reading activity indicator.
Integer (0/1). Video watching indicator.
Integer (0/1). Discussion forum indicator.
Integer (0/1). Quiz/assessment indicator.
Integer (0/1). Coding practice indicator.
Integer (0/1). Review/revision indicator.
head(learning_activities)head(learning_activities)
Return a data frame summarising all registered network estimators.
list_estimators()list_estimators()
A data frame with columns name, description,
directed.
register_estimator, get_estimator
list_estimators()list_estimators()
Convert sequence data from long format (one row per action) to wide format (one row per sequence, columns as time points).
long_to_wide( data, id_col = "Actor", time_col = "Time", action_col = "Action", time_prefix = "V", fill_na = TRUE )long_to_wide( data, id_col = "Actor", time_col = "Time", action_col = "Action", time_prefix = "V", fill_na = TRUE )
data |
Data frame in long format. |
id_col |
Character. Name of the column identifying sequences. Default: "Actor". |
time_col |
Character. Name of the column identifying time points. Default: "Time". |
action_col |
Character. Name of the column containing actions/states. Default: "Action". |
time_prefix |
Character. Prefix for time point columns in output. Default: "V". |
fill_na |
Logical. Whether to fill missing time points with NA. Default: TRUE. |
This function converts long format data (like that from simulate_long_data())
to the wide format expected by tna::tna() and related functions.
If time_col contains non-integer values (e.g., timestamps), the function
will use the ordering within each sequence to create time indices.
A data frame in wide format where each row is a sequence and columns V1, V2, ... contain the actions at each time point.
wide_to_long for the reverse conversion,
prepare_for_tna for preparing data for TNA analysis.
long_data <- data.frame( Actor = rep(1:3, each = 4), Time = rep(1:4, 3), Action = sample(c("A", "B", "C"), 12, replace = TRUE) ) wide_data <- long_to_wide(long_data, id_col = "Actor") head(wide_data)long_data <- data.frame( Actor = rep(1:3, each = 4), Time = rep(1:4, 3), Action = sample(c("A", "B", "C"), 12, replace = TRUE) ) wide_data <- long_to_wide(long_data, id_col = "Actor") head(wide_data)
Coded interaction sequences from 429 human-AI pair programming sessions across 34 projects, in long format.
human_long ai_longhuman_long ai_long
Data frames in long format with 9 columns:
Integer. Turn index.
Character. Project identifier (Project_1 .. Project_34).
Character. Unique session hash.
Integer. Unix timestamp for ordering.
Character. Date of the session (YYYY-MM-DD).
Character. Interaction code (17 action labels).
Character. High-level cluster: Action, Communication, Directive, Evaluative, Metacognitive, or Repair.
Integer. Order of the code within the session.
Integer. Absolute turn order within the session.
human_long |
Human turns only, 10,796 rows |
ai_long |
AI turns only, 8,551 rows |
An object of class data.frame with 10796 rows and 9 columns.
An object of class data.frame with 8551 rows and 9 columns.
Saqr, M. (2026). Human-AI vibe coding interaction study. https://saqr.me/blog/2026/human-ai-interaction-cograph/
net <- build_network(human_long, method = "tna", action = "code", actor = "session_id", time = "timestamp") netnet <- build_network(human_long, method = "tna", action = "code", actor = "session_id", time = "timestamp") net
Quantifies, per edge, how much row-normalization moves a transition
network between its two natural summaries: raw transition counts
(frequency / FTNA, build_network(method = "frequency")) and
row-conditional probabilities (TNA, build_network(method = "relative")).
The two matrices rank edges differently — an edge that is large in counts
can be modest in probability, and a rare-source edge can dominate its row
in probability. The per-edge discrepancy on a common scale is the
magnitude difference.
magnitude_difference( data, actor = "Actor", action = "Action", time = NULL, metric = c("abs_diff", "chord_dist", "atanh_diff", "geom_norm_diff", "cv_inflation"), scale = c("tna_range", "rank_minmax", "minmax", "none"), format = c("auto", "long", "wide") ) ## S3 method for class 'magnitude_difference' print(x, ...) ## S3 method for class 'magnitude_difference' plot(x, type = c("stacked", "circular"), min_show = 0.01, title = NULL, ...)magnitude_difference( data, actor = "Actor", action = "Action", time = NULL, metric = c("abs_diff", "chord_dist", "atanh_diff", "geom_norm_diff", "cv_inflation"), scale = c("tna_range", "rank_minmax", "minmax", "none"), format = c("auto", "long", "wide") ) ## S3 method for class 'magnitude_difference' print(x, ...) ## S3 method for class 'magnitude_difference' plot(x, type = c("stacked", "circular"), min_show = 0.01, title = NULL, ...)
data |
Long- or wide-format event log ( |
actor, action, time
|
Column names in |
metric |
Discrepancy metric. One of |
scale |
How the two weight matrices are placed on a common scale
before differencing. |
format |
Input format passed through to |
x |
A |
... |
Passed to plotting helpers (ignored by |
type |
Plot style, |
min_show |
For |
title |
Plot title. |
An object of class "magnitude_difference": a list with
$edges (per-edge data.frame with columns from, to, ftna,
tna, signed = tna - ftna, and value = the chosen metric),
$metric, $scale, $weights_ftna, $weights_tna, and $states.
print invisibly returns x.
plot returns a ggplot object.
print(magnitude_difference): Print a compact summary of the per-edge
magnitude-difference distribution.
plot(magnitude_difference): Plot the per-edge magnitude difference as
a polar portrait. type = "stacked" (default) draws one sector per
from-state with stacked wedges (grey base = shared value, colored tip =
magnitude difference); type = "circular" draws a chord-style diagram
with signed differences on a diverging blue-orange scale.
build_network(), compare_model()
data(group_regulation_long, package = "Nestimate") fit <- magnitude_difference(group_regulation_long, actor = "Actor", action = "Action", time = "Time") print(fit) # Edges most promoted by row-normalization (rare-source transitions): head(fit$edges[order(-fit$edges$signed), c("from", "to", "ftna", "tna")]) plot(fit) # stacked polar portrait plot(fit, type = "circular") # chord-style diagramdata(group_regulation_long, package = "Nestimate") fit <- magnitude_difference(group_regulation_long, actor = "Actor", action = "Action", time = "Time") print(fit) # Edges most promoted by row-normalization (rare-source transitions): head(fit$edges[order(-fit$edges$signed), c("from", "to", "ftna", "tna")]) plot(fit) # stacked polar portrait plot(fit, type = "circular") # chord-style diagram
Mirror of mark_terminal_state() for left-censored sequence data.
Replaces every cell before each row's first observed state with
the label given by state. The resulting chain has a structurally
recurrent "Start" state that everyone enters from — useful for
cohort-entry analyses where students join at different time points
and you want a uniform pre-observation marker.
mark_first_state(data, state = "Start", cols = NULL)mark_first_state(data, state = "Start", cols = NULL)
data |
A wide-format matrix or data.frame (rows = actors,
cols = time steps) of state labels with |
state |
Character. Label to insert in leading-NA cells.
Default |
cols |
Optional state-column names; otherwise all columns. |
Unlike mark_terminal_state(), the marked state is not
absorbing in the resulting transition matrix — every transition
from "Start" goes to one of the original states (the actor's
first observed state), and the "Start" row is row-stochastic
exactly as the data dictates.
A data.frame of the same shape as data with leading
NAs filled by state.
mark_terminal_state(), actor_endpoints()
M <- mark_first_state(trajectories, state = "Start") # In a chain built from M, "Start" is a transient entry point.M <- mark_first_state(trajectories, state = "Start") # In a chain built from M, "Start" is a transient entry point.
Replaces every cell after each row's last observed state with the
label given by state, leaving non-terminal NAs untouched. The
result, passed to build_network(), yields a Markov chain in
which the marked state is absorbing by construction
(P[state, state] = 1).
mark_terminal_state(data, state = "End", cols = NULL)mark_terminal_state(data, state = "End", cols = NULL)
data |
A wide-format matrix or data.frame (rows = actors,
cols = time steps) of state labels with |
state |
Character. Label to insert in terminal-NA cells.
Default |
cols |
Optional state-column names; otherwise all columns. |
This is the small piece of pre-processing required to turn
right-censored sequence data into an absorbing-chain model. The
chain on the resulting matrix has one extra state (state)
which is structurally absorbing because every cell after the
actor's last observed step has been set to state — the chain
stays there forever once entered.
Use chain_structure() on the result to compute mean absorption
time, absorption probabilities, and per-state classification.
Note that markov_stability() is not the right summary for
absorbing chains; its stationary distribution will collapse to
the absorbing state.
A data.frame of the same shape as data with terminal
NAs filled by state.
actor_endpoints(), chain_structure(), build_network()
M <- mark_terminal_state(trajectories, state = "Dropout") net <- build_network(M, method = "relative") chain_structure(net)M <- mark_terminal_state(trajectories, state = "Dropout") net <- build_network(M, method = "relative") chain_structure(net)
Principled test of whether a categorical sequence is best described
as a -th order Markov chain. At each order
max_order, the function computes the
classical likelihood-ratio statistic () for the conditional
independence , where is the
-gram context, is the extra (k-th-back) state
added at order , and is the next state. Under
(order- is correct), is independent of
given .
The null distribution is obtained by an exact within-
permutation test: for each context the successor labels are
exchangeable under , so shuffling within each
-group yields an exact reference distribution for .
No plug-in MLE bias and no refitting per replicate. An asymptotic
p-value is reported alongside for reference.
The optimal order is the smallest that is not
significantly better than at level alpha: we
keep raising the order while the test rejects, and stop at the first
non-rejection.
markov_order_test( data, max_order = 3L, n_perm = 500L, alpha = 0.05, parallel = FALSE, n_cores = 2L, seed = NULL )markov_order_test( data, max_order = 3L, n_perm = 500L, alpha = 0.05, parallel = FALSE, n_cores = 2L, seed = NULL )
data |
A data.frame (wide format, one sequence per row) or list of character vectors (one per trajectory). NAs are treated as end of sequence. |
max_order |
Integer. Highest Markov order to test. Default 3. |
n_perm |
Integer. Number of within- |
alpha |
Numeric. Significance level for order selection. Default 0.05. |
parallel |
Logical. Use |
n_cores |
Integer. Cores for parallel execution. Default 2. |
seed |
Optional integer seed for reproducibility. |
An object of class net_markov_order with elements:
Integer. Selected order via sequential permutation test.
Integer. Order minimising BIC (reported by
print/plot; not used in the permutation selection).
Integer. Order minimising AIC (reported by
print/plot; not used in the permutation selection).
Tidy data.frame, one row per order tested with
columns order, loglik, AIC, BIC,
df, g2, p_permutation, p_asymptotic,
significant. AIC/BIC are the
information-criterion values used for the ic plot panel and
to derive aic_order/bic_order; the order-0 row has
NA for the test columns (df, g2,
p_permutation, p_asymptotic, significant).
List of numeric vectors (length max_order),
one empirical null distribution per order.
Named numeric vector of log-likelihoods per order (for AIC / BIC panel only, not used in the test).
Named integer vector of model degrees of freedom per order (free parameters added at each layer), used to compute the AIC / BIC columns.
List of fitted transition matrices.
Character vector of observed state labels.
Data summary.
Call settings.
# First-order Markov data: test should select order 1 set.seed(1) states <- letters[1:4] tm <- matrix(runif(16), 4, 4, dimnames = list(states, states)) tm <- tm / rowSums(tm) seqs <- lapply(1:30, function(.) { s <- character(50); s[1] <- sample(states, 1) for (i in 2:50) s[i] <- sample(states, 1, prob = tm[s[i - 1], ]) s }) res <- markov_order_test(seqs, max_order = 3, n_perm = 300, seed = 1) res$optimal_order summary(res) plot(res)# First-order Markov data: test should select order 1 set.seed(1) states <- letters[1:4] tm <- matrix(runif(16), 4, 4, dimnames = list(states, states)) tm <- tm / rowSums(tm) seqs <- lapply(1:30, function(.) { s <- character(50); s[1] <- sample(states, 1) for (i in 2:50) s[i] <- sample(states, 1, prob = tm[s[i - 1], ]) s }) res <- markov_order_test(seqs, max_order = 3, n_perm = 300, seed = 1) res$optimal_order summary(res) plot(res)
Computes per-state stability metrics from a transition network: persistence (self-loop probability), stationary distribution, mean recurrence time, sojourn time, and mean accessibility to/from other states.
markov_stability(x, normalize = TRUE) ## S3 method for class 'net_markov_stability' plot( x, metrics = c("persistence", "stationary_prob", "return_time", "sojourn_time", "avg_time_to_others", "avg_time_from_others"), combined = TRUE, ... )markov_stability(x, normalize = TRUE) ## S3 method for class 'net_markov_stability' plot( x, metrics = c("persistence", "stationary_prob", "return_time", "sojourn_time", "avg_time_to_others", "avg_time_from_others"), combined = TRUE, ... )
x |
A |
normalize |
Logical. Normalize rows to sum to 1? Default |
metrics |
Character vector. Which metrics to plot. Options:
|
combined |
When |
... |
Ignored. |
Sojourn time is the expected consecutive time steps spent in a
state before leaving: . States with
persistence = 1 have sojourn_time = Inf.
avg_time_to_others: mean passage time from this state to all others; reflects how "sticky" or "isolated" the state is.
avg_time_from_others: mean passage time from all other states to this one; reflects accessibility (attractor strength).
An object of class "net_markov_stability" with:
Data frame with one row per state and columns:
state, persistence (),
stationary_prob (),
return_time (),
sojourn_time (),
avg_time_to_others (mean MFPT leaving state ),
avg_time_from_others (mean MFPT arriving at state ).
The underlying net_mpt object.
net <- build_network(as.data.frame(trajectories), method = "relative") ms <- markov_stability(net) print(ms) plot(ms)net <- build_network(as.data.frame(trajectories), method = "relative") ms <- markov_stability(net) print(ms) plot(ms)
Returns a data frame of all transitions at a given Markov order, sorted by count (descending). Each row shows the full path as a readable sequence of states, along with the observed count and transition probability.
mogen_transitions(x, order = NULL, min_count = 1L)mogen_transitions(x, order = NULL, min_count = 1L)
x |
A |
order |
Integer. Which order's transitions to extract. Must be a whole number; a non-integer value is an error rather than being silently truncated. Defaults to the optimal order selected by the model. |
min_count |
Integer. Minimum observed count to include (default 1). Use this to filter out rare transitions that have unreliable probabilities. |
At order k, each edge in the De Bruijn graph represents a (k+1)-step path.
For example, at order 2, the edge from node "AI -> FAIL" to node
"FAIL -> SOLVE" represents the three-step path AI -> FAIL -> SOLVE.
The path column reconstructs this full sequence for readability.
A data frame with columns:
The full state sequence (e.g., "AI -> FAIL -> SOLVE").
Number of times this transition was observed.
Transition probability P(to | from).
The context / conditioning states (k-gram source node).
The predicted next state.
seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) mg <- build_mogen(seqs, max_order = 2) mogen_transitions(mg, order = 1) trajs <- list(c("A","B","C","D"), c("A","B","D","C"), c("B","C","D","A"), c("C","D","A","B")) m <- build_mogen(trajs, max_order = 3) mogen_transitions(m, order = 1)seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) mg <- build_mogen(seqs, max_order = 2) mogen_transitions(mg, order = 1) trajs <- list(c("A","B","C","D"), c("A","B","D","C"), c("B","C","D","A"), c("C","D","A","B")) m <- build_mogen(trajs, max_order = 3) mogen_transitions(m, order = 1)
Draws a Hartigan-Friendly mosaic (marimekko geometry, chi-square
standardized-residual fill) for an integer-weighted network. Equivalent in
algorithm and appearance to tna::plot_mosaic(); named differently to
avoid an export clash when both packages are attached.
mosaic_plot(x, ...) ## Default S3 method: mosaic_plot(x, ...) ## S3 method for class 'netobject' mosaic_plot( x, xlab = NULL, ylab = NULL, range = NULL, top_angle = NULL, left_angle = NULL, residuals = c("permutation", "asymptotic"), n_perm = 500L, seed = NULL, values = FALSE, ... ) ## S3 method for class 'htna' mosaic_plot( x, xlab = NULL, ylab = NULL, range = NULL, top_angle = NULL, left_angle = NULL, residuals = c("permutation", "asymptotic"), n_perm = 500L, seed = NULL, values = FALSE, ... ) ## S3 method for class 'mcml' mosaic_plot( x, level = c("macro", "clusters"), xlab = NULL, ylab = NULL, range = NULL, top_angle = NULL, left_angle = NULL, residuals = c("permutation", "asymptotic"), n_perm = 500L, seed = NULL, ncol = 2L, values = FALSE, ... ) ## S3 method for class 'netobject_group' mosaic_plot( x, xlab = NULL, ylab = NULL, range = NULL, top_angle = NULL, left_angle = NULL, residuals = c("permutation", "asymptotic"), n_perm = 500L, seed = NULL, ncol = 2L, values = FALSE, ... ) ## S3 method for class 'table' mosaic_plot( x, xlab = "Row", ylab = "Column", range = NULL, top_angle = NULL, left_angle = NULL, residuals = c("permutation", "asymptotic"), n_perm = 500L, seed = NULL, values = FALSE, ... ) ## S3 method for class 'matrix' mosaic_plot(x, ...)mosaic_plot(x, ...) ## Default S3 method: mosaic_plot(x, ...) ## S3 method for class 'netobject' mosaic_plot( x, xlab = NULL, ylab = NULL, range = NULL, top_angle = NULL, left_angle = NULL, residuals = c("permutation", "asymptotic"), n_perm = 500L, seed = NULL, values = FALSE, ... ) ## S3 method for class 'htna' mosaic_plot( x, xlab = NULL, ylab = NULL, range = NULL, top_angle = NULL, left_angle = NULL, residuals = c("permutation", "asymptotic"), n_perm = 500L, seed = NULL, values = FALSE, ... ) ## S3 method for class 'mcml' mosaic_plot( x, level = c("macro", "clusters"), xlab = NULL, ylab = NULL, range = NULL, top_angle = NULL, left_angle = NULL, residuals = c("permutation", "asymptotic"), n_perm = 500L, seed = NULL, ncol = 2L, values = FALSE, ... ) ## S3 method for class 'netobject_group' mosaic_plot( x, xlab = NULL, ylab = NULL, range = NULL, top_angle = NULL, left_angle = NULL, residuals = c("permutation", "asymptotic"), n_perm = 500L, seed = NULL, ncol = 2L, values = FALSE, ... ) ## S3 method for class 'table' mosaic_plot( x, xlab = "Row", ylab = "Column", range = NULL, top_angle = NULL, left_angle = NULL, residuals = c("permutation", "asymptotic"), n_perm = 500L, seed = NULL, values = FALSE, ... ) ## S3 method for class 'matrix' mosaic_plot(x, ...)
x |
One of the four data-bearing Nestimate classes:
|
... |
Ignored. |
xlab, ylab
|
Axis labels. |
range |
Numeric of length 2 giving the lower and upper colour-scale
limits for the standardized residual. |
top_angle, left_angle
|
Rotation in degrees for the top (x) and left
(y) tick labels. |
residuals |
One of |
n_perm |
Number of permutations when |
seed |
Optional integer seed for the permutation RNG. Use for
reproducible plots; ignored when |
values |
Logical. When |
level |
For |
ncol |
For |
Column widths are proportional to row marginals of the weight matrix
(incoming totals when the matrix is transposed, as for transitions). Within
each column, segment heights are proportional to that row's conditional
distribution. Cell fill is the standardized residual from
stats::chisq.test(), with a diverging palette clipped to .
Mosaics need integer counts: when $weights is already integer
(method = "frequency" / "co_occurrence") it is used directly;
for a single netobject / htna otherwise (relative, glasso,
cor, ...) order-1 transition counts are recounted from the raw $data
sequences. The function errors only when neither integer weights nor
$data are available.
A ggplot object (or a gtable from
gridExtra::arrangeGrob for netobject_group when
gridExtra is available).
plot_mosaic for the lower-level data.frame primitive.
## Not run: net <- build_network(group_regulation, method = "frequency") mosaic_plot(net) ## End(Not run)## Not run: net <- build_network(group_regulation, method = "frequency") mosaic_plot(net) ## End(Not run)
Tests whether two networks estimated from independent samples differ at three levels: global strength (M-statistic), network structure (S-statistic, max absolute edge difference), and individual edges (E-statistic per edge). Inference is via permutation of group labels.
nct( data1, data2, iter = 1000L, gamma = 0.5, paired = FALSE, abs = TRUE, weighted = TRUE, p_adjust = "none" )nct( data1, data2, iter = 1000L, gamma = 0.5, paired = FALSE, abs = TRUE, weighted = TRUE, p_adjust = "none" )
data1 |
A numeric matrix or data.frame of observations from group 1. |
data2 |
A numeric matrix or data.frame of observations from group 2.
Same number of columns as |
iter |
Integer. Number of permutation iterations. Default 1000. |
gamma |
EBIC tuning parameter for glasso. Default 0.5. |
paired |
Logical. If |
abs |
Logical. If |
weighted |
Logical. If |
p_adjust |
P-value adjustment method for the per-edge tests
(any method in |
Implementation matches NetworkComparisonTest::NCT() with defaults
abs = TRUE, weighted = TRUE, paired = FALSE at
machine precision when the same seed is used. The network estimator is
EBIC-selected glasso applied to a Pearson correlation matrix, with
Matrix::nearPD symmetrization (matching NCT's
NCT_estimator_GGM default).
A list of class net_nct with elements:
Estimated weighted adjacency matrices.
List with observed, perm, p_value for
the global strength test.
Same structure for the maximum absolute edge difference.
Same structure for per-edge tests.
Number of permutations.
Whether a paired test was used.
## Not run: set.seed(1) x1 <- matrix(rnorm(200 * 5), 200, 5) x2 <- matrix(rnorm(200 * 5), 200, 5) colnames(x1) <- colnames(x2) <- paste0("V", 1:5) res <- nct(x1, x2, iter = 100) res$M$p_value res$S$p_value ## End(Not run)## Not run: set.seed(1) x1 <- matrix(rnorm(200 * 5), 200, 5) x2 <- matrix(rnorm(200 * 5), 200, 5) colnames(x1) <- colnames(x2) <- paste0("V", 1:5) res <- nct(x1, x2, iter = 100) res$M$p_value res$S$p_value ## End(Not run)
Aggregates a vector of edge weights using various methods. Compatible with igraph's edge.attr.comb parameter.
net_aggregate_weights(w, method = "sum", n_possible = NULL)net_aggregate_weights(w, method = "sum", n_possible = NULL)
w |
Numeric vector of finite edge weights. |
method |
Single aggregation method: "sum", "mean", "median", "max",
"min", "prod", "density", or "geomean". Because zeros are stripped first,
|
n_possible |
Optional single finite numeric number of possible edges
for density calculation. When omitted, |
Single aggregated value
w <- c(0.5, 0.8, 0.3, 0.9) net_aggregate_weights(w, "sum") # 2.5 net_aggregate_weights(w, "mean") # 0.625 net_aggregate_weights(w, "max") # 0.9 net_aggregate_weights(w, "density", n_possible = 9) # 2.5 / 9w <- c(0.5, 0.8, 0.3, 0.9) net_aggregate_weights(w, "sum") # 2.5 net_aggregate_weights(w, "mean") # 0.625 net_aggregate_weights(w, "max") # 0.9 net_aggregate_weights(w, "density", n_possible = 9) # 2.5 / 9
Computes centrality measures from a netobject,
netobject_group, or cograph_network. For directed networks
the default measures are InStrength, OutStrength, and Betweenness. For
undirected networks the defaults are Closeness and Betweenness.
net_centrality(x, measures = NULL, loops = FALSE, centrality_fn = NULL, ...)net_centrality(x, measures = NULL, loops = FALSE, centrality_fn = NULL, ...)
x |
A |
measures |
Character vector. Centrality measures to compute.
Built-in: |
loops |
Logical. Include self-loops (diagonal) in computation?
Default: |
centrality_fn |
Optional function. Custom centrality function that takes a weight matrix and returns a named list of centrality vectors. |
... |
Additional arguments (ignored). |
For a netobject: a data frame with node names as rows and
centrality measures as columns. For a netobject_group: a named
list of such data frames (one per group).
seqs <- data.frame( V1 = c("A","B","A","C"), V2 = c("B","C","B","A"), V3 = c("C","A","C","B")) net <- build_network(seqs, method = "relative") net_centrality(net)seqs <- data.frame( V1 = c("A","B","A","C"), V2 = c("B","C","B","A"), V3 = c("C","A","C","B")) net <- build_network(seqs, method = "relative") net_centrality(net)
Assesses the stability of network estimates by repeatedly splitting sequences into two halves, building networks from each half, and comparing them. Supports single-model reliability assessment and multi-model comparison with optional scaling for cross-method comparability.
For transition methods ("relative", "frequency",
"co_occurrence"), uses pre-computed per-sequence count matrices
for fast resampling (same infrastructure as
bootstrap_network).
network_reliability( ..., iter = 1000L, split = 0.5, scale = "none", seed = NULL )network_reliability( ..., iter = 1000L, split = 0.5, scale = "none", seed = NULL )
... |
One or more |
iter |
Integer. Number of split-half iterations (default: 1000). |
split |
Numeric. Fraction of sequences assigned to the first half (default: 0.5). |
scale |
Character. Scaling applied to both split-half matrices
before computing metrics. One of |
seed |
Integer or NULL. RNG seed for reproducibility. |
An object of class "net_reliability" containing:
Data frame with columns model, mean_dev,
median_dev, cor, max_dev (one row per iteration
per model).
Data frame with columns model, metric,
mean, sd.
Named list of the original netobjects.
Number of iterations.
Split fraction.
Scaling method used.
build_network, bootstrap_network
net <- build_network(data.frame(V1 = c("A","B","C","A"), V2 = c("B","C","A","B")), method = "relative") rel <- network_reliability(net, iter = 10) seqs <- data.frame( V1 = sample(LETTERS[1:4], 30, TRUE), V2 = sample(LETTERS[1:4], 30, TRUE), V3 = sample(LETTERS[1:4], 30, TRUE), V4 = sample(LETTERS[1:4], 30, TRUE) ) net <- build_network(seqs, method = "relative") rel <- network_reliability(net, iter = 100, seed = 42) print(rel)net <- build_network(data.frame(V1 = c("A","B","C","A"), V2 = c("B","C","A","B")), method = "relative") rel <- network_reliability(net, iter = 10) seqs <- data.frame( V1 = sample(LETTERS[1:4], 30, TRUE), V2 = sample(LETTERS[1:4], 30, TRUE), V3 = sample(LETTERS[1:4], 30, TRUE), V4 = sample(LETTERS[1:4], 30, TRUE) ) net <- build_network(seqs, method = "relative") rel <- network_reliability(net, iter = 100, seed = 42) print(rel)
Computes the full matrix of mean first passage times (MFPT) for a Markov
chain. Element is the expected number of steps to travel from
state to state for the first time. The diagonal equals
the mean recurrence time .
passage_time(x, states = NULL, normalize = TRUE) ## S3 method for class 'net_mpt' summary(object, ...) ## S3 method for class 'net_mpt' plot( x, log_scale = TRUE, digits = 1, title = "Mean First Passage Times", low = "#004d00", high = "#ccffcc", ... )passage_time(x, states = NULL, normalize = TRUE) ## S3 method for class 'net_mpt' summary(object, ...) ## S3 method for class 'net_mpt' plot( x, log_scale = TRUE, digits = 1, title = "Mean First Passage Times", low = "#004d00", high = "#ccffcc", ... )
x |
A |
states |
Character vector. Restrict output to these states.
|
normalize |
Logical. If |
object |
A |
... |
Ignored. |
log_scale |
Logical. Apply log transform to the fill scale for better
contrast? Default |
digits |
Integer. Decimal places displayed in cells. Default |
title |
Character. Plot title. |
low |
Character. Hex colour for the low end (short passage time).
Default dark green |
high |
Character. Hex colour for the high end (long passage time).
Default pale green |
Uses the Kemeny-Snell fundamental matrix formula:
where . Requires an ergodic (irreducible,
aperiodic) chain.
An object of class "net_mpt" with:
Full MFPT matrix. Row , column
= expected steps from state to state .
Diagonal = mean recurrence time .
Named numeric vector: stationary distribution .
Named numeric vector: per state.
Character vector of state names.
summary.net_mpt returns a data frame with one row per state
and columns state, return_time, stationary,
mean_out (mean steps to other states), mean_in (mean steps
from other states).
Kemeny, J.G. and Snell, J.L. (1976). Finite Markov Chains. Springer-Verlag.
markov_stability, build_network
net <- build_network(as.data.frame(trajectories), method = "relative") pt <- passage_time(net) print(pt) plot(pt)net <- build_network(as.data.frame(trajectories), method = "relative") pt <- passage_time(net) print(pt) plot(pt)
Counts the frequency of k-step paths (k-grams) across all trajectories. Useful for understanding which sequences dominate the data before applying formal models.
path_counts(data, k = 2L, top = NULL)path_counts(data, k = 2L, top = NULL)
data |
A list of character vectors (trajectories) or a data.frame (rows = trajectories, columns = time points). |
k |
Integer. Length of the path / n-gram (default 2). A k of 2 counts individual transitions; k of 3 counts two-step paths, etc. Must be a whole number; a non-integer value is an error rather than being silently truncated. |
top |
Integer or NULL. If set, returns only the top N most frequent paths (default NULL = all). |
A data frame with columns: path, count,
proportion.
trajs <- list(c("A","B","C","D"), c("A","B","D","C")) path_counts(trajs, k = 2) path_counts(trajs, k = 3, top = 10)trajs <- list(c("A","B","C","D"), c("A","B","D","C")) path_counts(trajs, k = 2) path_counts(trajs, k = 3, top = 10)
Diagnoses where a chain's order-1 Markov assumption fails by comparing,
for each order-k context , the empirical
next-state distribution against
the order-1 prediction that uses only the most
recent state. Returns a tidy per-context table sorted by Kullback-Leibler
divergence so the analyst can see exactly which histories carry extra
predictive information.
path_dependence(x, order = 2L, min_count = 5L, base = 2)path_dependence(x, order = 2L, min_count = 5L, base = 2)
x |
A wide sequence data.frame / matrix (rows = actors, columns =
time-steps), or a |
order |
Integer. Order of the conditioning context. |
min_count |
Integer. Drop contexts seen fewer than this many times. Default 5. Very small samples produce noisy KL estimates. |
base |
Numeric. Logarithm base for entropy and KL. Default 2 (bits). |
For each context occurring at least
min_count times, the function computes:
the empirical conditional from k-gram counts;
the order-1 prediction from the
most recent state alone (the bigram-marginal estimator);
the entropy drop - bits of uncertainty
removed by extending memory by one step in this specific context;
the Kullback-Leibler divergence -
bits of "surprise" if you used the order-1 model when the order-k
model is true.
KL = 0 means longer history adds no information for that context.
H_drop > 0 means longer history sharpens the prediction;
H_drop < 0 indicates the order-k context happens to spread
probability across more outcomes than order-1 alone (small-sample noise
or genuine context-induced uncertainty - inspect n).
Contexts where flips = TRUE are the substantively interesting
ones: the longer history changes the modal prediction, not just its
confidence.
Pair this with markov_order_test (which decides whether
order-k is needed globally) to see the chain-level decision broken
down per context.
An object of class "net_path_dependence" with
tidy data.frame, one row per order-k context, sorted
by KL descending. Columns: context (e.g. "A -> B"), n
(count), H_order1 (entropy of ),
H_orderk (entropy of ),
H_drop (= H_order1 - H_orderk), KL
(= ), top_o1 (most likely next state
under order-1), top_ok (most likely next state under order-k),
flips (logical: did the most likely next state change?).
list with chain-level summaries: KL_weighted
(count-weighted mean KL across contexts), H_drop_weighted
(count-weighted mean entropy drop), n_contexts, n_flips
(contexts where the most-likely next state changed).
integer
numeric
integer
character vector
Cover, T.M. & Thomas, J.A. (2006). Elements of Information Theory, 2nd ed., chapters 2 and 4. Wiley. (KL divergence and conditional entropy.)
markov_order_test, transition_entropy,
build_mogen
data(trajectories, package = "Nestimate") pd <- path_dependence(as.data.frame(trajectories), order = 2) print(pd) summary(pd) plot(pd)data(trajectories, package = "Nestimate") pd <- path_dependence(as.data.frame(trajectories), order = 2) print(pd) summary(pd) plot(pd)
Extracts higher-order pathway strings suitable for
cograph::plot_simplicial(). Each pathway represents a
multi-step dependency: source states lead to a target state.
For net_hon: extracts edges where the source node is
higher-order (order > 1), i.e., the transitions that differ from
first-order Markov.
For net_hypa: extracts anomalous paths (over- or
under-represented relative to the hypergeometric null model).
For net_mogen: extracts all transitions at the optimal order
(or a specified order).
pathways(x, ...) ## S3 method for class 'net_hon' pathways(x, min_count = 1L, min_prob = 0, top = NULL, order = NULL, ...) ## S3 method for class 'net_hypa' pathways(x, type = "all", ...) ## S3 method for class 'netobject' pathways(x, ho_method = c("hon", "hypa"), ...) ## S3 method for class 'net_association_rules' pathways(x, top = NULL, min_lift = NULL, min_confidence = NULL, ...) ## S3 method for class 'net_link_prediction' pathways(x, method = NULL, top = 10L, evidence = TRUE, max_evidence = 3L, ...) ## S3 method for class 'net_mogen' pathways(x, order = NULL, min_count = 1L, min_prob = 0, top = NULL, ...)pathways(x, ...) ## S3 method for class 'net_hon' pathways(x, min_count = 1L, min_prob = 0, top = NULL, order = NULL, ...) ## S3 method for class 'net_hypa' pathways(x, type = "all", ...) ## S3 method for class 'netobject' pathways(x, ho_method = c("hon", "hypa"), ...) ## S3 method for class 'net_association_rules' pathways(x, top = NULL, min_lift = NULL, min_confidence = NULL, ...) ## S3 method for class 'net_link_prediction' pathways(x, method = NULL, top = 10L, evidence = TRUE, max_evidence = 3L, ...) ## S3 method for class 'net_mogen' pathways(x, order = NULL, min_count = 1L, min_prob = 0, top = NULL, ...)
x |
A higher-order network object ( |
... |
Additional arguments. |
min_count |
Integer. Minimum transition count to include (default: 1). |
min_prob |
Numeric. Minimum transition probability to include (default: 0). |
top |
Integer or NULL. Return only the top N pathways ranked by count (default: NULL = all). |
order |
Integer or NULL. Markov order to extract. Default: optimal order from model selection. |
type |
Character. Which anomalies to include: |
ho_method |
Character. Higher-order method: |
min_lift |
Numeric or NULL. Additional lift filter applied on top of the object's original threshold (default: NULL). |
min_confidence |
Numeric or NULL. Additional confidence filter (default: NULL). |
method |
Character or NULL. Which prediction method to use. Default: first method in the object. |
evidence |
Logical. If TRUE, include common neighbor evidence nodes in each pathway. Default: TRUE. |
max_evidence |
Integer. Maximum number of evidence nodes per pathway (default: 3). |
A character vector of pathway strings in arrow notation
(e.g. "A B -> C"), suitable for
cograph::plot_simplicial().
A character vector of pathway strings.
A character vector of pathway strings.
A character vector of pathway strings.
A character vector of pathway strings.
A character vector of pathway strings.
A character vector of pathway strings.
pathways(net_hon): Extract higher-order pathways from HON
pathways(net_hypa): Extract anomalous pathways from HYPA
pathways(netobject): Extract pathways from a netobject
Builds a Higher-Order Network (HON) from the netobject's sequence data
and returns the higher-order pathways. Requires that the netobject was
built from sequence data (has $data).
pathways(net_association_rules): Extract pathways from association rules
Converts association rules {A, B} => {C} into pathway strings
"A B -> C" suitable for cograph::plot_simplicial().
Antecedent items become source nodes; consequent items become the target.
pathways(net_link_prediction): Extract pathways from link predictions
Converts predicted links into pathway strings for
cograph::plot_simplicial(). When evidence = TRUE
(default), each predicted edge A -> B is enriched with common
neighbors that structurally support the prediction, producing
"A cn1 cn2 -> B".
pathways(net_mogen): Extract transition pathways from MOGen
seqs <- list(c("A","B","C","D"), c("A","B","C","A")) hon <- build_hon(seqs, max_order = 3) pw <- pathways(hon) trans <- list(c("A","B","C"), c("A","B"), c("B","C","D"), c("A","C","D")) rules <- association_rules(trans, min_support = 0.3, min_confidence = 0.3, min_lift = 0) pathways(rules) seqs <- data.frame( V1 = sample(LETTERS[1:5], 50, TRUE), V2 = sample(LETTERS[1:5], 50, TRUE), V3 = sample(LETTERS[1:5], 50, TRUE) ) net <- build_network(seqs, method = "relative") pred <- predict_links(net, methods = "common_neighbors") pathways(pred)seqs <- list(c("A","B","C","D"), c("A","B","C","A")) hon <- build_hon(seqs, max_order = 3) pw <- pathways(hon) trans <- list(c("A","B","C"), c("A","B"), c("B","C","D"), c("A","C","D")) rules <- association_rules(trans, min_support = 0.3, min_confidence = 0.3, min_lift = 0) pathways(rules) seqs <- data.frame( V1 = sample(LETTERS[1:5], 50, TRUE), V2 = sample(LETTERS[1:5], 50, TRUE), V3 = sample(LETTERS[1:5], 50, TRUE) ) net <- build_network(seqs, method = "relative") pred <- predict_links(net, methods = "common_neighbors") pathways(pred)
Compares two networks estimated by build_network using a
permutation test. Works with all built-in methods (transition and
association) as well as custom registered estimators. The test shuffles
which observations belong to which group, re-estimates networks, and tests
whether observed edge-wise differences exceed chance.
For transition methods ("relative", "frequency",
"co_occurrence"), uses a fast pre-computation strategy: per-sequence
count matrices are computed once, and each permutation iteration only
shuffles group labels and computes group-wise colSums.
For association methods ("cor", "pcor", "glasso",
and custom estimators), the full estimator is called on each permuted
group split.
If either transition network contains only one sequence, the function warns that such a network is not recommended for permutation or other confirmatory testing.
permutation( x, y = NULL, iter = 1000L, alpha = 0.05, paired = FALSE, adjust = "none", nlambda = 50L, seed = NULL )permutation( x, y = NULL, iter = 1000L, alpha = 0.05, paired = FALSE, adjust = "none", nlambda = 50L, seed = NULL )
x |
A |
y |
A |
iter |
Integer. Number of permutation iterations (default: 1000). |
alpha |
Numeric. Significance level (default: 0.05). |
paired |
Logical. If |
adjust |
Character. p-value adjustment method passed to
|
nlambda |
Integer. Number of lambda values for the |
seed |
Integer or NULL. RNG seed for reproducibility. |
An object of class "net_permutation" containing:
The first netobject.
The second netobject.
Observed difference matrix (x - y).
Observed difference where p < alpha, else 0.
P-value matrix (adjusted if adjust != "none").
Effect size matrix (observed diff / SD of permutation diffs).
Long-format data frame of edge-level results.
The network estimation method.
Number of permutation iterations.
Significance level used.
Whether paired permutation was used.
p-value adjustment method used.
build_network, bootstrap_network,
print.net_permutation,
summary.net_permutation
s1 <- data.frame(V1 = c("A","B","C"), V2 = c("B","C","A")) s2 <- data.frame(V1 = c("A","C","B"), V2 = c("C","B","A")) n1 <- build_network(s1, method = "relative") n2 <- build_network(s2, method = "relative") perm <- permutation(n1, n2, iter = 10) set.seed(1) d1 <- data.frame(V1 = sample(LETTERS[1:4], 20, TRUE), V2 = sample(LETTERS[1:4], 20, TRUE), V3 = sample(LETTERS[1:4], 20, TRUE)) d2 <- data.frame(V1 = sample(LETTERS[1:4], 20, TRUE), V2 = sample(LETTERS[1:4], 20, TRUE), V3 = sample(LETTERS[1:4], 20, TRUE)) net1 <- build_network(d1, method = "relative") net2 <- build_network(d2, method = "relative") perm <- permutation(net1, net2, iter = 100, seed = 42) print(perm) summary(perm)s1 <- data.frame(V1 = c("A","B","C"), V2 = c("B","C","A")) s2 <- data.frame(V1 = c("A","C","B"), V2 = c("C","B","A")) n1 <- build_network(s1, method = "relative") n2 <- build_network(s2, method = "relative") perm <- permutation(n1, n2, iter = 10) set.seed(1) d1 <- data.frame(V1 = sample(LETTERS[1:4], 20, TRUE), V2 = sample(LETTERS[1:4], 20, TRUE), V3 = sample(LETTERS[1:4], 20, TRUE)) d2 <- data.frame(V1 = sample(LETTERS[1:4], 20, TRUE), V2 = sample(LETTERS[1:4], 20, TRUE), V3 = sample(LETTERS[1:4], 20, TRUE)) net1 <- build_network(d1, method = "relative") net2 <- build_network(d2, method = "relative") perm <- permutation(net1, net2, iter = 100, seed = 42) print(perm) summary(perm)
Computes the persistence landscape (Bubenik 2015) from a persistence diagram. Each (birth, death) pair contributes a tent function
The -th landscape function is the
-th largest of at each
. Landscapes are stable under bottleneck distance and form a
Banach-space embedding of persistence diagrams.
persistence_landscape(ph, k_max = 5L, dimension = 1L, t_grid = NULL)persistence_landscape(ph, k_max = 5L, dimension = 1L, t_grid = NULL)
ph |
A |
k_max |
Maximum landscape index to compute (default 5). Must be a single positive integer. |
dimension |
Integer scalar – which homology dimension to compute the landscape for. Default 1. |
t_grid |
Numeric vector of evaluation points. |
A persistence_landscape object with:
Data frame: k, t, value.
Integer scalar.
Integer scalar.
Numeric vector.
Bubenik, P. (2015). Statistical topological data analysis using persistence landscapes. Journal of Machine Learning Research 16, 77-102.
mat <- matrix(c(0, .6, .5, .6, 0, .4, .5, .4, 0), 3, 3) rownames(mat) <- colnames(mat) <- c("A","B","C") ph <- persistent_homology(mat, n_steps = 5) pl <- persistence_landscape(ph, k_max = 3, dimension = 0)mat <- matrix(c(0, .6, .5, .6, 0, .4, .5, .4, 0), 3, 3) rownames(mat) <- colnames(mat) <- c("A","B","C") ph <- persistent_homology(mat, n_steps = 5) pl <- persistence_landscape(ph, k_max = 3, dimension = 0)
Computes persistent homology via full boundary-matrix reduction over
(Edelsbrunner, Letscher & Zomorodian 2000). The
returned persistence diagram pairs each k-dimensional homology class
to the simplex whose addition creates it (birth) and the simplex whose
addition destroys it (death). Essential classes — those never killed —
are reported with death = 0 in clique mode (similarity scale,
descending) and death = Inf in VR mode (distance scale, ascending).
Two filtration modes are supported:
type = "clique"Weighted clique filtration. Input is
treated as a similarity matrix; high-weight simplices appear early.
For each k-simplex , the filtration value is
. Thresholds run high to low.
type = "vr"Vietoris-Rips filtration on a non-negative
distance matrix. For each k-simplex , the filtration
value is . Thresholds run low
to high. Use max_scale to cap the filtration diameter.
persistent_homology( x, n_steps = 20L, max_dim = 3L, type = "clique", max_scale = NULL )persistent_homology( x, n_steps = 20L, max_dim = 3L, type = "clique", max_scale = NULL )
x |
A square matrix, |
n_steps |
Number of grid points for the reported Betti curve
(default 20). The persistence diagram itself is exact — it does not
depend on |
max_dim |
Maximum simplex dimension to track (default 3). |
type |
Filtration: |
max_scale |
For |
A persistent_homology object with:
Data frame: threshold, dimension,
betti.
Data frame of birth-death pairs:
dimension, birth, death, persistence.
Sorted by descending persistence.
Numeric vector of grid thresholds.
Either "clique" or "vr".
Edelsbrunner, H., Letscher, D., & Zomorodian, A. (2000). Topological persistence and simplification. Discrete & Computational Geometry 28, 511-533.
mat <- matrix(c(0,.6,.5,.6,0,.4,.5,.4,0), 3, 3) colnames(mat) <- rownames(mat) <- c("A","B","C") ph <- persistent_homology(mat, n_steps = 10) print(ph)mat <- matrix(c(0,.6,.5,.6,0,.4,.5,.4,0), 3, 3) colnames(mat) <- rownames(mat) <- c("A","B","C") ph <- persistent_homology(mat, n_steps = 10) print(ph)
Low-level rectangle-coordinate builder for marimekko (mosaic) plots.
Column widths are proportional to the per-column total of weight;
within each column, segments stack to height 1 with sub-heights
proportional to each row's share of that column's total.
plot_mosaic( data, x, y, weight, fill = "y", colors = NULL, show_labels = TRUE, label_size = 3.5, x_label = NULL, y_label = NULL )plot_mosaic( data, x, y, weight, fill = "y", colors = NULL, show_labels = TRUE, label_size = 3.5, x_label = NULL, y_label = NULL )
data |
A data.frame in long form. Must contain the columns named
in |
x |
Column name for the X (column) variable. |
y |
Column name for the Y (segment) variable. |
weight |
Column name for the cell weight (e.g. count). |
fill |
Either |
colors |
Optional character vector of fill colors. When
|
show_labels |
If |
label_size |
Numeric size for segment labels. |
x_label, y_label
|
Optional axis labels. |
Used internally by plot_state_frequencies; exposed so that
other plot methods (e.g. permutation-residual visualisations) can reuse
the same geometry by supplying a different fill column.
A ggplot object.
df <- data.frame( group = rep(c("A", "B", "C"), each = 3), state = rep(c("s1", "s2", "s3"), 3), count = c(10, 5, 2, 7, 8, 3, 4, 6, 12) ) plot_mosaic(df, x = "group", y = "state", weight = "count")df <- data.frame( group = rep(c("A", "B", "C"), each = 3), state = rep(c("s1", "s2", "s3"), 3), count = c(10, 5, 2, 7, 8, 3, 4, 6, 12) ) plot_mosaic(df, x = "group", y = "state", weight = "count")
Visualise state (node) frequency distributions across groups for any
Nestimate object that carries sequence data: a single netobject,
a netobject_group, an mcml model, or an htna network.
plot_state_frequencies(x, ...) ## S3 method for class 'netobject' plot_state_frequencies( x, style = "marimekko", metric = "prop", label = "prop", legend = "auto", legend_dir = "auto", legend_frame = "none", sort_states = "frequency", colors = NULL, label_size = 3.5, abbreviate = FALSE, include_macro = FALSE, combine = "auto", ncol = NULL, node_groups = NULL, ... ) ## S3 method for class 'htna' plot_state_frequencies( x, style = "marimekko", metric = "prop", label = "prop", legend = "auto", legend_dir = "auto", legend_frame = "none", sort_states = "frequency", colors = NULL, label_size = 3.5, abbreviate = FALSE, include_macro = FALSE, combine = "auto", ncol = NULL, node_groups = NULL, ... ) ## S3 method for class 'mcml' plot_state_frequencies( x, style = "marimekko", metric = "prop", label = "prop", legend = "auto", legend_dir = "auto", legend_frame = "none", sort_states = "frequency", colors = NULL, label_size = 3.5, abbreviate = FALSE, include_macro = FALSE, combine = "auto", ncol = NULL, node_groups = NULL, ... ) ## S3 method for class 'netobject_group' plot_state_frequencies( x, style = "marimekko", metric = "prop", label = "prop", legend = "auto", legend_dir = "auto", legend_frame = "none", sort_states = "frequency", colors = NULL, label_size = 3.5, abbreviate = FALSE, include_macro = FALSE, combine = "auto", ncol = NULL, node_groups = NULL, ... ) ## Default S3 method: plot_state_frequencies(x, ...)plot_state_frequencies(x, ...) ## S3 method for class 'netobject' plot_state_frequencies( x, style = "marimekko", metric = "prop", label = "prop", legend = "auto", legend_dir = "auto", legend_frame = "none", sort_states = "frequency", colors = NULL, label_size = 3.5, abbreviate = FALSE, include_macro = FALSE, combine = "auto", ncol = NULL, node_groups = NULL, ... ) ## S3 method for class 'htna' plot_state_frequencies( x, style = "marimekko", metric = "prop", label = "prop", legend = "auto", legend_dir = "auto", legend_frame = "none", sort_states = "frequency", colors = NULL, label_size = 3.5, abbreviate = FALSE, include_macro = FALSE, combine = "auto", ncol = NULL, node_groups = NULL, ... ) ## S3 method for class 'mcml' plot_state_frequencies( x, style = "marimekko", metric = "prop", label = "prop", legend = "auto", legend_dir = "auto", legend_frame = "none", sort_states = "frequency", colors = NULL, label_size = 3.5, abbreviate = FALSE, include_macro = FALSE, combine = "auto", ncol = NULL, node_groups = NULL, ... ) ## S3 method for class 'netobject_group' plot_state_frequencies( x, style = "marimekko", metric = "prop", label = "prop", legend = "auto", legend_dir = "auto", legend_frame = "none", sort_states = "frequency", colors = NULL, label_size = 3.5, abbreviate = FALSE, include_macro = FALSE, combine = "auto", ncol = NULL, node_groups = NULL, ... ) ## Default S3 method: plot_state_frequencies(x, ...)
x |
A |
... |
Reserved for future use. |
style |
One of:
For chi-square mosaics of a (group x state) contingency table, use
|
metric |
For |
label |
Inline tile / bar annotation. All formats render on a single line.
|
legend |
Legend position. |
legend_dir |
Legend internal layout: |
legend_frame |
|
sort_states |
One of |
colors |
Optional character vector overriding the default Okabe-Ito state palette. Length must be at least the number of unique states. |
label_size |
Numeric size of inline labels (max size when ggfittext is installed – text auto-shrinks per tile). |
abbreviate |
Abbreviate state names. |
include_macro |
For |
combine |
For |
ncol |
For |
node_groups |
Optional named character vector mapping node labels to semantic groups. When supplied, panels (or bars) are coloured / annotated by group rather than by individual state, so state-level palettes can collapse onto a smaller categorical legend. |
The marimekko layout is dispatched per class:
For mcml, where states partition cleanly into clusters,
the chart is a hierarchical 2D marimekko: cluster columns of width
proportional to cluster total, segments stacked vertically with
heights proportional to within-cluster state proportions.
For all other classes (netobject, netobject_group,
htna), each group is rendered as its own panel containing a
squarified treemap: each state becomes a rectangular tile whose
AREA is exactly proportional to the state's share within that group.
Single-panel when no groups exist; faceted when groups are present.
The bar style produces horizontal bars (state on the y-axis), faceted by group when groups exist. All variants use the Okabe-Ito palette.
A state_freq object: a list with the rendered $plot
(a ggplot or gtable), the tidy $table (a
data.frame with columns group, state, count,
proportion), and the call's $style, $metric,
$source_class. The class supports print() (shows the
tidy table in the console), plot() (renders the chart), and
as.data.frame() (returns the table).
if (requireNamespace("ggplot2", quietly = TRUE)) { data(group_regulation_long, package = "Nestimate") nw <- build_network(group_regulation_long, method = "relative", format = "long", actor = "Actor", action = "Action", order = "Time", group = "Course") res <- plot_state_frequencies(nw) print(res) # tidy frequency table in the console plot(res) # ggplot chart head(as.data.frame(res)) }if (requireNamespace("ggplot2", quietly = TRUE)) { data(group_regulation_long, package = "Nestimate") nw <- build_network(group_regulation_long, method = "relative", format = "long", actor = "Actor", action = "Action", order = "Time", group = "Course") res <- plot_state_frequencies(nw) print(res) # tidy frequency table in the console plot(res) # ggplot chart head(as.data.frame(res)) }
Plots bootstrap results for GLASSO networks.
## S3 method for class 'boot_glasso' plot(x, type = "edges", measure = NULL, ...)## S3 method for class 'boot_glasso' plot(x, type = "edges", measure = NULL, ...)
x |
A |
type |
Character. Plot type: |
measure |
Character. Centrality measure for
|
... |
Additional arguments passed to plotting functions. For
|
A ggplot object, invisibly.
set.seed(1) dat <- as.data.frame(matrix(rnorm(60), ncol = 3)) bg <- boot_glasso(dat, iter = 10, cs_iter = 5, centrality = "strength") plot(bg, type = "edges") set.seed(42) mat <- matrix(rnorm(60), ncol = 4) colnames(mat) <- LETTERS[1:4] boot <- boot_glasso(as.data.frame(mat), iter = 20, cs_iter = 10, centrality = "strength", seed = 42) plot(boot, type = "edges")set.seed(1) dat <- as.data.frame(matrix(rnorm(60), ncol = 3)) bg <- boot_glasso(dat, iter = 10, cs_iter = 5, centrality = "strength") plot(bg, type = "edges") set.seed(42) mat <- matrix(rnorm(60), ncol = 4) colnames(mat) <- LETTERS[1:4] boot <- boot_glasso(as.data.frame(mat), iter = 20, cs_iter = 10, centrality = "strength", seed = 42) plot(boot, type = "edges")
chain_structure.Renders the hitting-probability matrix as a heatmap, with rows and columns ordered by communicating class so the block structure is visible at a glance. State labels along both axes are coloured by classification (absorbing / recurrent / transient). The subtitle summarises the chain-level properties (regular, reversible).
## S3 method for class 'chain_structure' plot(x, show_values = TRUE, digits = 2L, ...)## S3 method for class 'chain_structure' plot(x, show_values = TRUE, digits = 2L, ...)
x |
A |
show_values |
Logical. If |
digits |
Integer. Decimal places for in-cell labels. |
... |
Ignored. |
Cell colour encodes P(ever reach j | start at i). The diagonal
uses the return-time convention (P(return to j in >= 1 steps)),
matching markovchain::hittingProbabilities. A non-irreducible chain
shows zero off-block entries – visual evidence of one-way doors
between behavioural phases. An absorbing chain shows a column of 1's
for the absorbing state.
A ggplot object.
Six explicit chart types plus a smart "auto" default. The user
picks the shape; the function does not editorialise (no "best"
annotation, no interpretive subtitles, no inferred recommendation).
## S3 method for class 'cluster_choice' plot( x, type = c("auto", "lines", "bars", "heatmap", "tradeoff", "facet"), abbrev = FALSE, combined = TRUE, ... )## S3 method for class 'cluster_choice' plot( x, type = c("auto", "lines", "bars", "heatmap", "tradeoff", "facet"), abbrev = FALSE, combined = TRUE, ... )
x |
A |
type |
Character. One of |
abbrev |
Logical. If |
combined |
Only meaningful for |
... |
Unsupported. Supplying unused arguments raises an error. |
Type cheat-sheet:
"auto"Default. Picks one of the others based on which
axes were swept. k-only -> "lines"; one categorical axis
swept -> "bars"; k plus one categorical -> "lines";
k plus two categoricals -> "facet"; both categoricals
without k -> "heatmap".
"lines"Silhouette across k (and mean_within_dist
when k is the only swept axis), one line per non-k axis
when present.
"bars"Horizontal bar chart of silhouette per axis level. Bars sorted by silhouette.
"heatmap"Tiled silhouette across two categorical
axes. Requires both dissimilarity and method swept.
"tradeoff"Scatter: silhouette (y) vs size_ratio
(x). Works for any sweep; labels each point.
"facet"Lines vs k, colour by one categorical axis,
facet by another. Requires k plus two categoricals.
Asking for a type the data can't support raises an error pointing at the alternatives.
A ggplot object, invisibly; for type = "facet"
with combined = FALSE, a named list of ggplots.
Plot Method for mmm_compare
## S3 method for class 'mmm_compare' plot(x, ...)## S3 method for class 'mmm_compare' plot(x, ...)
x |
An |
... |
Unsupported. Supplying unused arguments raises an error. |
A ggplot object, invisibly.
seqs <- data.frame(V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE)) cmp <- compare_mmm(seqs, k = 2:3, n_starts = 1, max_iter = 10, seed = 1) plot(cmp) set.seed(1) seqs <- data.frame( V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE), V3 = sample(c("A","B","C"), 30, TRUE) ) cmp <- compare_mmm(seqs, k = 2:3, n_starts = 5, seed = 1) plot(cmp)seqs <- data.frame(V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE)) cmp <- compare_mmm(seqs, k = 2:3, n_starts = 1, max_iter = 10, seed = 1) plot(cmp) set.seed(1) seqs <- data.frame( V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE), V3 = sample(c("A","B","C"), 30, TRUE) ) cmp <- compare_mmm(seqs, k = 2:3, n_starts = 5, seed = 1) plot(cmp)
Scatter plot of association rules: support vs confidence, with point size proportional to lift.
## S3 method for class 'net_association_rules' plot(x, ...)## S3 method for class 'net_association_rules' plot(x, ...)
x |
A |
... |
Additional arguments passed to |
A ggplot object, invisibly.
trans <- list(c("A","B","C"), c("A","B"), c("B","C","D"), c("A","C","D"), c("A","B","D"), c("B","C")) rules <- association_rules(trans, min_support = 0.3, min_confidence = 0.3, min_lift = 0) plot(rules)trans <- list(c("A","B","C"), c("A","B"), c("B","C","D"), c("A","C","D"), c("A","B","D"), c("B","C")) rules <- association_rules(trans, min_support = 0.3, min_confidence = 0.3, min_lift = 0) plot(rules)
Delegates to the original clustering object's plot method
(plot.net_clustering for distance-based diagnostics,
plot.net_mmm_clustering or plot.net_mmm
for model-based). The diagnostics object itself stores no plot
geometry – it just keeps a reference to the source so the existing
visual layer is reused.
## S3 method for class 'net_cluster_diagnostics' plot(x, type = NULL, ...)## S3 method for class 'net_cluster_diagnostics' plot(x, type = NULL, ...)
x |
A |
type |
Character. Forwarded to the underlying plot method. Valid
values for distance: |
... |
Forwarded to the underlying plot method. |
A ggplot object, invisibly.
Plot Sequence Clustering Results
## S3 method for class 'net_clustering' plot( x, type = c("silhouette", "mds", "heatmap", "predictors"), combined = TRUE, ... )## S3 method for class 'net_clustering' plot( x, type = c("silhouette", "mds", "heatmap", "predictors"), combined = TRUE, ... )
x |
A |
type |
Character. Plot type: |
combined |
Logical. For |
... |
Unsupported. Supplying unused arguments raises an error. |
A ggplot object (invisibly).
seqs <- data.frame(V1 = c("A","B","C","A","B"), V2 = c("B","C","A","B","A"), V3 = c("C","A","B","C","B")) cl <- build_clusters(seqs, k = 2) plot(cl, type = "silhouette") set.seed(1) seqs <- data.frame( V1 = sample(c("A","B","C"), 20, TRUE), V2 = sample(c("A","B","C"), 20, TRUE), V3 = sample(c("A","B","C"), 20, TRUE) ) cl <- build_clusters(seqs, k = 2) plot(cl, type = "silhouette")seqs <- data.frame(V1 = c("A","B","C","A","B"), V2 = c("B","C","A","B","A"), V3 = c("C","A","B","C","B")) cl <- build_clusters(seqs, k = 2) plot(cl, type = "silhouette") set.seed(1) seqs <- data.frame( V1 = sample(c("A","B","C"), 20, TRUE), V2 = sample(c("A","B","C"), 20, TRUE), V3 = sample(c("A","B","C"), 20, TRUE) ) cl <- build_clusters(seqs, k = 2) plot(cl, type = "silhouette")
Visualises a net_comparison object. Currently supports the edge-weight
scatterplot (default), with the diagonal reference (perfect agreement)
and the OLS regression line annotated by Pearson, Spearman, and Kendall
correlations.
## S3 method for class 'net_comparison' plot( x, type = c("scatter", "heatmap", "diff_hist", "weight_dist", "all"), combined = TRUE, ... )## S3 method for class 'net_comparison' plot( x, type = c("scatter", "heatmap", "diff_hist", "weight_dist", "all"), combined = TRUE, ... )
x |
A |
type |
Character. One of |
combined |
When |
... |
Ignored. |
A ggplot object; for type = "all" with combined = TRUE
a gtable arranged 2 by 2; for type = "all" with combined = FALSE
a named list of four ggplots.
Plot Method for net_gimme
## S3 method for class 'net_gimme' plot( x, type = c("temporal", "contemporaneous", "individual", "counts", "fit"), subject = NULL, ... )## S3 method for class 'net_gimme' plot( x, type = c("temporal", "contemporaneous", "individual", "counts", "fit"), subject = NULL, ... )
x |
A |
type |
Character. Plot type: |
subject |
Integer or character. Subject to plot for |
... |
Additional arguments (ignored). |
The input object, invisibly.
set.seed(1) panel <- data.frame( id = rep(1:5, each = 20), t = rep(seq_len(20), 5), A = rnorm(100), B = rnorm(100), C = rnorm(100) ) gm <- build_gimme(panel, vars = c("A","B","C"), id = "id", time = "t") plot(gm, type = "temporal")set.seed(1) panel <- data.frame( id = rep(1:5, each = 20), t = rep(seq_len(20), 5), A = rnorm(100), B = rnorm(100), C = rnorm(100) ) gm <- build_gimme(panel, vars = c("A","B","C"), id = "id", time = "t") plot(gm, type = "temporal")
Plot Method for net_honem
## S3 method for class 'net_honem' plot(x, dims = c(1L, 2L), ...)## S3 method for class 'net_honem' plot(x, dims = c(1L, 2L), ...)
x |
A |
dims |
Integer vector of length 2. Dimensions to plot (default: |
... |
Additional arguments passed to |
The input object, invisibly.
seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) hem <- build_honem(build_hon(seqs, max_order = 2), dim = 2) plot(hem) seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) hon <- build_hon(seqs, max_order = 3) he <- build_honem(hon, dim = 2) plot(he)seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) hem <- build_honem(build_hon(seqs, max_order = 2), dim = 2) plot(hem) seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) hon <- build_hon(seqs, max_order = 3) he <- build_honem(hon, dim = 2) plot(he)
Two-panel professional visualization:
Panel A: log-likelihood, AIC, BIC across tested orders with the selected order highlighted (both the permutation-selected order and the BIC-minimizing order are marked).
Panel B: permutation null density per order with the observed
as a vertical marker; colored by rejection at
alpha.
Uses the Okabe-Ito colorblind-safe palette.
## S3 method for class 'net_markov_order' plot(x, panel = c("both", "ic", "permutation"), combined = TRUE, ...)## S3 method for class 'net_markov_order' plot(x, panel = c("both", "ic", "permutation"), combined = TRUE, ...)
x |
A |
panel |
Which panel(s) to render: |
combined |
When |
... |
Ignored. |
A ggplot (single panel), a gridExtra-arranged grob (both, combined), or a named list of two ggplots (both, not combined).
# First-order Markov data: test should select order 1 set.seed(1) states <- letters[1:4] tm <- matrix(runif(16), 4, 4, dimnames = list(states, states)) tm <- tm / rowSums(tm) seqs <- lapply(1:30, function(.) { s <- character(50); s[1] <- sample(states, 1) for (i in 2:50) s[i] <- sample(states, 1, prob = tm[s[i - 1], ]) s }) res <- markov_order_test(seqs, max_order = 3, n_perm = 300, seed = 1) res$optimal_order summary(res) plot(res)# First-order Markov data: test should select order 1 set.seed(1) states <- letters[1:4] tm <- matrix(runif(16), 4, 4, dimnames = list(states, states)) tm <- tm / rowSums(tm) seqs <- lapply(1:30, function(.) { s <- character(50); s[1] <- sample(states, 1) for (i in 2:50) s[i] <- sample(states, 1, prob = tm[s[i - 1], ]) s }) res <- markov_order_test(seqs, max_order = 3, n_perm = 300, seed = 1) res$optimal_order summary(res) plot(res)
Plot Method for net_mmm
## S3 method for class 'net_mmm' plot(x, type = c("posterior", "covariates"), combined = TRUE, ...)## S3 method for class 'net_mmm' plot(x, type = c("posterior", "covariates"), combined = TRUE, ...)
x |
A |
type |
Character. Plot type: |
combined |
Logical. For |
... |
Unsupported. Supplying unused arguments raises an error. |
A ggplot object, invisibly.
seqs <- data.frame(V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE)) mmm <- build_mmm(seqs, k = 2, n_starts = 1, max_iter = 10, seed = 1) plot(mmm, type = "posterior") set.seed(1) seqs <- data.frame( V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE), V3 = sample(c("A","B","C"), 30, TRUE) ) mmm <- build_mmm(seqs, k = 2, n_starts = 5, seed = 1) plot(mmm, type = "posterior")seqs <- data.frame(V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE)) mmm <- build_mmm(seqs, k = 2, n_starts = 1, max_iter = 10, seed = 1) plot(mmm, type = "posterior") set.seed(1) seqs <- data.frame( V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE), V3 = sample(c("A","B","C"), 30, TRUE) ) mmm <- build_mmm(seqs, k = 2, n_starts = 5, seed = 1) plot(mmm, type = "posterior")
Plot routines for the MMM clustering metadata attached to a
netobject_group by cluster_mmm (or
cluster_network with cluster_by = "mmm").
Mirrors the type-driven surface of
plot.net_clustering but covers only the metrics the EM
fit produces – there is no distance matrix on an MMM clustering, so
"silhouette" / "mds" / "heatmap" aren't defined
here and the dispatcher raises a clear error if you ask for one of
those on an MMM result.
## S3 method for class 'net_mmm_clustering' plot( x, type = c("posterior", "covariates", "predictors"), combined = TRUE, ... )## S3 method for class 'net_mmm_clustering' plot( x, type = c("posterior", "covariates", "predictors"), combined = TRUE, ... )
x |
A |
type |
Character. One of |
combined |
Logical. For |
... |
Unsupported. Supplying unused arguments raises an error. |
A ggplot object, invisibly.
seqs <- data.frame(V1 = sample(c("A","B","C"), 40, TRUE), V2 = sample(c("A","B","C"), 40, TRUE)) grp <- cluster_mmm(seqs, k = 2, n_starts = 1, max_iter = 20, seed = 1) plot(attr(grp, "clustering"), type = "posterior")seqs <- data.frame(V1 = sample(c("A","B","C"), 40, TRUE), V2 = sample(c("A","B","C"), 40, TRUE)) grp <- cluster_mmm(seqs, k = 2, n_starts = 1, max_iter = 20, seed = 1) plot(attr(grp, "clustering"), type = "posterior")
Plot Method for net_mogen
## S3 method for class 'net_mogen' plot(x, type = c("ic", "likelihood"), ...)## S3 method for class 'net_mogen' plot(x, type = c("ic", "likelihood"), ...)
x |
A |
type |
Character. Plot type: |
... |
Additional arguments passed to |
The input object, invisibly.
seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) mg <- build_mogen(seqs, max_order = 2) plot(mg) seqs <- data.frame( V1 = c("A","B","C","A","B"), V2 = c("B","C","A","B","C"), V3 = c("C","A","B","C","A") ) mog <- build_mogen(seqs, max_order = 2L) plot(mog, type = "ic")seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) mg <- build_mogen(seqs, max_order = 2) plot(mg) seqs <- data.frame( V1 = c("A","B","C","A","B"), V2 = c("B","C","A","B","C"), V3 = c("C","A","B","C","A") ) mog <- build_mogen(seqs, max_order = 2L) plot(mog, type = "ic")
net_path_dependence
Lollipop chart of per-context KL divergence, sorted descending. Point size is proportional to context count; points where the modal next state flips between orders are marked with an X to highlight substantively meaningful order-2 effects.
## S3 method for class 'net_path_dependence' plot(x, top = 15L, title = NULL, ...)## S3 method for class 'net_path_dependence' plot(x, top = 15L, title = NULL, ...)
x |
A |
top |
Integer. Number of contexts to show (top by KL). Default 15. |
title |
Character. Plot title. |
... |
Ignored. |
A ggplot object.
Density plots of split-half metrics faceted by metric type. Multi-model comparisons show overlaid densities colored by model.
## S3 method for class 'net_reliability' plot(x, bins = 60L, combined = TRUE, ...)## S3 method for class 'net_reliability' plot(x, bins = 60L, combined = TRUE, ...)
x |
A |
bins |
Integer. Number of histogram bins per panel (default 60). |
combined |
When |
... |
Additional arguments (ignored). |
A ggplot object (invisibly), or a named list of four
ggplots when combined = FALSE.
net <- build_network(data.frame(V1 = c("A","B","C","A"), V2 = c("B","C","A","B")), method = "relative") rel <- network_reliability(net, iter = 10) plot(rel) set.seed(1) seqs <- data.frame( V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE), V3 = sample(c("A","B","C"), 30, TRUE) ) net <- build_network(seqs, method = "relative") rel <- network_reliability(net, iter = 20, seed = 1) plot(rel)net <- build_network(data.frame(V1 = c("A","B","C","A"), V2 = c("B","C","A","B")), method = "relative") rel <- network_reliability(net, iter = 10) plot(rel) set.seed(1) seqs <- data.frame( V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE), V3 = sample(c("A","B","C"), 30, TRUE) ) net <- build_network(seqs, method = "relative") rel <- network_reliability(net, iter = 20, seed = 1) plot(rel)
Visualizes pattern-level standardized residuals across groups. Two styles are available:
"pyramid"Back-to-back bars of pattern proportions, shaded by each side's standardized residual. Requires exactly 2 groups.
"heatmap"One tile per (pattern, group) cell, colored by standardized residual. Works for any number of groups.
Residuals are read directly from the resid_<group> columns in
$patterns, which are always populated regardless of the inference
method chosen in sequence_compare.
## S3 method for class 'net_sequence_comparison' plot( x, top_n = 10L, style = c("pyramid", "heatmap"), sort = c("statistic", "frequency"), alpha = 0.05, show_residuals = FALSE, ... )## S3 method for class 'net_sequence_comparison' plot( x, top_n = 10L, style = c("pyramid", "heatmap"), sort = c("statistic", "frequency"), alpha = 0.05, show_residuals = FALSE, ... )
x |
A |
top_n |
Integer. Show top N patterns. Default: 10. |
style |
Character. |
sort |
Character. |
alpha |
Numeric. Significance threshold for p-value display in the
pyramid: patterns with |
show_residuals |
Logical. If |
... |
Additional arguments (ignored). |
A ggplot object, invisibly.
seqs <- data.frame( V1 = sample(LETTERS[1:4], 60, TRUE), V2 = sample(LETTERS[1:4], 60, TRUE), V3 = sample(LETTERS[1:4], 60, TRUE), V4 = sample(LETTERS[1:4], 60, TRUE) ) grp <- rep(c("X", "Y"), 30) net <- build_network(seqs, method = "relative") res <- sequence_compare(net, group = grp, sub = 2:3, test = "chisq")seqs <- data.frame( V1 = sample(LETTERS[1:4], 60, TRUE), V2 = sample(LETTERS[1:4], 60, TRUE), V3 = sample(LETTERS[1:4], 60, TRUE), V4 = sample(LETTERS[1:4], 60, TRUE) ) grp <- rep(c("X", "Y"), 30) net <- build_network(seqs, method = "relative") res <- sequence_compare(net, group = grp, sub = 2:3, test = "chisq")
Plots mean correlation vs drop proportion for each centrality measure. The CS-coefficient is marked where the curve crosses the threshold.
## S3 method for class 'net_stability' plot(x, ...)## S3 method for class 'net_stability' plot(x, ...)
x |
A |
... |
Additional arguments (ignored). |
A ggplot object (invisibly).
net <- build_network(data.frame(V1 = c("A","B","C","A"), V2 = c("B","C","A","B")), method = "relative") cs <- centrality_stability(net, iter = 10, drop_prop = 0.3) plot(cs) set.seed(1) seqs <- data.frame( V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE), V3 = sample(c("A","B","C"), 30, TRUE) ) net <- build_network(seqs, method = "relative") stab <- centrality_stability(net, measures = c("InStrength","OutStrength"), iter = 10) plot(stab)net <- build_network(data.frame(V1 = c("A","B","C","A"), V2 = c("B","C","A","B")), method = "relative") cs <- centrality_stability(net, iter = 10, drop_prop = 0.3) plot(cs) set.seed(1) seqs <- data.frame( V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE), V3 = sample(c("A","B","C"), 30, TRUE) ) net <- build_network(seqs, method = "relative") stab <- centrality_stability(net, measures = c("InStrength","OutStrength"), iter = 10) plot(stab)
net_transition_entropy
Bar chart of per-state row entropy with overlaid horizontal lines at
the entropy rate (chain-level summary) and the maximum row
entropy (uniform branching). Bar widths are proportional
to the stationary probability so the visual area sums to the entropy
rate.
## S3 method for class 'net_transition_entropy' plot(x, title = "Transition Entropy", fill = "#0072B2", ...)## S3 method for class 'net_transition_entropy' plot(x, title = "Transition Entropy", fill = "#0072B2", ...)
x |
A |
title |
Character. Plot title. |
fill |
Character. Bar fill colour. Default Okabe-Ito blue. |
... |
Ignored. |
A ggplot object.
Plot Persistence Landscape
## S3 method for class 'persistence_landscape' plot(x, ...)## S3 method for class 'persistence_landscape' plot(x, ...)
x |
A |
... |
Ignored. |
A ggplot.
mat <- matrix(c(0, .6, .5, .6, 0, .4, .5, .4, 0), 3, 3) rownames(mat) <- colnames(mat) <- c("A","B","C") ph <- persistent_homology(mat, n_steps = 5) pl <- persistence_landscape(ph, k_max = 3, dimension = 0) plot(pl)mat <- matrix(c(0, .6, .5, .6, 0, .4, .5, .4, 0), 3, 3) rownames(mat) <- colnames(mat) <- c("A","B","C") ph <- persistent_homology(mat, n_steps = 5) pl <- persistence_landscape(ph, k_max = 3, dimension = 0) plot(pl)
Two panels: Betti curve (threshold vs Betti number) and persistence
diagram (birth vs death). Persistence pairs come from full boundary-
matrix reduction; essential classes are shown at the filtration boundary
(death = 0 in clique mode, death = max_scale in VR mode).
## S3 method for class 'persistent_homology' plot(x, combined = TRUE, ...)## S3 method for class 'persistent_homology' plot(x, combined = TRUE, ...)
x |
A |
combined |
When |
... |
Ignored. |
A grid grob (invisibly) when combined = TRUE; a named list
of two ggplots when combined = FALSE.
seqs <- data.frame( V1 = c("A","B","C","A","B"), V2 = c("B","C","A","B","C"), V3 = c("C","A","B","C","A") ) net <- build_network(seqs, method = "relative") ph <- persistent_homology(net) if (requireNamespace("gridExtra", quietly = TRUE)) plot(ph)seqs <- data.frame( V1 = c("A","B","C","A","B"), V2 = c("B","C","A","B","C"), V3 = c("C","A","B","C","A") ) net <- build_network(seqs, method = "relative") ph <- persistent_homology(net) if (requireNamespace("gridExtra", quietly = TRUE)) plot(ph)
Two panels: Q-vector (components at each connectivity level) and structure vector (max simplex dimension per node).
## S3 method for class 'q_analysis' plot(x, combined = TRUE, ...)## S3 method for class 'q_analysis' plot(x, combined = TRUE, ...)
x |
A |
combined |
When |
... |
Ignored. |
A grid grob (invisibly) when combined = TRUE; a named list
of two ggplots when combined = FALSE.
seqs <- data.frame( V1 = c("A","B","C","A","B"), V2 = c("B","C","A","B","C"), V3 = c("C","A","B","C","A") ) net <- build_network(seqs, method = "relative") sc <- build_simplicial(net, type = "clique") qa <- q_analysis(sc) plot(qa)seqs <- data.frame( V1 = c("A","B","C","A","B"), V2 = c("B","C","A","B","C"), V3 = c("C","A","B","C","A") ) net <- build_network(seqs, method = "relative") sc <- build_simplicial(net, type = "clique") qa <- q_analysis(sc) plot(qa)
Produces a multi-panel summary: f-vector, simplicial degree ranking, and degree-by-dimension heatmap.
## S3 method for class 'simplicial_complex' plot(x, combined = TRUE, ...)## S3 method for class 'simplicial_complex' plot(x, combined = TRUE, ...)
x |
A |
combined |
When |
... |
Ignored. |
A grid grob (invisibly) when combined = TRUE; a named list of
four ggplots when combined = FALSE.
mat <- matrix(c(0,.6,.5,.6,0,.4,.5,.4,0), 3, 3) colnames(mat) <- rownames(mat) <- c("A","B","C") sc <- build_simplicial(mat, threshold = 0.3) if (requireNamespace("gridExtra", quietly = TRUE)) plot(sc)mat <- matrix(c(0,.6,.5,.6,0,.4,.5,.4,0), 3, 3) colnames(mat) <- rownames(mat) <- c("A","B","C") sc <- build_simplicial(mat, threshold = 0.3) if (requireNamespace("gridExtra", quietly = TRUE)) plot(sc)
Computes link prediction scores for all node pairs using one or more
structural similarity methods. Accepts netobject, mcml,
cograph_network, or a raw weight matrix.
All methods are fully vectorized using matrix operations — no loops. Supports both weighted and binary adjacency, directed and undirected networks.
predict_links( x, methods = c("common_neighbors", "resource_allocation", "adamic_adar", "jaccard", "preferential_attachment", "katz"), weighted = TRUE, top_n = NULL, exclude_existing = TRUE, include_self = FALSE, katz_damping = NULL )predict_links( x, methods = c("common_neighbors", "resource_allocation", "adamic_adar", "jaccard", "preferential_attachment", "katz"), weighted = TRUE, top_n = NULL, exclude_existing = TRUE, include_self = FALSE, katz_damping = NULL )
x |
A |
methods |
Character vector. One or more of:
|
weighted |
Logical. If |
top_n |
Integer or NULL. Return only the top N predictions per method.
Default: |
exclude_existing |
Logical. If |
include_self |
Logical. If |
katz_damping |
Numeric or NULL. Attenuation factor for Katz index.
If NULL, auto-computed as |
Number of shared neighbors. For directed graphs,
sums shared out-neighbors and shared in-neighbors.
Vectorized as A %*% t(A) + t(A) %*% A.
Zhou et al. (2009). Like common neighbors but
weights each shared neighbor z by 1/degree(z).
Penalizes hubs, rewards rare shared connections.
Adamic & Adar (2003). Like resource allocation but
weights by 1/log(degree(z)). Less aggressive penalty than RA.
Ratio of shared neighbors to total neighbors. For directed graphs, computed on combined (out+in) neighbor sets.
Product of source out-degree and target in-degree. Captures the "rich-get-richer" effect.
Katz (1953). Weighted sum of all paths between nodes,
exponentially damped by path length. Computed via matrix inversion:
(I - beta * A)^{-1} - I. Captures global structure.
An object of class "net_link_prediction" containing:
Data frame with columns: from, to, method, score, rank. Sorted by score (descending) within each method.
Named list of score matrices (one per method).
Character vector of methods used.
Character vector of node names.
Logical.
Logical.
Integer.
Integer. Number of existing edges.
Liben-Nowell, D. & Kleinberg, J. (2007). The link-prediction problem for social networks. JASIST, 58(7), 1019–1031.
Zhou, T., Lu, L. & Zhang, Y.-C. (2009). Network topology and link prediction. European Physical Journal B, 71, 623–630.
Adamic, L. A. & Adar, E. (2003). Friends and neighbors on the Web. Social Networks, 25(3), 211–230.
Katz, L. (1953). A new status index derived from sociometric analysis. Psychometrika, 18(1), 39–43.
evaluate_links for prediction evaluation,
build_network for network estimation.
seqs <- data.frame( V1 = sample(LETTERS[1:5], 50, TRUE), V2 = sample(LETTERS[1:5], 50, TRUE), V3 = sample(LETTERS[1:5], 50, TRUE) ) net <- build_network(seqs, method = "relative") pred <- predict_links(net) print(pred) summary(pred)seqs <- data.frame( V1 = sample(LETTERS[1:5], 50, TRUE), V2 = sample(LETTERS[1:5], 50, TRUE), V3 = sample(LETTERS[1:5], 50, TRUE) ) net <- build_network(seqs, method = "relative") pred <- predict_links(net) print(pred) summary(pred)
Computes the proportion of variance explained (R) for each node in
the network, following Haslbeck & Waldorp (2018).
For method = "glasso" or "pcor", predictability is computed
analytically from the precision matrix:
where is the precision (inverse correlation) matrix.
For method = "cor", predictability is the multiple R from
regressing each node on its network neighbors (nodes with non-zero edges).
predictability(object, ...) ## S3 method for class 'netobject' predictability(object, data = NULL, ...) ## S3 method for class 'netobject_ml' predictability(object, ...) ## S3 method for class 'netobject_group' predictability(object, ...)predictability(object, ...) ## S3 method for class 'netobject' predictability(object, data = NULL, ...) ## S3 method for class 'netobject_ml' predictability(object, ...) ## S3 method for class 'netobject_group' predictability(object, ...)
object |
A |
... |
Additional arguments (ignored). |
data |
Optional data frame of the original variables used to estimate
the network. Required for |
For netobject: a named numeric vector of R values
(one per node, between 0 and 1).
For netobject_ml: a list with elements $between and
$within, each a named numeric vector.
A named numeric vector of predictability values per node.
A list with within and between predictability vectors.
A named list of per-group predictability vectors.
Haslbeck, J. M. B., & Waldorp, L. J. (2018). How well do network models predict observations? On the importance of predictability in network models. Behavior Research Methods, 50(2), 853–861. doi:10.3758/s13428-017-0910-x
set.seed(42) mat <- matrix(rnorm(60), ncol = 4) colnames(mat) <- LETTERS[1:4] net <- build_network(as.data.frame(mat), method = "glasso") predictability(net)set.seed(42) mat <- matrix(rnorm(60), ncol = 4) colnames(mat) <- LETTERS[1:4] net <- build_network(as.data.frame(mat), method = "glasso") predictability(net)
Converts event log data (actor, action, time) into wide sequence format
suitable for build_network. Automatically parses timestamps,
detects sessions from time gaps, and handles tie-breaking.
prepare( data, actor, action, time = NULL, order = NULL, session = NULL, time_threshold = 900, custom_format = NULL, is_unix_time = FALSE, unix_time_unit = c("seconds", "milliseconds", "microseconds") )prepare( data, actor, action, time = NULL, order = NULL, session = NULL, time_threshold = 900, custom_format = NULL, is_unix_time = FALSE, unix_time_unit = c("seconds", "milliseconds", "microseconds") )
data |
Data frame with event log columns. |
actor |
Character or character vector. Column name(s) identifying who
performed the action (e.g. |
action |
Character. Column name containing the action/state/code. |
time |
Character or NULL. Column name containing timestamps. Supports ISO8601, Unix timestamps (numeric), and 40+ date/time formats. If NULL, row order defines the sequence. Default: NULL. |
order |
Character or NULL. Column name for tie-breaking when timestamps are identical. If NULL, original row order is used. Default: NULL. |
session |
Character, character vector, or NULL. Column name(s) for
explicit session grouping (e.g. |
time_threshold |
Numeric. Maximum gap in seconds between consecutive
events before a new session starts. Only used when |
custom_format |
Character or NULL. Custom |
is_unix_time |
Logical. If TRUE, treat numeric time values as Unix timestamps. Default: FALSE (auto-detected for numeric columns). |
unix_time_unit |
Character. Unit for Unix timestamps:
|
A list with class "nestimate_data" containing:
Data frame in wide format (one row per session, columns T1, T2, ...).
The processed long-format data with session IDs.
Session-level metadata (session ID, actor).
Parsed time values in wide format (if time provided).
List with total_sessions, total_actions, max_sequence_length, unique_actors, etc.
df <- data.frame( student = rep(1:3, each = 5), code = sample(c("read", "write", "test"), 15, replace = TRUE), timestamp = seq.POSIXt(as.POSIXct("2024-01-01"), by = "min", length.out = 15) ) prepared <- prepare(df, actor = "student", action = "code", time = "timestamp") net <- build_network(prepared$sequence_data, method = "relative")df <- data.frame( student = rep(1:3, each = 5), code = sample(c("read", "write", "test"), 15, replace = TRUE), timestamp = seq.POSIXt(as.POSIXct("2024-01-01"), by = "min", length.out = 15) ) prepared <- prepare(df, actor = "student", action = "code", time = "timestamp") net <- build_network(prepared$sequence_data, method = "relative")
Prepare simulated or real data for use with tna::tna() and related
functions. Handles various input formats and ensures the output is
compatible with TNA models.
prepare_for_tna( data, type = c("sequences", "long", "auto"), state_names = NULL, id_col = "Actor", time_col = "Time", action_col = "Action", validate = TRUE )prepare_for_tna( data, type = c("sequences", "long", "auto"), state_names = NULL, id_col = "Actor", time_col = "Time", action_col = "Action", validate = TRUE )
data |
Data frame containing sequence data. |
type |
Character. Type of input data:
|
state_names |
Character vector. Expected state names, or NULL to extract from data. Default: NULL. |
id_col |
Character. Name of ID column for long format data. Default: "Actor". |
time_col |
Character. Name of time column for long format data. Default: "Time". |
action_col |
Character. Name of action column for long format data. Default: "Action". |
validate |
Logical. Whether to validate that all actions are in state_names. Default: TRUE. |
This function performs several preparations:
Converts long format to wide format if needed.
Validates that all actions/states are recognized.
Removes any non-sequence columns (e.g., id, metadata).
Converts factors to characters.
Ensures consistent column naming (V1, V2, ...).
A data frame ready for use with TNA functions. For "sequences" type, returns a data frame where each row is a sequence and columns are time points (V1, V2, ...). For "long" type, converts to wide format first.
wide_to_long, long_to_wide for
format conversions.
# From wide format sequences sequences <- data.frame( V1 = c("A","B","C","A"), V2 = c("B","C","A","B"), V3 = c("C","A","B","C"), V4 = c("A","B","A","B") ) tna_data <- prepare_for_tna(sequences, type = "sequences")# From wide format sequences sequences <- data.frame( V1 = c("A","B","C","A"), V2 = c("B","C","A","B"), V3 = c("C","A","B","C"), V4 = c("A","B","A","B") ) tna_data <- prepare_for_tna(sequences, type = "sequences")
Converts binary indicator (one-hot) data into the wide sequence format
expected by build_network and tna::tna(). Each binary
column represents a state; rows where the value is 1 are marked with the
column name. Supports optional windowed aggregation.
Simultaneous active states are preserved using the same window-span
representation as tna::import_onehot(): each input row/window is
expanded to one sequence slot per code and transition counting occurs between
windows, not between simultaneous states inside the same row.
prepare_onehot( data, cols, actor = NULL, session = NULL, interval = NULL, window_size = 3L, window_type = c("non-overlapping", "overlapping"), aggregate = FALSE )prepare_onehot( data, cols, actor = NULL, session = NULL, interval = NULL, window_size = 3L, window_type = c("non-overlapping", "overlapping"), aggregate = FALSE )
data |
Data frame with binary (0/1) indicator columns. |
cols |
Character vector. Names of the one-hot columns to use. |
actor |
Character or NULL. Name of the actor/ID column. If NULL, all rows are treated as a single sequence. Default: NULL. |
session |
Character or NULL. Name of the session column for sub-grouping within actors. Default: NULL. |
interval |
Integer or NULL. Number of rows per time point in the output. If NULL, all rows become a single time point group. Default: NULL. |
window_size |
Integer (>= 1). Number of consecutive rows to aggregate
into each window. Default: 3. Set |
window_type |
Character. |
aggregate |
Logical. If TRUE, aggregate within each window by taking the first non-NA indicator per column. Default: FALSE. |
A data frame in wide format with columns named
W{window}_T{time} where each cell contains a state name or NA.
Attributes windowed, window_size, window_span
are set on the result.
action_to_onehot for the reverse conversion.
# Simple binary data df <- data.frame( A = c(1, 0, 1, 0, 1), B = c(0, 1, 0, 1, 0), C = c(0, 0, 0, 0, 0) ) seq_data <- prepare_onehot(df, cols = c("A", "B", "C")) # With actor grouping df$actor <- c(1, 1, 1, 2, 2) seq_data <- prepare_onehot(df, cols = c("A", "B", "C"), actor = "actor") # With windowing seq_data <- prepare_onehot(df, cols = c("A", "B", "C"), window_size = 2, window_type = "non-overlapping")# Simple binary data df <- data.frame( A = c(1, 0, 1, 0, 1), B = c(0, 1, 0, 1, 0), C = c(0, 0, 0, 0, 0) ) seq_data <- prepare_onehot(df, cols = c("A", "B", "C")) # With actor grouping df$actor <- c(1, 1, 1, 2, 2) seq_data <- prepare_onehot(df, cols = c("A", "B", "C"), actor = "actor") # With windowing seq_data <- prepare_onehot(df, cols = c("A", "B", "C"), window_size = 2, window_type = "non-overlapping")
Print Method for boot_glasso
## S3 method for class 'boot_glasso' print(x, ...)## S3 method for class 'boot_glasso' print(x, ...)
x |
A |
... |
Additional arguments (ignored). |
The input object, invisibly.
set.seed(1) dat <- as.data.frame(matrix(rnorm(60), ncol = 3)) bg <- boot_glasso(dat, iter = 10, cs_iter = 5, centrality = "strength") print(bg) set.seed(42) mat <- matrix(rnorm(60), ncol = 4) colnames(mat) <- LETTERS[1:4] boot <- boot_glasso(as.data.frame(mat), iter = 20, cs_iter = 10, centrality = "strength", seed = 42) print(boot)set.seed(1) dat <- as.data.frame(matrix(rnorm(60), ncol = 3)) bg <- boot_glasso(dat, iter = 10, cs_iter = 5, centrality = "strength") print(bg) set.seed(42) mat <- matrix(rnorm(60), ncol = 4) colnames(mat) <- LETTERS[1:4] boot <- boot_glasso(as.data.frame(mat), iter = 20, cs_iter = 10, centrality = "strength", seed = 42) print(boot)
chain_structure.Prints a compact chain-level header. For the full per-state table,
call summary() on the same object.
## S3 method for class 'chain_structure' print(x, ...)## S3 method for class 'chain_structure' print(x, ...)
x |
A |
... |
Ignored. |
x invisibly.
chain_structure_group.One header line per group, followed by each group's per-state
table (via summary.chain_structure).
## S3 method for class 'chain_structure_group' print(x, ...)## S3 method for class 'chain_structure_group' print(x, ...)
x |
A |
... |
Forwarded to |
x invisibly.
Print Method for cluster_choice
## S3 method for class 'cluster_choice' print(x, digits = 3L, ...)## S3 method for class 'cluster_choice' print(x, digits = 3L, ...)
x |
A |
digits |
Integer. Decimal places for floating-point columns.
Default |
... |
Unsupported. Supplying unused arguments raises an error. |
The input object, invisibly.
Print Method for mcml
## S3 method for class 'mcml' print(x, ...)## S3 method for class 'mcml' print(x, ...)
x |
An |
... |
Unsupported. Supplying unused arguments raises an error. |
The input object, invisibly.
seqs <- data.frame(V1 = c("A","B","C","A"), V2 = c("B","C","A","B")) clusters <- list(G1 = c("A","B"), G2 = c("C")) cs <- build_mcml(seqs, clusters) print(cs) seqs <- data.frame( T1 = c("A","B","A"), T2 = c("B","C","B"), T3 = c("C","A","C"), T4 = c("A","B","A") ) clusters <- c("Alpha", "Beta", "Alpha") cs <- build_mcml(seqs, clusters, type = "raw") print(cs)seqs <- data.frame(V1 = c("A","B","C","A"), V2 = c("B","C","A","B")) clusters <- list(G1 = c("A","B"), G2 = c("C")) cs <- build_mcml(seqs, clusters) print(cs) seqs <- data.frame( T1 = c("A","B","A"), T2 = c("B","C","B"), T3 = c("C","A","C"), T4 = c("A","B","A") ) clusters <- c("Alpha", "Beta", "Alpha") cs <- build_mcml(seqs, clusters, type = "raw") print(cs)
Compact summary of one mcml layer (macro or a single within-cluster
network) – nodes, edges, weight matrix dimensions – without spilling
the full $weights, $inits, or $data contents.
## S3 method for class 'mcml_layer' print(x, ...)## S3 method for class 'mcml_layer' print(x, ...)
x |
An |
... |
Unused. |
The input, invisibly.
Print Method for mmm_compare
## S3 method for class 'mmm_compare' print(x, ...)## S3 method for class 'mmm_compare' print(x, ...)
x |
An |
... |
Unsupported. Supplying unused arguments raises an error. |
The input object, invisibly.
seqs <- data.frame(V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE)) cmp <- compare_mmm(seqs, k = 2:3, n_starts = 1, max_iter = 10, seed = 1) print(cmp) set.seed(1) seqs <- data.frame( V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE), V3 = sample(c("A","B","C"), 30, TRUE) ) cmp <- compare_mmm(seqs, k = 2:3, n_starts = 5, seed = 1) print(cmp)seqs <- data.frame(V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE)) cmp <- compare_mmm(seqs, k = 2:3, n_starts = 1, max_iter = 10, seed = 1) print(cmp) set.seed(1) seqs <- data.frame( V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE), V3 = sample(c("A","B","C"), 30, TRUE) ) cmp <- compare_mmm(seqs, k = 2:3, n_starts = 5, seed = 1) print(cmp)
Print Method for nestimate_data
## S3 method for class 'nestimate_data' print(x, ...)## S3 method for class 'nestimate_data' print(x, ...)
x |
A |
... |
Additional arguments (ignored). |
The input object, invisibly.
events <- data.frame( actor = c("u1","u1","u1","u2","u2","u2"), action = c("A","B","C","B","A","C"), time = c(1,2,3,1,2,3) ) nd <- prepare(events, action = "action", actor = "actor", time = "time") print(nd)events <- data.frame( actor = c("u1","u1","u1","u2","u2","u2"), action = c("A","B","C","B","A","C"), time = c(1,2,3,1,2,3) ) nd <- prepare(events, action = "action", actor = "actor", time = "time") print(nd)
Print Method for net_association_rules
## S3 method for class 'net_association_rules' print(x, ...)## S3 method for class 'net_association_rules' print(x, ...)
x |
A |
... |
Additional arguments (ignored). |
The input object, invisibly.
trans <- list(c("A","B","C"), c("A","B"), c("B","C","D"), c("A","C","D")) rules <- association_rules(trans, min_support = 0.3, min_confidence = 0.5, min_lift = 0) print(rules)trans <- list(c("A","B","C"), c("A","B"), c("B","C","D"), c("A","C","D")) rules <- association_rules(trans, min_support = 0.3, min_confidence = 0.5, min_lift = 0) print(rules)
Print Method for net_bootstrap
## S3 method for class 'net_bootstrap' print(x, ...)## S3 method for class 'net_bootstrap' print(x, ...)
x |
A |
... |
Additional arguments (ignored). |
The input object, invisibly.
net <- build_network(data.frame(V1 = c("A","B","C"), V2 = c("B","C","A")), method = "relative") boot <- bootstrap_network(net, iter = 10) print(boot) set.seed(1) seqs <- data.frame( V1 = c("A","B","A","C","B"), V2 = c("B","C","B","A","C"), V3 = c("C","A","C","B","A") ) net <- build_network(seqs, method = "relative") boot <- bootstrap_network(net, iter = 20) print(boot)net <- build_network(data.frame(V1 = c("A","B","C"), V2 = c("B","C","A")), method = "relative") boot <- bootstrap_network(net, iter = 10) print(boot) set.seed(1) seqs <- data.frame( V1 = c("A","B","A","C","B"), V2 = c("B","C","B","A","C"), V3 = c("C","A","C","B","A") ) net <- build_network(seqs, method = "relative") boot <- bootstrap_network(net, iter = 20) print(boot)
Print Method for net_bootstrap_group
## S3 method for class 'net_bootstrap_group' print(x, ...)## S3 method for class 'net_bootstrap_group' print(x, ...)
x |
A |
... |
Ignored. |
x invisibly.
seqs <- data.frame(V1 = c("A","B","A","C"), V2 = c("B","C","C","A"), V3 = c("C","A","B","B"), grp = c("X","X","Y","Y")) nets <- build_network(seqs, method = "relative", group = "grp") boot <- bootstrap_network(nets, iter = 10) print(boot) set.seed(1) seqs <- data.frame( V1 = c("A","B","A","C","B","A"), V2 = c("B","C","B","A","C","B"), V3 = c("C","A","C","B","A","C"), grp = c("X","X","X","Y","Y","Y") ) nets <- build_network(seqs, method = "relative", group = "grp") boot <- bootstrap_network(nets, iter = 20) print(boot)seqs <- data.frame(V1 = c("A","B","A","C"), V2 = c("B","C","C","A"), V3 = c("C","A","B","B"), grp = c("X","X","Y","Y")) nets <- build_network(seqs, method = "relative", group = "grp") boot <- bootstrap_network(nets, iter = 10) print(boot) set.seed(1) seqs <- data.frame( V1 = c("A","B","A","C","B","A"), V2 = c("B","C","B","A","C","B"), V3 = c("C","A","C","B","A","C"), grp = c("X","X","X","Y","Y","Y") ) nets <- build_network(seqs, method = "relative", group = "grp") boot <- bootstrap_network(nets, iter = 20) print(boot)
Prints a uniform header, family-specific quality / IC line, and a
per-cluster table. Layout matches print.net_clustering
and print.net_mmm.
## S3 method for class 'net_cluster_diagnostics' print(x, digits = 3L, ...)## S3 method for class 'net_cluster_diagnostics' print(x, digits = 3L, ...)
x |
A |
digits |
Integer. Decimal places for floating-point statistics.
Default |
... |
Unsupported. Supplying unused arguments raises an error. |
The input object, invisibly.
Compact, fixed-width summary of a sequence-clustering result. The header carries the clustering method and dissimilarity; the per-cluster table carries cluster size (count and percentage) and mean within-cluster distance when available. Optional medoid and covariate lines surface only when those fields are populated.
## S3 method for class 'net_clustering' print(x, digits = 3L, ...)## S3 method for class 'net_clustering' print(x, digits = 3L, ...)
x |
A |
digits |
Integer. Decimal places used for floating-point statistics
in the printout. Default |
... |
Unsupported. Supplying unused arguments raises an error. |
The input object, invisibly.
seqs <- data.frame(V1 = c("A","B","C","A","B"), V2 = c("B","C","A","B","A"), V3 = c("C","A","B","C","B")) cl <- build_clusters(seqs, k = 2) print(cl) set.seed(1) seqs <- data.frame( V1 = sample(c("A","B","C"), 20, TRUE), V2 = sample(c("A","B","C"), 20, TRUE), V3 = sample(c("A","B","C"), 20, TRUE) ) cl <- build_clusters(seqs, k = 2) print(cl)seqs <- data.frame(V1 = c("A","B","C","A","B"), V2 = c("B","C","A","B","A"), V3 = c("C","A","B","C","B")) cl <- build_clusters(seqs, k = 2) print(cl) set.seed(1) seqs <- data.frame( V1 = sample(c("A","B","C"), 20, TRUE), V2 = sample(c("A","B","C"), 20, TRUE), V3 = sample(c("A","B","C"), 20, TRUE) ) cl <- build_clusters(seqs, k = 2) print(cl)
Print Method for net_gimme
## S3 method for class 'net_gimme' print(x, ...)## S3 method for class 'net_gimme' print(x, ...)
x |
A |
... |
Additional arguments (ignored). |
The input object, invisibly.
set.seed(1) panel <- data.frame( id = rep(1:5, each = 20), t = rep(seq_len(20), 5), A = rnorm(100), B = rnorm(100), C = rnorm(100) ) gm <- build_gimme(panel, vars = c("A","B","C"), id = "id", time = "t") print(gm)set.seed(1) panel <- data.frame( id = rep(1:5, each = 20), t = rep(seq_len(20), 5), A = rnorm(100), B = rnorm(100), C = rnorm(100) ) gm <- build_gimme(panel, vars = c("A","B","C"), id = "id", time = "t") print(gm)
Print Method for net_hon
## S3 method for class 'net_hon' print(x, ...)## S3 method for class 'net_hon' print(x, ...)
x |
A |
... |
Additional arguments (ignored). |
The input object, invisibly.
seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) hon <- build_hon(seqs, max_order = 2) print(hon) seqs <- data.frame( V1 = c("A","B","C","A","B"), V2 = c("B","C","A","B","C"), V3 = c("C","A","B","C","A") ) hon <- build_hon(seqs, max_order = 2L) print(hon)seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) hon <- build_hon(seqs, max_order = 2) print(hon) seqs <- data.frame( V1 = c("A","B","C","A","B"), V2 = c("B","C","A","B","C"), V3 = c("C","A","B","C","A") ) hon <- build_hon(seqs, max_order = 2L) print(hon)
Print Method for net_honem
## S3 method for class 'net_honem' print(x, ...)## S3 method for class 'net_honem' print(x, ...)
x |
A |
... |
Additional arguments (ignored). |
The input object, invisibly.
seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) hem <- build_honem(build_hon(seqs, max_order = 2), dim = 2) print(hem) seqs <- data.frame( V1 = c("A","B","C","A","B"), V2 = c("B","C","A","B","C"), V3 = c("C","A","B","C","A") ) hon <- build_hon(seqs, max_order = 2L) honem <- build_honem(hon, dim = 2L) print(honem)seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) hem <- build_honem(build_hon(seqs, max_order = 2), dim = 2) print(hem) seqs <- data.frame( V1 = c("A","B","C","A","B"), V2 = c("B","C","A","B","C"), V3 = c("C","A","B","C","A") ) hon <- build_hon(seqs, max_order = 2L) honem <- build_honem(hon, dim = 2L) print(honem)
Print Method for net_hypa
## S3 method for class 'net_hypa' print(x, ...)## S3 method for class 'net_hypa' print(x, ...)
x |
A |
... |
Additional arguments (ignored). |
The input object, invisibly.
seqs <- list(c("A","B","C"), c("B","C","A"), c("A","C","B"), c("A","B","C")) hyp <- build_hypa(seqs, k = 2) print(hyp) seqs <- data.frame( V1 = c("A","B","C","A","B","C","A","B","C","A"), V2 = c("B","C","A","B","C","A","B","C","A","B"), V3 = c("C","A","B","C","A","B","C","A","B","C"), V4 = c("A","B","C","A","B","C","A","B","C","A") ) hypa <- build_hypa(seqs, k = 2L) print(hypa)seqs <- list(c("A","B","C"), c("B","C","A"), c("A","C","B"), c("A","B","C")) hyp <- build_hypa(seqs, k = 2) print(hyp) seqs <- data.frame( V1 = c("A","B","C","A","B","C","A","B","C","A"), V2 = c("B","C","A","B","C","A","B","C","A","B"), V3 = c("C","A","B","C","A","B","C","A","B","C"), V4 = c("A","B","C","A","B","C","A","B","C","A") ) hypa <- build_hypa(seqs, k = 2L) print(hypa)
Print Method for net_link_prediction
## S3 method for class 'net_link_prediction' print(x, ...)## S3 method for class 'net_link_prediction' print(x, ...)
x |
A |
... |
Additional arguments (ignored). |
The input object, invisibly.
seqs <- data.frame( V1 = sample(LETTERS[1:4], 30, TRUE), V2 = sample(LETTERS[1:4], 30, TRUE), V3 = sample(LETTERS[1:4], 30, TRUE) ) net <- build_network(seqs, method = "relative") pred <- predict_links(net) print(pred)seqs <- data.frame( V1 = sample(LETTERS[1:4], 30, TRUE), V2 = sample(LETTERS[1:4], 30, TRUE), V3 = sample(LETTERS[1:4], 30, TRUE) ) net <- build_network(seqs, method = "relative") pred <- predict_links(net) print(pred)
Print Method for net_markov_order
## S3 method for class 'net_markov_order' print(x, ...)## S3 method for class 'net_markov_order' print(x, ...)
x |
A |
... |
Ignored. |
The input object, invisibly.
# First-order Markov data: test should select order 1 set.seed(1) states <- letters[1:4] tm <- matrix(runif(16), 4, 4, dimnames = list(states, states)) tm <- tm / rowSums(tm) seqs <- lapply(1:30, function(.) { s <- character(50); s[1] <- sample(states, 1) for (i in 2:50) s[i] <- sample(states, 1, prob = tm[s[i - 1], ]) s }) res <- markov_order_test(seqs, max_order = 3, n_perm = 300, seed = 1) res$optimal_order summary(res) plot(res)# First-order Markov data: test should select order 1 set.seed(1) states <- letters[1:4] tm <- matrix(runif(16), 4, 4, dimnames = list(states, states)) tm <- tm / rowSums(tm) seqs <- lapply(1:30, function(.) { s <- character(50); s[1] <- sample(states, 1) for (i in 2:50) s[i] <- sample(states, 1, prob = tm[s[i - 1], ]) s }) res <- markov_order_test(seqs, max_order = 3, n_perm = 300, seed = 1) res$optimal_order summary(res) plot(res)
net_markov_order_group
Print method for net_markov_order_group
## S3 method for class 'net_markov_order_group' print(x, ...)## S3 method for class 'net_markov_order_group' print(x, ...)
x |
A |
... |
Forwarded to |
x invisibly.
net_markov_stability_group
Print method for net_markov_stability_group
## S3 method for class 'net_markov_stability_group' print(x, ...)## S3 method for class 'net_markov_stability_group' print(x, ...)
x |
A |
... |
Forwarded to |
x invisibly.
Print method for net_mlvar
## S3 method for class 'net_mlvar' print(x, ...)## S3 method for class 'net_mlvar' print(x, ...)
x |
A |
... |
Unused; present for S3 consistency. |
Invisibly returns x.
## Not run: d <- simulate_data("mlvar", seed = 1) fit <- build_mlvar(d, vars = attr(d, "vars"), id = "id", day = "day", beep = "beep") print(fit) summary(fit) ## End(Not run)## Not run: d <- simulate_data("mlvar", seed = 1) fit <- build_mlvar(d, vars = attr(d, "vars"), id = "id", day = "day", beep = "beep") print(fit) summary(fit) ## End(Not run)
Compact summary of a Mixed Markov Model fit. Header carries dimensions
and information criteria; cluster table carries N, mixing share, and
per-cluster average posterior probability (AvePP). Layout matches
print.net_clustering so distance- and model-based
clusterings can be compared at a glance.
## S3 method for class 'net_mmm' print(x, digits = 3L, ...)## S3 method for class 'net_mmm' print(x, digits = 3L, ...)
x |
A |
digits |
Integer. Decimal places for floating-point statistics.
Default |
... |
Unsupported. Supplying unused arguments raises an error. |
The input object, invisibly.
seqs <- data.frame(V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE)) mmm <- build_mmm(seqs, k = 2, n_starts = 1, max_iter = 10, seed = 1) print(mmm) set.seed(1) seqs <- data.frame( V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE), V3 = sample(c("A","B","C"), 30, TRUE) ) mmm <- build_mmm(seqs, k = 2, n_starts = 5, seed = 1) print(mmm)seqs <- data.frame(V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE)) mmm <- build_mmm(seqs, k = 2, n_starts = 1, max_iter = 10, seed = 1) print(mmm) set.seed(1) seqs <- data.frame( V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE), V3 = sample(c("A","B","C"), 30, TRUE) ) mmm <- build_mmm(seqs, k = 2, n_starts = 5, seed = 1) print(mmm)
Prints the clustering metadata that cluster_mmm attaches
to its netobject_group return value (attr(grp, "clustering")).
Layout mirrors print.net_clustering: a one-line dimension
header, a quality line with AvePP / entropy / classification error,
information criteria, and a per-cluster table.
## S3 method for class 'net_mmm_clustering' print(x, digits = 3L, ...)## S3 method for class 'net_mmm_clustering' print(x, digits = 3L, ...)
x |
A |
digits |
Integer. Decimal places for floating-point statistics.
Default |
... |
Unsupported. Supplying unused arguments raises an error. |
The input object, invisibly.
seqs <- data.frame(V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE)) grp <- cluster_mmm(seqs, k = 2, n_starts = 1, max_iter = 10, seed = 1) print(attr(grp, "clustering"))seqs <- data.frame(V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE)) grp <- cluster_mmm(seqs, k = 2, n_starts = 1, max_iter = 10, seed = 1) print(attr(grp, "clustering"))
Print Method for net_mogen
## S3 method for class 'net_mogen' print(x, ...)## S3 method for class 'net_mogen' print(x, ...)
x |
A |
... |
Additional arguments (ignored). |
The input object, invisibly.
seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) mg <- build_mogen(seqs, max_order = 2) print(mg) seqs <- data.frame( V1 = c("A","B","C","A","B"), V2 = c("B","C","A","B","C"), V3 = c("C","A","B","C","A") ) mog <- build_mogen(seqs, max_order = 2L) print(mog)seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) mg <- build_mogen(seqs, max_order = 2) print(mg) seqs <- data.frame( V1 = c("A","B","C","A","B"), V2 = c("B","C","A","B","C"), V3 = c("C","A","B","C","A") ) mog <- build_mogen(seqs, max_order = 2L) print(mog)
net_mpt_group
Print method for net_mpt_group
## S3 method for class 'net_mpt_group' print(x, ...)## S3 method for class 'net_mpt_group' print(x, ...)
x |
A |
... |
Forwarded to |
x invisibly.
Print Method for net_nct
## S3 method for class 'net_nct' print(x, ...)## S3 method for class 'net_nct' print(x, ...)
x |
A |
... |
Ignored. |
The input object, invisibly.
## Not run: set.seed(1) x1 <- matrix(rnorm(200 * 5), 200, 5) x2 <- matrix(rnorm(200 * 5), 200, 5) colnames(x1) <- colnames(x2) <- paste0("V", 1:5) res <- nct(x1, x2, iter = 100) res$M$p_value res$S$p_value ## End(Not run)## Not run: set.seed(1) x1 <- matrix(rnorm(200 * 5), 200, 5) x2 <- matrix(rnorm(200 * 5), 200, 5) colnames(x1) <- colnames(x2) <- paste0("V", 1:5) res <- nct(x1, x2, iter = 100) res$M$p_value res$S$p_value ## End(Not run)
net_path_dependence
Print method for net_path_dependence
## S3 method for class 'net_path_dependence' print(x, top = 10L, digits = 3L, ...)## S3 method for class 'net_path_dependence' print(x, top = 10L, digits = 3L, ...)
x |
A |
top |
Integer. Number of top contexts to show. Default 10. |
digits |
Integer. Digits to round numeric output. Default 3. |
... |
Ignored. |
x invisibly.
Print Method for net_permutation
## S3 method for class 'net_permutation' print(x, ...)## S3 method for class 'net_permutation' print(x, ...)
x |
A |
... |
Additional arguments (ignored). |
The input object, invisibly.
s1 <- data.frame(V1 = c("A","B","C"), V2 = c("B","C","A")) s2 <- data.frame(V1 = c("A","C","B"), V2 = c("C","B","A")) n1 <- build_network(s1, method = "relative") n2 <- build_network(s2, method = "relative") perm <- permutation(n1, n2, iter = 10) print(perm) set.seed(1) d1 <- data.frame(V1 = c("A","B","A"), V2 = c("B","C","B"), V3 = c("C","A","C")) d2 <- data.frame(V1 = c("C","A","C"), V2 = c("A","B","A"), V3 = c("B","C","B")) net1 <- build_network(d1, method = "relative") net2 <- build_network(d2, method = "relative") perm <- permutation(net1, net2, iter = 20, seed = 1) print(perm)s1 <- data.frame(V1 = c("A","B","C"), V2 = c("B","C","A")) s2 <- data.frame(V1 = c("A","C","B"), V2 = c("C","B","A")) n1 <- build_network(s1, method = "relative") n2 <- build_network(s2, method = "relative") perm <- permutation(n1, n2, iter = 10) print(perm) set.seed(1) d1 <- data.frame(V1 = c("A","B","A"), V2 = c("B","C","B"), V3 = c("C","A","C")) d2 <- data.frame(V1 = c("C","A","C"), V2 = c("A","B","A"), V3 = c("B","C","B")) net1 <- build_network(d1, method = "relative") net2 <- build_network(d2, method = "relative") perm <- permutation(net1, net2, iter = 20, seed = 1) print(perm)
Print Method for net_permutation_group
## S3 method for class 'net_permutation_group' print(x, ...)## S3 method for class 'net_permutation_group' print(x, ...)
x |
A |
... |
Additional arguments (ignored). |
x invisibly.
s1 <- data.frame(V1 = c("A","B","A","C"), V2 = c("B","C","B","A"), V3 = c("C","A","C","B"), grp = c("X","X","Y","Y")) s2 <- data.frame(V1 = c("C","A","C","B"), V2 = c("A","B","A","C"), V3 = c("B","C","B","A"), grp = c("X","X","Y","Y")) nets1 <- build_network(s1, method = "relative", group = "grp") nets2 <- build_network(s2, method = "relative", group = "grp") perm <- permutation(nets1, nets2, iter = 10) print(perm) set.seed(1) s1 <- data.frame(V1 = c("A","B","A","C"), V2 = c("B","C","B","A"), V3 = c("C","A","C","B"), grp = c("X","X","Y","Y")) s2 <- data.frame(V1 = c("C","A","C","B"), V2 = c("A","B","A","C"), V3 = c("B","C","B","A"), grp = c("X","X","Y","Y")) nets1 <- build_network(s1, method = "relative", group = "grp") nets2 <- build_network(s2, method = "relative", group = "grp") perm <- permutation(nets1, nets2, iter = 20, seed = 1) print(perm)s1 <- data.frame(V1 = c("A","B","A","C"), V2 = c("B","C","B","A"), V3 = c("C","A","C","B"), grp = c("X","X","Y","Y")) s2 <- data.frame(V1 = c("C","A","C","B"), V2 = c("A","B","A","C"), V3 = c("B","C","B","A"), grp = c("X","X","Y","Y")) nets1 <- build_network(s1, method = "relative", group = "grp") nets2 <- build_network(s2, method = "relative", group = "grp") perm <- permutation(nets1, nets2, iter = 10) print(perm) set.seed(1) s1 <- data.frame(V1 = c("A","B","A","C"), V2 = c("B","C","B","A"), V3 = c("C","A","C","B"), grp = c("X","X","Y","Y")) s2 <- data.frame(V1 = c("C","A","C","B"), V2 = c("A","B","A","C"), V3 = c("B","C","B","A"), grp = c("X","X","Y","Y")) nets1 <- build_network(s1, method = "relative", group = "grp") nets2 <- build_network(s2, method = "relative", group = "grp") perm <- permutation(nets1, nets2, iter = 20, seed = 1) print(perm)
Print Method for net_reliability
## S3 method for class 'net_reliability' print(x, ...)## S3 method for class 'net_reliability' print(x, ...)
x |
A |
... |
Additional arguments (ignored). |
The input object, invisibly.
net <- build_network(data.frame(V1 = c("A","B","C","A"), V2 = c("B","C","A","B")), method = "relative") rel <- network_reliability(net, iter = 10) print(rel) set.seed(1) seqs <- data.frame( V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE), V3 = sample(c("A","B","C"), 30, TRUE) ) net <- build_network(seqs, method = "relative") rel <- network_reliability(net, iter = 20, seed = 1) print(rel)net <- build_network(data.frame(V1 = c("A","B","C","A"), V2 = c("B","C","A","B")), method = "relative") rel <- network_reliability(net, iter = 10) print(rel) set.seed(1) seqs <- data.frame( V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE), V3 = sample(c("A","B","C"), 30, TRUE) ) net <- build_network(seqs, method = "relative") rel <- network_reliability(net, iter = 20, seed = 1) print(rel)
Print Method for net_sequence_comparison
## S3 method for class 'net_sequence_comparison' print(x, ...)## S3 method for class 'net_sequence_comparison' print(x, ...)
x |
A |
... |
Additional arguments (ignored). |
The input object, invisibly.
seqs <- data.frame( V1 = sample(LETTERS[1:4], 60, TRUE), V2 = sample(LETTERS[1:4], 60, TRUE), V3 = sample(LETTERS[1:4], 60, TRUE), V4 = sample(LETTERS[1:4], 60, TRUE) ) grp <- rep(c("X", "Y"), 30) net <- build_network(seqs, method = "relative") res <- sequence_compare(net, group = grp, sub = 2:3, test = "chisq")seqs <- data.frame( V1 = sample(LETTERS[1:4], 60, TRUE), V2 = sample(LETTERS[1:4], 60, TRUE), V3 = sample(LETTERS[1:4], 60, TRUE), V4 = sample(LETTERS[1:4], 60, TRUE) ) grp <- rep(c("X", "Y"), 30) net <- build_network(seqs, method = "relative") res <- sequence_compare(net, group = grp, sub = 2:3, test = "chisq")
Print Method for net_stability
## S3 method for class 'net_stability' print(x, ...)## S3 method for class 'net_stability' print(x, ...)
x |
A |
... |
Additional arguments (ignored). |
The input object, invisibly.
net <- build_network(data.frame(V1 = c("A","B","C","A"), V2 = c("B","C","A","B")), method = "relative") cs <- centrality_stability(net, iter = 10, drop_prop = 0.3) print(cs) set.seed(1) seqs <- data.frame( V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE), V3 = sample(c("A","B","C"), 30, TRUE) ) net <- build_network(seqs, method = "relative") stab <- centrality_stability(net, measures = c("InStrength","OutStrength"), iter = 10) print(stab)net <- build_network(data.frame(V1 = c("A","B","C","A"), V2 = c("B","C","A","B")), method = "relative") cs <- centrality_stability(net, iter = 10, drop_prop = 0.3) print(cs) set.seed(1) seqs <- data.frame( V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE), V3 = sample(c("A","B","C"), 30, TRUE) ) net <- build_network(seqs, method = "relative") stab <- centrality_stability(net, measures = c("InStrength","OutStrength"), iter = 10) print(stab)
Print Method for net_stability_group
## S3 method for class 'net_stability_group' print(x, ...)## S3 method for class 'net_stability_group' print(x, ...)
x |
A |
... |
Additional arguments (ignored). |
The input x invisibly.
net_transition_entropy
Print method for net_transition_entropy
## S3 method for class 'net_transition_entropy' print(x, digits = 3, ...)## S3 method for class 'net_transition_entropy' print(x, digits = 3, ...)
x |
A |
digits |
Integer. Digits to round numeric output. Default |
... |
Ignored. |
x invisibly.
net_transition_entropy_group
Print method for net_transition_entropy_group
## S3 method for class 'net_transition_entropy_group' print(x, ...)## S3 method for class 'net_transition_entropy_group' print(x, ...)
x |
A |
... |
Forwarded to |
x invisibly.
Print Method for Network Object
## S3 method for class 'netobject' print(x, ...)## S3 method for class 'netobject' print(x, ...)
x |
A |
... |
Additional arguments (ignored). |
The input object, invisibly.
seqs <- data.frame(V1 = c("A","B","C","A"), V2 = c("B","C","A","B")) net <- build_network(seqs, method = "relative") print(net) seqs <- data.frame( V1 = c("A","B","A","C"), V2 = c("B","C","B","A"), V3 = c("C","A","C","B") ) net <- build_network(seqs, method = "relative") print(net)seqs <- data.frame(V1 = c("A","B","C","A"), V2 = c("B","C","A","B")) net <- build_network(seqs, method = "relative") print(net) seqs <- data.frame( V1 = c("A","B","A","C"), V2 = c("B","C","B","A"), V3 = c("C","A","C","B") ) net <- build_network(seqs, method = "relative") print(net)
Compact summary of a netobject_group. Header surfaces the source
(a clustering attached by cluster_network or
cluster_mmm, or a plain split by group_col). The
per-group table carries node and edge counts, weight range, and – when
a clustering attribute is present – N and percentage of sequences per
cluster (matching the layout used by print.net_clustering
and print.net_mmm).
## S3 method for class 'netobject_group' print(x, digits = 3L, ...)## S3 method for class 'netobject_group' print(x, digits = 3L, ...)
x |
A |
digits |
Integer. Decimal places for the weight summary. Default
|
... |
Additional arguments (ignored). |
The input object, invisibly.
seqs <- data.frame(V1 = c("A","B","A","B"), V2 = c("B","A","B","A"), grp = c("X","X","Y","Y")) nets <- build_network(seqs, method = "relative", group = "grp") print(nets) seqs <- data.frame( V1 = c("A","B","A","C","B","A"), V2 = c("B","C","B","A","C","B"), V3 = c("C","A","C","B","A","C"), grp = c("X","X","X","Y","Y","Y") ) nets <- build_network(seqs, method = "relative", group = "grp") print(nets)seqs <- data.frame(V1 = c("A","B","A","B"), V2 = c("B","A","B","A"), grp = c("X","X","Y","Y")) nets <- build_network(seqs, method = "relative", group = "grp") print(nets) seqs <- data.frame( V1 = c("A","B","A","C","B","A"), V2 = c("B","C","B","A","C","B"), V3 = c("C","A","C","B","A","C"), grp = c("X","X","X","Y","Y","Y") ) nets <- build_network(seqs, method = "relative", group = "grp") print(nets)
Print Method for Multilevel Network Object
## S3 method for class 'netobject_ml' print(x, ...)## S3 method for class 'netobject_ml' print(x, ...)
x |
A |
... |
Additional arguments (ignored). |
The input object, invisibly.
set.seed(1) obs <- data.frame(id = rep(1:3, each = 5), A = rnorm(15), B = rnorm(15), C = rnorm(15)) net_ml <- build_network(obs, method = "cor", params = list(id = "id"), level = "both") print(net_ml) set.seed(1) obs <- data.frame( id = rep(1:5, each = 8), A = rnorm(40), B = rnorm(40), C = rnorm(40), D = rnorm(40) ) net_ml <- build_network(obs, method = "cor", params = list(id = "id"), level = "both") print(net_ml)set.seed(1) obs <- data.frame(id = rep(1:3, each = 5), A = rnorm(15), B = rnorm(15), C = rnorm(15)) net_ml <- build_network(obs, method = "cor", params = list(id = "id"), level = "both") print(net_ml) set.seed(1) obs <- data.frame( id = rep(1:5, each = 8), A = rnorm(40), B = rnorm(40), C = rnorm(40), D = rnorm(40) ) net_ml <- build_network(obs, method = "cor", params = list(id = "id"), level = "both") print(net_ml)
Print Persistence Landscape
## S3 method for class 'persistence_landscape' print(x, ...)## S3 method for class 'persistence_landscape' print(x, ...)
x |
A |
... |
Ignored. |
The input, invisibly.
mat <- matrix(c(0, .6, .5, .6, 0, .4, .5, .4, 0), 3, 3) rownames(mat) <- colnames(mat) <- c("A","B","C") ph <- persistent_homology(mat, n_steps = 5) pl <- persistence_landscape(ph, k_max = 3, dimension = 0) print(pl)mat <- matrix(c(0, .6, .5, .6, 0, .4, .5, .4, 0), 3, 3) rownames(mat) <- colnames(mat) <- c("A","B","C") ph <- persistent_homology(mat, n_steps = 5) pl <- persistence_landscape(ph, k_max = 3, dimension = 0) print(pl)
Print persistent homology results
## S3 method for class 'persistent_homology' print(x, ...)## S3 method for class 'persistent_homology' print(x, ...)
x |
A |
... |
Additional arguments (unused). |
The input object, invisibly.
mat <- matrix(c(0,.6,.5,.6,0,.4,.5,.4,0), 3, 3) colnames(mat) <- rownames(mat) <- c("A","B","C") ph <- persistent_homology(mat, n_steps = 10) print(ph)mat <- matrix(c(0,.6,.5,.6,0,.4,.5,.4,0), 3, 3) colnames(mat) <- rownames(mat) <- c("A","B","C") ph <- persistent_homology(mat, n_steps = 10) print(ph)
Print Q-analysis results
## S3 method for class 'q_analysis' print(x, ...)## S3 method for class 'q_analysis' print(x, ...)
x |
A |
... |
Additional arguments (unused). |
The input object, invisibly.
mat <- matrix(c(0,.6,.5,.6,0,.4,.5,.4,0), 3, 3) colnames(mat) <- rownames(mat) <- c("A","B","C") sc <- build_simplicial(mat, threshold = 0.3) qa <- q_analysis(sc) print(qa)mat <- matrix(c(0,.6,.5,.6,0,.4,.5,.4,0), 3, 3) colnames(mat) <- rownames(mat) <- c("A","B","C") sc <- build_simplicial(mat, threshold = 0.3) qa <- q_analysis(sc) print(qa)
Print a simplicial complex
## S3 method for class 'simplicial_complex' print(x, ...)## S3 method for class 'simplicial_complex' print(x, ...)
x |
A |
... |
Additional arguments (unused). |
The input object, invisibly.
mat <- matrix(c(0,.6,.5,.6,0,.4,.5,.4,0), 3, 3) colnames(mat) <- rownames(mat) <- c("A","B","C") sc <- build_simplicial(mat, threshold = 0.3) print(sc)mat <- matrix(c(0,.6,.5,.6,0,.4,.5,.4,0), 3, 3) colnames(mat) <- rownames(mat) <- c("A","B","C") sc <- build_simplicial(mat, threshold = 0.3) print(sc)
summary.chain_structure.Prints a one-line chain header followed by the tidy per-state table.
## S3 method for class 'summary_chain_structure' print(x, ...)## S3 method for class 'summary_chain_structure' print(x, ...)
x |
A |
... |
Forwarded to |
x invisibly.
summary.net_path_dependence
Print method for summary.net_path_dependence
## S3 method for class 'summary.net_path_dependence' print(x, digits = 3L, ...)## S3 method for class 'summary.net_path_dependence' print(x, digits = 3L, ...)
x |
A |
digits |
Integer. Digits to round numeric output. Default 3. |
... |
Ignored. |
x invisibly.
summary.net_transition_entropy
Print method for summary.net_transition_entropy
## S3 method for class 'summary.net_transition_entropy' print(x, digits = 3, ...)## S3 method for class 'summary.net_transition_entropy' print(x, digits = 3, ...)
x |
A |
digits |
Integer. Digits to round numeric output. Default |
... |
Ignored. |
x invisibly.
Prints a one-line header naming the estimator, then the data.frame.
The full human-readable view (per-cluster stats, profiles, OR/test
tables) was already printed by summary() when this object was
produced, so this method intentionally stays minimal to avoid
duplication. Auto-prints when the user types the variable at the REPL.
## S3 method for class 'tidy_covariates' print(x, ...)## S3 method for class 'tidy_covariates' print(x, ...)
x |
A |
... |
Ignored. |
The input invisibly.
Print Method for wtna_boot_mixed
## S3 method for class 'wtna_boot_mixed' print(x, ...)## S3 method for class 'wtna_boot_mixed' print(x, ...)
x |
A |
... |
Additional arguments (ignored). |
The input object, invisibly.
oh <- data.frame(A = c(1,0,1,0), B = c(0,1,0,1), C = c(1,1,0,0)) mixed <- wtna(oh, method = "both") boot <- bootstrap_network(mixed, iter = 10) print(boot) set.seed(1) oh <- data.frame( A = c(1,0,1,0,1,0,1,0), B = c(0,1,0,1,0,1,0,1), C = c(1,1,0,0,1,1,0,0) ) mixed <- wtna(oh, method = "both") boot <- bootstrap_network(mixed, iter = 20) print(boot)oh <- data.frame(A = c(1,0,1,0), B = c(0,1,0,1), C = c(1,1,0,0)) mixed <- wtna(oh, method = "both") boot <- bootstrap_network(mixed, iter = 10) print(boot) set.seed(1) oh <- data.frame( A = c(1,0,1,0,1,0,1,0), B = c(0,1,0,1,0,1,0,1), C = c(1,1,0,0,1,1,0,0) ) mixed <- wtna(oh, method = "both") boot <- bootstrap_network(mixed, iter = 20) print(boot)
Print Method for wtna_mixed
## S3 method for class 'wtna_mixed' print(x, ...)## S3 method for class 'wtna_mixed' print(x, ...)
x |
A |
... |
Additional arguments (ignored). |
The input object, invisibly.
oh <- matrix(c(1,0,0, 0,1,0, 0,0,1, 1,0,0), nrow = 4, byrow = TRUE, dimnames = list(NULL, c("A","B","C"))) mixed <- wtna(oh, method = "both") print(mixed) oh <- data.frame( A = c(1,0,1,0,1,0,1,0), B = c(0,1,0,1,0,1,0,1), C = c(1,1,0,0,1,1,0,0) ) mixed <- wtna(oh, method = "both") print(mixed)oh <- matrix(c(1,0,0, 0,1,0, 0,0,1, 1,0,0), nrow = 4, byrow = TRUE, dimnames = list(NULL, c("A","B","C"))) mixed <- wtna(oh, method = "both") print(mixed) oh <- data.frame( A = c(1,0,1,0,1,0,1,0), B = c(0,1,0,1,0,1,0,1), C = c(1,1,0,0,1,1,0,0) ) mixed <- wtna(oh, method = "both") print(mixed)
Print Method for wtna_perm_mixed
## S3 method for class 'wtna_perm_mixed' print(x, ...)## S3 method for class 'wtna_perm_mixed' print(x, ...)
x |
A |
... |
Additional arguments (ignored). |
The input object, invisibly.
Computes Q-connectivity structure (Atkin 1974). Two maximal simplices
are q-connected if they share a face of dimension . Reports:
Q-vector: number of connected components at each q-level
Structure vector: highest simplex dimension per node
q_analysis(sc)q_analysis(sc)
sc |
A |
A q_analysis object with $q_vector,
$structure_vector, and $max_q.
Atkin, R. H. (1974). Mathematical Structure in Human Affairs.
mat <- matrix(c(0,.6,.5,.6,0,.4,.5,.4,0), 3, 3) colnames(mat) <- rownames(mat) <- c("A","B","C") sc <- build_simplicial(mat, threshold = 0.3) q_analysis(sc)mat <- matrix(c(0,.6,.5,.6,0,.4,.5,.4,0), 3, 3) colnames(mat) <- rownames(mat) <- c("A","B","C") sc <- build_simplicial(mat, threshold = 0.3) q_analysis(sc)
Register a custom or built-in network estimator function by name.
Estimators registered here can be used by estimate_network
via the method parameter.
register_estimator(name, fn, description, directed)register_estimator(name, fn, description, directed)
name |
Character. Unique name for the estimator (e.g. |
fn |
Function. The estimator function. Must accept |
description |
Character. Short description of the estimator. |
directed |
Logical. Whether the estimator produces directed networks. |
Invisible NULL.
get_estimator, list_estimators,
remove_estimator, estimate_network
my_fn <- function(data, ...) { m <- cor(data) diag(m) <- 0 list(matrix = m, nodes = colnames(m), directed = FALSE) } register_estimator("my_cor", my_fn, "Custom correlation", directed = FALSE) df <- data.frame(A = rnorm(20), B = rnorm(20), C = rnorm(20)) net <- build_network(df, method = "my_cor") remove_estimator("my_cor")my_fn <- function(data, ...) { m <- cor(data) diag(m) <- 0 list(matrix = m, nodes = colnames(m), directed = FALSE) } register_estimator("my_cor", my_fn, "Custom correlation", directed = FALSE) df <- data.frame(A = rnorm(20), B = rnorm(20), C = rnorm(20)) net <- build_network(df, method = "my_cor") remove_estimator("my_cor")
Remove a network estimator from the registry.
remove_estimator(name)remove_estimator(name)
name |
Character. Name of the estimator to remove. |
Invisible NULL.
register_estimator, list_estimators
register_estimator("test_est", function(data, ...) diag(3), description = "test", directed = FALSE) remove_estimator("test_est")register_estimator("test_est", function(data, ...) diag(3), description = "test", directed = FALSE) remove_estimator("test_est")
netobject_group
Replaces the names of the constituent networks in a netobject_group
(or any object inheriting from it). Useful when build_network()
produced generic labels (e.g. "Cluster 1", "Cluster 2") and you
want to substitute meaningful ones (e.g. "High engagement",
"Low engagement").
rename_models(x, new_names) ## S3 method for class 'netobject_group' rename_models(x, new_names) ## Default S3 method: rename_models(x, new_names)rename_models(x, new_names) ## S3 method for class 'netobject_group' rename_models(x, new_names) ## Default S3 method: rename_models(x, new_names)
x |
A |
new_names |
A character vector of new names. Must have the same
length as |
A netobject_group of the same class with renamed members.
## Not run: d <- tna::group_regulation grp <- build_network(d, method = "tna", group = sample(c("a", "b"), nrow(d), TRUE)) grp <- rename_models(grp, c("High", "Low")) names(grp) ## End(Not run)## Not run: d <- tna::group_regulation grp <- build_network(d, method = "tna", group = sample(c("a", "b"), nrow(d), TRUE)) grp <- rename_models(grp, c("High", "Low")) names(grp) ## End(Not run)
Extracts all k-gram patterns (subsequences of length k) from sequences in each group, computes standardized residuals against the independence model, and optionally runs a permutation or chi-square test of group differences.
sequence_compare( x, group = NULL, sub = 3:5, min_freq = 5L, test = c("permutation", "chisq", "none"), iter = 1000L, adjust = "fdr" )sequence_compare( x, group = NULL, sub = 3:5, min_freq = 5L, test = c("permutation", "chisq", "none"), iter = 1000L, adjust = "fdr" )
x |
A |
group |
Character or vector. Column name or vector of group labels.
Not needed for |
sub |
Integer vector. Pattern lengths to analyze. Default: |
min_freq |
Integer. Minimum frequency in each group for a pattern to be included. Default: 5. |
test |
Character. Inference method: one of |
iter |
Integer. Permutation iterations. Only used when
|
adjust |
Character. P-value correction method (see
|
Standardized residuals are always computed from a 2xG contingency table
of (this pattern vs. everything else) using the textbook formula
(o - e) / sqrt(e * (1 - r/N) * (1 - c/N)). They describe how much
each group's count for a given pattern deviates from expectation under
independence, scaled to be approximately N(0,1) under the null.
The optional test argument chooses an inference method:
"permutation"Shuffles group labels across sequences and recomputes a per-pattern statistic (row-wise Euclidean residual norm). Answers: "is this pattern's distribution associated with group membership at the actor level?" Respects the sequence as the unit of analysis; can be underpowered when the number of sequences is small.
"chisq"Runs chisq.test on the 2xG table per
pattern. Answers: "do the group streams generate this pattern
at different rates?" Treats each k-gram occurrence as an event; fast
and powerful even with few sequences, but the iid assumption it makes
is optimistic when sequences are strongly autocorrelated.
"none"Skip inference. Only residuals, frequencies, and proportions are returned.
P-values are adjusted once across all patterns (not per-pattern) using
any method supported by p.adjust. The default is
"fdr" (Benjamini-Hochberg).
An object of class "net_sequence_comparison" containing:
Tidy data.frame. Always present:
pattern, length, freq_<group>,
prop_<group>, resid_<group>. If
test = "permutation": effect_size, p_value.
If test = "chisq": statistic, p_value.
Character vector of group names.
Integer. Number of patterns passing min_freq.
List of sub, min_freq, test, iter, adjust.
seqs <- data.frame( V1 = sample(LETTERS[1:4], 60, TRUE), V2 = sample(LETTERS[1:4], 60, TRUE), V3 = sample(LETTERS[1:4], 60, TRUE), V4 = sample(LETTERS[1:4], 60, TRUE) ) grp <- rep(c("X", "Y"), 30) net <- build_network(seqs, method = "relative") res <- sequence_compare(net, group = grp, sub = 2:3, test = "chisq")seqs <- data.frame( V1 = sample(LETTERS[1:4], 60, TRUE), V2 = sample(LETTERS[1:4], 60, TRUE), V3 = sample(LETTERS[1:4], 60, TRUE), V4 = sample(LETTERS[1:4], 60, TRUE) ) grp <- rep(c("X", "Y"), 30) net <- build_network(seqs, method = "relative") res <- sequence_compare(net, group = grp, sub = 2:3, test = "chisq")
Single entry point for three categorical-sequence visualisations.
type = "heatmap" (default): dense carpet, rows reordered
by sort / dendrogram (single panel).
type = "index": same data layout, but rows separated by
thin gaps (no dendrogram). Supports grouping via group or a
net_clustering, plus a ncol x nrow facet grid.
type = "distribution": dispatches to
distribution_plot.
sequence_plot( x, type = c("heatmap", "index", "distribution"), sort = c("lcs", "frequency", "start", "end", "hamming", "osa", "lv", "dl", "qgram", "cosine", "jaccard", "jw"), tree = NULL, group = NULL, scale = c("proportion", "count"), geom = c("area", "bar"), na = TRUE, row_gap = 0, dendrogram_width = 1.2, k = NULL, k_color = "white", k_line_width = 2.5, state_colors = NULL, na_color = "grey90", cell_border = NA, frame = FALSE, width = NULL, height = NULL, main = NULL, show_n = TRUE, time_label = "Time", xlab = NULL, y_label = NULL, ylab = NULL, tick = NULL, ncol = NULL, nrow = NULL, combined = TRUE, legend = NULL, legend_size = NULL, legend_title = NULL, legend_ncol = NULL, legend_border = NA, legend_bty = "n" )sequence_plot( x, type = c("heatmap", "index", "distribution"), sort = c("lcs", "frequency", "start", "end", "hamming", "osa", "lv", "dl", "qgram", "cosine", "jaccard", "jw"), tree = NULL, group = NULL, scale = c("proportion", "count"), geom = c("area", "bar"), na = TRUE, row_gap = 0, dendrogram_width = 1.2, k = NULL, k_color = "white", k_line_width = 2.5, state_colors = NULL, na_color = "grey90", cell_border = NA, frame = FALSE, width = NULL, height = NULL, main = NULL, show_n = TRUE, time_label = "Time", xlab = NULL, y_label = NULL, ylab = NULL, tick = NULL, ncol = NULL, nrow = NULL, combined = TRUE, legend = NULL, legend_size = NULL, legend_title = NULL, legend_ncol = NULL, legend_border = NA, legend_bty = "n" )
x |
Wide-format sequence data. Accepts:
|
type |
One of |
sort |
Row-ordering strategy for heatmap / within-panel for index.
One of |
tree |
Optional |
group |
Optional grouping vector (length |
scale, geom, na
|
Passed to |
row_gap |
Fraction of row height used as vertical gap between
sequences in index plots. |
dendrogram_width |
Width ratio of the dendrogram panel (heatmap). |
k |
Optional integer. When supplied in |
k_color |
Colour for the cluster separator lines. Default
|
k_line_width |
Line width for the cluster separators. Default
|
state_colors |
Vector of colours, one per state. |
na_color |
Colour for |
cell_border |
Cell border colour. |
frame |
If |
width, height
|
Optional device dimensions in inches. When supplied,
opens a new graphics device via |
main |
Plot title. |
show_n |
Append |
time_label, xlab
|
X-axis label. |
y_label, ylab
|
Y-axis label (distribution only). |
tick |
Show every Nth x-axis label. |
ncol, nrow
|
Facet grid dimensions (index + distribution).
Ignored when |
combined |
Index and distribution types only. When |
legend |
Legend position: |
legend_size |
Legend text size. |
legend_title |
Optional legend title. |
legend_ncol |
Number of legend columns. |
legend_border |
Swatch border colour. |
legend_bty |
|
Invisibly, a list describing the plot (shape depends on
type).
distribution_plot, build_clusters
sequence_plot(trajectories) sequence_plot(trajectories, type = "index") sequence_plot(trajectories, type = "distribution")sequence_plot(trajectories) sequence_plot(trajectories, type = "index") sequence_plot(trajectories, type = "distribution")
Counts how many simplices of each dimension contain each node.
simplicial_degree(sc, normalized = FALSE)simplicial_degree(sc, normalized = FALSE)
sc |
A |
normalized |
Divide by maximum possible count. Default |
Data frame with node, columns d0 through
d_k, and total (sum of d1+). Sorted by total descending.
mat <- matrix(c(0,.6,.5,.6,0,.4,.5,.4,0), 3, 3) colnames(mat) <- rownames(mat) <- c("A","B","C") sc <- build_simplicial(mat, threshold = 0.3) simplicial_degree(sc)mat <- matrix(c(0,.6,.5,.6,0,.4,.5,.4,0), 3, 3) colnames(mat) <- rownames(mat) <- c("A","B","C") sc <- build_simplicial(mat, threshold = 0.3) simplicial_degree(sc)
Simulated frequency counts of 9 self-regulated learning (SRL) strategies for 250 university students. Strategies are grouped into three clusters: metacognitive (Planning, Monitoring, Evaluating), cognitive (Elaboration, Organization, Rehearsal), and resource management (Help_Seeking, Time_Mgmt, Effort_Reg). Within-cluster correlations are moderate (0.3–0.6), cross-cluster correlations are weaker.
srl_strategiessrl_strategies
A data frame with 250 rows and 9 columns. Each column is an integer count of how often the student used that strategy.
net <- build_network(srl_strategies, method = "glasso", params = list(gamma = 0.5)) netnet <- build_network(srl_strategies, method = "glasso", params = list(gamma = 0.5)) net
Returns a tidy data.frame(group, state, count, proportion) with one
row per (group, state) cell. Companion to state_frequencies
(which counts unique states in raw sequence input);
state_distribution() pulls the same shape of frame from a fitted
Nestimate object so analyses don't have to reach for the underlying
$data slot directly.
state_distribution(x, ...) ## S3 method for class 'netobject' state_distribution(x, ...) ## S3 method for class 'htna' state_distribution(x, ...) ## S3 method for class 'mcml' state_distribution(x, include_macro = FALSE, ...) ## S3 method for class 'netobject_group' state_distribution(x, ...) ## Default S3 method: state_distribution(x, ...)state_distribution(x, ...) ## S3 method for class 'netobject' state_distribution(x, ...) ## S3 method for class 'htna' state_distribution(x, ...) ## S3 method for class 'mcml' state_distribution(x, include_macro = FALSE, ...) ## S3 method for class 'netobject_group' state_distribution(x, ...) ## Default S3 method: state_distribution(x, ...)
x |
A |
... |
Currently unused. |
include_macro |
For |
Used internally by plot_state_frequencies as the data layer
behind every chart, and surfaced as the $table slot of the
returned state_freq object.
A data.frame with columns group (character),
state (character), count (integer), and
proportion (numeric, within-group share).
## Not run: data(ai_long) net <- build_network(ai_long, method = "frequency", id_col = "session_id", time_col = "order_in_session", action = "code") state_distribution(net) ## End(Not run)## Not run: data(ai_long) net <- build_network(ai_long, method = "frequency", id_col = "session_id", time_col = "order_in_session", action = "code") state_distribution(net) ## End(Not run)
plot_state_frequencies() returns a state_freq object holding
both the rendered chart and the tidy frequency table. print() shows
the table in the console, plot() renders the chart, and
as.data.frame() returns the tidy table for downstream piping.
## S3 method for class 'state_freq' print(x, digits = 1, max_states = 20L, ...) ## S3 method for class 'state_freq' plot(x, ...) ## S3 method for class 'state_freq' as.data.frame(x, ...)## S3 method for class 'state_freq' print(x, digits = 1, max_states = 20L, ...) ## S3 method for class 'state_freq' plot(x, ...) ## S3 method for class 'state_freq' as.data.frame(x, ...)
x |
A |
digits |
Number of decimal places for proportion / share columns. |
max_states |
Cap on rows shown per group in the per-state table.
The full table remains available via |
... |
Unused. |
print() returns invisible(x); plot() returns
invisible(NULL) after drawing; as.data.frame() returns
x$table.
Counts how often each state appears across all trajectories. Returns a data frame sorted by frequency (descending).
state_frequencies(data)state_frequencies(data)
data |
A list of character vectors (trajectories) or a data.frame. |
A data frame with columns: state, count,
proportion.
trajs <- list(c("A","B","C"), c("A","B","A")) state_frequencies(trajs)trajs <- list(c("A","B","C"), c("A","B","A")) state_frequencies(trajs)
Summary Method for boot_glasso
## S3 method for class 'boot_glasso' summary(object, type = "edges", ...)## S3 method for class 'boot_glasso' summary(object, type = "edges", ...)
object |
A |
type |
Character. Summary type: |
... |
Additional arguments (ignored). |
A data frame or list of data frames depending on type.
set.seed(1) dat <- as.data.frame(matrix(rnorm(60), ncol = 3)) bg <- boot_glasso(dat, iter = 10, cs_iter = 5, centrality = "strength") summary(bg, type = "edges") set.seed(42) mat <- matrix(rnorm(60), ncol = 4) colnames(mat) <- LETTERS[1:4] boot <- boot_glasso(as.data.frame(mat), iter = 20, cs_iter = 10, centrality = "strength", seed = 42) summary(boot, type = "edges")set.seed(1) dat <- as.data.frame(matrix(rnorm(60), ncol = 3)) bg <- boot_glasso(dat, iter = 10, cs_iter = 5, centrality = "strength") summary(bg, type = "edges") set.seed(42) mat <- matrix(rnorm(60), ncol = 4) colnames(mat) <- LETTERS[1:4] boot <- boot_glasso(as.data.frame(mat), iter = 20, cs_iter = 10, centrality = "strength", seed = 42) summary(boot, type = "edges")
chain_structure.Returns a single data.frame with one row per state, combining every
per-state metric chain_structure() computes. Always includes
state, classification, period, return_probability (the
diagonal of the hitting matrix) and persistence (the diagonal of
the transition matrix); adds sojourn whenever it is finite, the
chain's stationary_probability when irreducible, and absorption
columns when the chain has any absorbing states.
## S3 method for class 'chain_structure' summary(object, ...)## S3 method for class 'chain_structure' summary(object, ...)
object |
A |
... |
Ignored. |
Columns are ordered for readability: identifiers first, classification second, dynamic per-state metrics last.
A data.frame with one row per state. Columns described above.
chain_structure_group.Produces a single tidy data.frame with one row per (group, state)
combination, combining classification, persistence, sojourn, and –
when applicable – stationary or mean-absorption-time columns. Useful
for side-by-side reporting of chain_structure() across the
members of a netobject_group.
## S3 method for class 'chain_structure_group' summary(object, ...)## S3 method for class 'chain_structure_group' summary(object, ...)
object |
A |
... |
Ignored. |
A data.frame with columns group, state, classification,
period, persistence, return_probability, sojourn_steps, plus
stationary_probability if all groups are irreducible and
mean_absorption_time if any group has absorbing states.
Summary Method for cluster_choice
## S3 method for class 'cluster_choice' summary(object, ...)## S3 method for class 'cluster_choice' summary(object, ...)
object |
A |
... |
Unsupported. Supplying unused arguments raises an error. |
A data frame with the swept configurations, all metrics, and
a best character column flagging the silhouette-max row.
Summary Method for mcml
## S3 method for class 'mcml' summary(object, ...)## S3 method for class 'mcml' summary(object, ...)
object |
An |
... |
Unsupported. Supplying unused arguments raises an error. |
A tidy data frame with one row per cluster and columns
cluster, size, within_total, between_out,
between_in. For undirected macro networks the in/out split is
not meaningful, so between_out reports total incident weight
and between_in is NA. The data frame is returned
silently without printing the full object – call
print(object) explicitly if you want the verbose dump.
seqs <- data.frame(V1 = c("A","B","C","A"), V2 = c("B","C","A","B")) clusters <- list(G1 = c("A","B"), G2 = c("C")) cs <- build_mcml(seqs, clusters) summary(cs) seqs <- data.frame( T1 = c("A","B","A"), T2 = c("B","C","B"), T3 = c("C","A","C"), T4 = c("A","B","A") ) clusters <- c("Alpha", "Beta", "Alpha") cs <- build_mcml(seqs, clusters, type = "raw") summary(cs)seqs <- data.frame(V1 = c("A","B","C","A"), V2 = c("B","C","A","B")) clusters <- list(G1 = c("A","B"), G2 = c("C")) cs <- build_mcml(seqs, clusters) summary(cs) seqs <- data.frame( T1 = c("A","B","A"), T2 = c("B","C","B"), T3 = c("C","A","C"), T4 = c("A","B","A") ) clusters <- c("Alpha", "Beta", "Alpha") cs <- build_mcml(seqs, clusters, type = "raw") summary(cs)
Summary Method for mmm_compare
## S3 method for class 'mmm_compare' summary(object, ...)## S3 method for class 'mmm_compare' summary(object, ...)
object |
An |
... |
Unsupported. Supplying unused arguments raises an error. |
A tidy data frame with one row per k, plus a best
character column flagging the minimum-BIC and minimum-ICL solutions.
Summary Method for Initial Probability Vectors
## S3 method for class 'nest_initial_probs' summary(object, ...)## S3 method for class 'nest_initial_probs' summary(object, ...)
object |
A |
... |
Additional arguments (ignored). |
A tidy data frame with columns state and prob,
sorted by decreasing probability.
Summary Method for Transition Count Matrices
## S3 method for class 'nest_transition_counts' summary(object, ...)## S3 method for class 'nest_transition_counts' summary(object, ...)
object |
A |
... |
Additional arguments (ignored). |
A tidy data frame with columns from, to,
count, with one row per non-zero transition.
Summary Method for Transition Matrices
## S3 method for class 'nest_transition_matrix' summary(object, ...)## S3 method for class 'nest_transition_matrix' summary(object, ...)
object |
A |
... |
Additional arguments (ignored). |
A tidy data frame with columns from, to,
weight, with one row per non-zero entry.
Summary Method for net_association_rules
## S3 method for class 'net_association_rules' summary(object, ...)## S3 method for class 'net_association_rules' summary(object, ...)
object |
A |
... |
Additional arguments (ignored). |
A data frame summarizing the rules, invisibly.
trans <- list(c("A","B","C"), c("A","B"), c("B","C","D"), c("A","C","D")) rules <- association_rules(trans, min_support = 0.3, min_confidence = 0.5, min_lift = 0) summary(rules)trans <- list(c("A","B","C"), c("A","B"), c("B","C","D"), c("A","C","D")) rules <- association_rules(trans, min_support = 0.3, min_confidence = 0.5, min_lift = 0) summary(rules)
Summary Method for net_bootstrap
## S3 method for class 'net_bootstrap' summary(object, ...)## S3 method for class 'net_bootstrap' summary(object, ...)
object |
A |
... |
Additional arguments (ignored). |
A data frame with edge-level bootstrap statistics.
net <- build_network(data.frame(V1 = c("A","B","C"), V2 = c("B","C","A")), method = "relative") boot <- bootstrap_network(net, iter = 10) summary(boot) set.seed(1) seqs <- data.frame( V1 = c("A","B","A","C","B"), V2 = c("B","C","B","A","C"), V3 = c("C","A","C","B","A") ) net <- build_network(seqs, method = "relative") boot <- bootstrap_network(net, iter = 20) summary(boot)net <- build_network(data.frame(V1 = c("A","B","C"), V2 = c("B","C","A")), method = "relative") boot <- bootstrap_network(net, iter = 10) summary(boot) set.seed(1) seqs <- data.frame( V1 = c("A","B","A","C","B"), V2 = c("B","C","B","A","C"), V3 = c("C","A","C","B","A") ) net <- build_network(seqs, method = "relative") boot <- bootstrap_network(net, iter = 20) summary(boot)
Summary Method for net_bootstrap_group
## S3 method for class 'net_bootstrap_group' summary(object, ...)## S3 method for class 'net_bootstrap_group' summary(object, ...)
object |
A |
... |
Ignored. |
A data frame with group, edge, and bootstrap statistics columns.
seqs <- data.frame(V1 = c("A","B","A","C"), V2 = c("B","C","C","A"), V3 = c("C","A","B","B"), grp = c("X","X","Y","Y")) nets <- build_network(seqs, method = "relative", group = "grp") boot <- bootstrap_network(nets, iter = 10) summary(boot) set.seed(1) seqs <- data.frame( V1 = c("A","B","A","C","B","A"), V2 = c("B","C","B","A","C","B"), V3 = c("C","A","C","B","A","C"), grp = c("X","X","X","Y","Y","Y") ) nets <- build_network(seqs, method = "relative", group = "grp") boot <- bootstrap_network(nets, iter = 20) summary(boot)seqs <- data.frame(V1 = c("A","B","A","C"), V2 = c("B","C","C","A"), V3 = c("C","A","B","B"), grp = c("X","X","Y","Y")) nets <- build_network(seqs, method = "relative", group = "grp") boot <- bootstrap_network(nets, iter = 10) summary(boot) set.seed(1) seqs <- data.frame( V1 = c("A","B","A","C","B","A"), V2 = c("B","C","B","A","C","B"), V3 = c("C","A","C","B","A","C"), grp = c("X","X","X","Y","Y","Y") ) nets <- build_network(seqs, method = "relative", group = "grp") boot <- bootstrap_network(nets, iter = 20) summary(boot)
Summary Method for net_clustering
## S3 method for class 'net_clustering' summary(object, ...)## S3 method for class 'net_clustering' summary(object, ...)
object |
A |
... |
Unsupported. Supplying unused arguments raises an error. |
The input object, invisibly.
seqs <- data.frame(V1 = c("A","B","C","A","B"), V2 = c("B","C","A","B","A"), V3 = c("C","A","B","C","B")) cl <- build_clusters(seqs, k = 2) summary(cl) set.seed(1) seqs <- data.frame( V1 = sample(c("A","B","C"), 20, TRUE), V2 = sample(c("A","B","C"), 20, TRUE), V3 = sample(c("A","B","C"), 20, TRUE) ) cl <- build_clusters(seqs, k = 2) summary(cl)seqs <- data.frame(V1 = c("A","B","C","A","B"), V2 = c("B","C","A","B","A"), V3 = c("C","A","B","C","B")) cl <- build_clusters(seqs, k = 2) summary(cl) set.seed(1) seqs <- data.frame( V1 = sample(c("A","B","C"), 20, TRUE), V2 = sample(c("A","B","C"), 20, TRUE), V3 = sample(c("A","B","C"), 20, TRUE) ) cl <- build_clusters(seqs, k = 2) summary(cl)
Summary Method for net_gimme
## S3 method for class 'net_gimme' summary(object, ...)## S3 method for class 'net_gimme' summary(object, ...)
object |
A |
... |
Additional arguments (ignored). |
The input object, invisibly.
set.seed(1) panel <- data.frame( id = rep(1:5, each = 20), t = rep(seq_len(20), 5), A = rnorm(100), B = rnorm(100), C = rnorm(100) ) gm <- build_gimme(panel, vars = c("A","B","C"), id = "id", time = "t") summary(gm)set.seed(1) panel <- data.frame( id = rep(1:5, each = 20), t = rep(seq_len(20), 5), A = rnorm(100), B = rnorm(100), C = rnorm(100) ) gm <- build_gimme(panel, vars = c("A","B","C"), id = "id", time = "t") summary(gm)
Summary Method for net_hon
## S3 method for class 'net_hon' summary(object, ...)## S3 method for class 'net_hon' summary(object, ...)
object |
A |
... |
Additional arguments (ignored). |
The edge data.frame object$edges (columns path,
from, to, count, probability,
from_order, to_order), returned visibly; the summary text
is printed as a side effect.
seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) hon <- build_hon(seqs, max_order = 2) summary(hon) seqs <- data.frame( V1 = c("A","B","C","A","B"), V2 = c("B","C","A","B","C"), V3 = c("C","A","B","C","A") ) hon <- build_hon(seqs, max_order = 2L) summary(hon)seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) hon <- build_hon(seqs, max_order = 2) summary(hon) seqs <- data.frame( V1 = c("A","B","C","A","B"), V2 = c("B","C","A","B","C"), V3 = c("C","A","B","C","A") ) hon <- build_hon(seqs, max_order = 2L) summary(hon)
Summary Method for net_honem
## S3 method for class 'net_honem' summary(object, ...)## S3 method for class 'net_honem' summary(object, ...)
object |
A |
... |
Additional arguments (ignored). |
A data.frame with one row per node: column node (node
label) followed by dim1, dim2, ..., dimd
embedding coordinates, returned visibly; the summary text is printed as
a side effect.
seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) hem <- build_honem(build_hon(seqs, max_order = 2), dim = 2) summary(hem) seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) hon <- build_hon(seqs, max_order = 3) he <- build_honem(hon, dim = 2) summary(he)seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) hem <- build_honem(build_hon(seqs, max_order = 2), dim = 2) summary(hem) seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) hon <- build_hon(seqs, max_order = 3) he <- build_honem(hon, dim = 2) summary(he)
Summary Method for net_hypa
## S3 method for class 'net_hypa' summary( object, n = 10L, type = c("all", "over", "under"), order_by = c("sig", "freq", "frequency", "ratio", "path"), ... )## S3 method for class 'net_hypa' summary( object, n = 10L, type = c("all", "over", "under"), order_by = c("sig", "freq", "frequency", "ratio", "path"), ... )
object |
A |
n |
Integer. Maximum number of paths to display per category (default: 10). |
type |
Character. Which anomalies to show: |
order_by |
Character. Ranking used within each anomaly direction:
|
... |
Additional arguments (ignored). |
A data frame with path, observed, expected, ratio, p_tail, and direction columns.
seqs <- list(c("A","B","C"), c("B","C","A"), c("A","C","B"), c("A","B","C")) hyp <- build_hypa(seqs, k = 2) summary(hyp) seqs <- data.frame( V1 = c("A","B","C","A","B","C","A","B","C","A"), V2 = c("B","C","A","B","C","A","B","C","A","B"), V3 = c("C","A","B","C","A","B","C","A","B","C"), V4 = c("A","B","C","A","B","C","A","B","C","A") ) hypa <- build_hypa(seqs, k = 2L) summary(hypa) summary(hypa, type = "over", n = 5)seqs <- list(c("A","B","C"), c("B","C","A"), c("A","C","B"), c("A","B","C")) hyp <- build_hypa(seqs, k = 2) summary(hyp) seqs <- data.frame( V1 = c("A","B","C","A","B","C","A","B","C","A"), V2 = c("B","C","A","B","C","A","B","C","A","B"), V3 = c("C","A","B","C","A","B","C","A","B","C"), V4 = c("A","B","C","A","B","C","A","B","C","A") ) hypa <- build_hypa(seqs, k = 2L) summary(hypa) summary(hypa, type = "over", n = 5)
Summary Method for net_link_prediction
## S3 method for class 'net_link_prediction' summary(object, ...)## S3 method for class 'net_link_prediction' summary(object, ...)
object |
A |
... |
Additional arguments (ignored). |
A data frame with per-method summary statistics, invisibly.
seqs <- data.frame( V1 = sample(LETTERS[1:4], 30, TRUE), V2 = sample(LETTERS[1:4], 30, TRUE), V3 = sample(LETTERS[1:4], 30, TRUE) ) net <- build_network(seqs, method = "relative") pred <- predict_links(net) summary(pred)seqs <- data.frame( V1 = sample(LETTERS[1:4], 30, TRUE), V2 = sample(LETTERS[1:4], 30, TRUE), V3 = sample(LETTERS[1:4], 30, TRUE) ) net <- build_network(seqs, method = "relative") pred <- predict_links(net) summary(pred)
Summary Method for net_markov_order
## S3 method for class 'net_markov_order' summary(object, ...)## S3 method for class 'net_markov_order' summary(object, ...)
object |
A |
... |
Ignored. |
The tidy test_table data.frame, with the selected
optimal_order attached as an attribute.
# First-order Markov data: test should select order 1 set.seed(1) states <- letters[1:4] tm <- matrix(runif(16), 4, 4, dimnames = list(states, states)) tm <- tm / rowSums(tm) seqs <- lapply(1:30, function(.) { s <- character(50); s[1] <- sample(states, 1) for (i in 2:50) s[i] <- sample(states, 1, prob = tm[s[i - 1], ]) s }) res <- markov_order_test(seqs, max_order = 3, n_perm = 300, seed = 1) res$optimal_order summary(res) plot(res)# First-order Markov data: test should select order 1 set.seed(1) states <- letters[1:4] tm <- matrix(runif(16), 4, 4, dimnames = list(states, states)) tm <- tm / rowSums(tm) seqs <- lapply(1:30, function(.) { s <- character(50); s[1] <- sample(states, 1) for (i in 2:50) s[i] <- sample(states, 1, prob = tm[s[i - 1], ]) s }) res <- markov_order_test(seqs, max_order = 3, n_perm = 300, seed = 1) res$optimal_order summary(res) plot(res)
Summary method for net_mlvar
## S3 method for class 'net_mlvar' summary(object, ...)## S3 method for class 'net_mlvar' summary(object, ...)
object |
A |
... |
Unused; present for S3 consistency. |
Invisibly returns object.
## Not run: d <- simulate_data("mlvar", seed = 1) fit <- build_mlvar(d, vars = attr(d, "vars"), id = "id", day = "day", beep = "beep") print(fit) summary(fit) ## End(Not run)## Not run: d <- simulate_data("mlvar", seed = 1) fit <- build_mlvar(d, vars = attr(d, "vars"), id = "id", day = "day", beep = "beep") print(fit) summary(fit) ## End(Not run)
Summary Method for net_mmm
## S3 method for class 'net_mmm' summary(object, ...)## S3 method for class 'net_mmm' summary(object, ...)
object |
A |
... |
Unsupported. Supplying unused arguments raises an error. |
A per-component summary data.frame. The class and visibility
depend on whether the model was fitted with covariates:
A plain data.frame with one row per
component and columns component, prior,
n_assigned, mean_posterior, avepp, returned
visibly (so it auto-prints after the printed summary block).
A tidy_covariates/data.frame
(the tidied covariate table, with the per-component stats attached),
returned invisibly.
In both cases the printed summary (model fit, per-cluster transition matrices, optional covariate profiles) is emitted as a side effect.
seqs <- data.frame(V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE)) mmm <- build_mmm(seqs, k = 2, n_starts = 1, max_iter = 10, seed = 1) summary(mmm) set.seed(1) seqs <- data.frame( V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE), V3 = sample(c("A","B","C"), 30, TRUE) ) mmm <- build_mmm(seqs, k = 2, n_starts = 5, seed = 1) summary(mmm)seqs <- data.frame(V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE)) mmm <- build_mmm(seqs, k = 2, n_starts = 1, max_iter = 10, seed = 1) summary(mmm) set.seed(1) seqs <- data.frame( V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE), V3 = sample(c("A","B","C"), 30, TRUE) ) mmm <- build_mmm(seqs, k = 2, n_starts = 5, seed = 1) summary(mmm)
Summary Method for net_mogen
## S3 method for class 'net_mogen' summary(object, ...)## S3 method for class 'net_mogen' summary(object, ...)
object |
A |
... |
Additional arguments (ignored). |
A per-order model-selection data.frame with columns order,
layer_dof, cum_dof, loglik, aic, bic,
best ("AIC"/"BIC"/"AIC+BIC" marker) and
selected ("<--" on the chosen order), returned visibly;
the summary text is printed as a side effect.
seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) mg <- build_mogen(seqs, max_order = 2) summary(mg) seqs <- data.frame( V1 = c("A","B","C","A","B"), V2 = c("B","C","A","B","C"), V3 = c("C","A","B","C","A") ) mog <- build_mogen(seqs, max_order = 2L) summary(mog)seqs <- list(c("A","B","C","D"), c("A","B","C","A"), c("B","C","D","A")) mg <- build_mogen(seqs, max_order = 2) summary(mg) seqs <- data.frame( V1 = c("A","B","C","A","B"), V2 = c("B","C","A","B","C"), V3 = c("C","A","B","C","A") ) mog <- build_mogen(seqs, max_order = 2L) summary(mog)
Returns a tidy data frame with one row per edge test. The global M (strength) and S (structure) statistics are attached as attributes.
## S3 method for class 'net_nct' summary(object, ...)## S3 method for class 'net_nct' summary(object, ...)
object |
A |
... |
Ignored. |
A data frame with columns from, to,
diff_observed, p_value, significant. Attributes
m_stat and s_stat each hold a one-row data frame with
observed and p_value.
## Not run: set.seed(1) x1 <- matrix(rnorm(200 * 5), 200, 5) x2 <- matrix(rnorm(200 * 5), 200, 5) colnames(x1) <- colnames(x2) <- paste0("V", 1:5) res <- nct(x1, x2, iter = 100) res$M$p_value res$S$p_value ## End(Not run)## Not run: set.seed(1) x1 <- matrix(rnorm(200 * 5), 200, 5) x2 <- matrix(rnorm(200 * 5), 200, 5) colnames(x1) <- colnames(x2) <- paste0("V", 1:5) res <- nct(x1, x2, iter = 100) res$M$p_value res$S$p_value ## End(Not run)
net_path_dependence
Summary method for net_path_dependence
## S3 method for class 'net_path_dependence' summary(object, ...)## S3 method for class 'net_path_dependence' summary(object, ...)
object |
A |
... |
Ignored. |
A summary.net_path_dependence with the full sorted table and
chain-level summaries.
Summary Method for net_permutation
## S3 method for class 'net_permutation' summary(object, ...)## S3 method for class 'net_permutation' summary(object, ...)
object |
A |
... |
Additional arguments (ignored). |
A data frame with edge-level permutation test results.
s1 <- data.frame(V1 = c("A","B","C"), V2 = c("B","C","A")) s2 <- data.frame(V1 = c("A","C","B"), V2 = c("C","B","A")) n1 <- build_network(s1, method = "relative") n2 <- build_network(s2, method = "relative") perm <- permutation(n1, n2, iter = 10) summary(perm) set.seed(1) d1 <- data.frame(V1 = c("A","B","A"), V2 = c("B","C","B"), V3 = c("C","A","C")) d2 <- data.frame(V1 = c("C","A","C"), V2 = c("A","B","A"), V3 = c("B","C","B")) net1 <- build_network(d1, method = "relative") net2 <- build_network(d2, method = "relative") perm <- permutation(net1, net2, iter = 20, seed = 1) summary(perm)s1 <- data.frame(V1 = c("A","B","C"), V2 = c("B","C","A")) s2 <- data.frame(V1 = c("A","C","B"), V2 = c("C","B","A")) n1 <- build_network(s1, method = "relative") n2 <- build_network(s2, method = "relative") perm <- permutation(n1, n2, iter = 10) summary(perm) set.seed(1) d1 <- data.frame(V1 = c("A","B","A"), V2 = c("B","C","B"), V3 = c("C","A","C")) d2 <- data.frame(V1 = c("C","A","C"), V2 = c("A","B","A"), V3 = c("B","C","B")) net1 <- build_network(d1, method = "relative") net2 <- build_network(d2, method = "relative") perm <- permutation(net1, net2, iter = 20, seed = 1) summary(perm)
Returns a combined summary data frame across all groups.
## S3 method for class 'net_permutation_group' summary(object, ...)## S3 method for class 'net_permutation_group' summary(object, ...)
object |
A |
... |
Additional arguments (ignored). |
A data frame with group, edge, p_value, and sig columns.
s1 <- data.frame(V1 = c("A","B","A","C"), V2 = c("B","C","B","A"), V3 = c("C","A","C","B"), grp = c("X","X","Y","Y")) s2 <- data.frame(V1 = c("C","A","C","B"), V2 = c("A","B","A","C"), V3 = c("B","C","B","A"), grp = c("X","X","Y","Y")) nets1 <- build_network(s1, method = "relative", group = "grp") nets2 <- build_network(s2, method = "relative", group = "grp") perm <- permutation(nets1, nets2, iter = 10) summary(perm) set.seed(1) s1 <- data.frame(V1 = c("A","B","A","C"), V2 = c("B","C","B","A"), V3 = c("C","A","C","B"), grp = c("X","X","Y","Y")) s2 <- data.frame(V1 = c("C","A","C","B"), V2 = c("A","B","A","C"), V3 = c("B","C","B","A"), grp = c("X","X","Y","Y")) nets1 <- build_network(s1, method = "relative", group = "grp") nets2 <- build_network(s2, method = "relative", group = "grp") perm <- permutation(nets1, nets2, iter = 20, seed = 1) summary(perm)s1 <- data.frame(V1 = c("A","B","A","C"), V2 = c("B","C","B","A"), V3 = c("C","A","C","B"), grp = c("X","X","Y","Y")) s2 <- data.frame(V1 = c("C","A","C","B"), V2 = c("A","B","A","C"), V3 = c("B","C","B","A"), grp = c("X","X","Y","Y")) nets1 <- build_network(s1, method = "relative", group = "grp") nets2 <- build_network(s2, method = "relative", group = "grp") perm <- permutation(nets1, nets2, iter = 10) summary(perm) set.seed(1) s1 <- data.frame(V1 = c("A","B","A","C"), V2 = c("B","C","B","A"), V3 = c("C","A","C","B"), grp = c("X","X","Y","Y")) s2 <- data.frame(V1 = c("C","A","C","B"), V2 = c("A","B","A","C"), V3 = c("B","C","B","A"), grp = c("X","X","Y","Y")) nets1 <- build_network(s1, method = "relative", group = "grp") nets2 <- build_network(s2, method = "relative", group = "grp") perm <- permutation(nets1, nets2, iter = 20, seed = 1) summary(perm)
Summary Method for net_reliability
## S3 method for class 'net_reliability' summary(object, ...)## S3 method for class 'net_reliability' summary(object, ...)
object |
A |
... |
Ignored. |
A tidy data frame with columns model, metric,
mean, sd summarising the split-half iterations.
net <- build_network(data.frame(V1 = c("A","B","C","A"), V2 = c("B","C","A","B")), method = "relative") rel <- network_reliability(net, iter = 10) seqs <- data.frame( V1 = sample(LETTERS[1:4], 30, TRUE), V2 = sample(LETTERS[1:4], 30, TRUE), V3 = sample(LETTERS[1:4], 30, TRUE), V4 = sample(LETTERS[1:4], 30, TRUE) ) net <- build_network(seqs, method = "relative") rel <- network_reliability(net, iter = 100, seed = 42) print(rel)net <- build_network(data.frame(V1 = c("A","B","C","A"), V2 = c("B","C","A","B")), method = "relative") rel <- network_reliability(net, iter = 10) seqs <- data.frame( V1 = sample(LETTERS[1:4], 30, TRUE), V2 = sample(LETTERS[1:4], 30, TRUE), V3 = sample(LETTERS[1:4], 30, TRUE), V4 = sample(LETTERS[1:4], 30, TRUE) ) net <- build_network(seqs, method = "relative") rel <- network_reliability(net, iter = 100, seed = 42) print(rel)
Summary Method for net_sequence_comparison
## S3 method for class 'net_sequence_comparison' summary(object, ...)## S3 method for class 'net_sequence_comparison' summary(object, ...)
object |
A |
... |
Additional arguments (ignored). |
The patterns data.frame (tidy: one row per k-gram pattern, per group, with frequency and proportion columns; includes p-values when a permutation test was run).
seqs <- data.frame( V1 = sample(LETTERS[1:4], 60, TRUE), V2 = sample(LETTERS[1:4], 60, TRUE), V3 = sample(LETTERS[1:4], 60, TRUE), V4 = sample(LETTERS[1:4], 60, TRUE) ) grp <- rep(c("X", "Y"), 30) net <- build_network(seqs, method = "relative") res <- sequence_compare(net, group = grp, sub = 2:3, test = "chisq")seqs <- data.frame( V1 = sample(LETTERS[1:4], 60, TRUE), V2 = sample(LETTERS[1:4], 60, TRUE), V3 = sample(LETTERS[1:4], 60, TRUE), V4 = sample(LETTERS[1:4], 60, TRUE) ) grp <- rep(c("X", "Y"), 30) net <- build_network(seqs, method = "relative") res <- sequence_compare(net, group = grp, sub = 2:3, test = "chisq")
Returns the mean correlation at each drop proportion for each measure.
## S3 method for class 'net_stability' summary(object, ...)## S3 method for class 'net_stability' summary(object, ...)
object |
A |
... |
Additional arguments (ignored). |
A data frame with columns measure, drop_prop,
mean_cor, sd_cor, prop_above.
net <- build_network(data.frame(V1 = c("A","B","C","A"), V2 = c("B","C","A","B")), method = "relative") cs <- centrality_stability(net, iter = 10, drop_prop = 0.3) summary(cs) set.seed(1) seqs <- data.frame( V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE), V3 = sample(c("A","B","C"), 30, TRUE) ) net <- build_network(seqs, method = "relative") stab <- centrality_stability(net, measures = c("InStrength","OutStrength"), iter = 10) summary(stab)net <- build_network(data.frame(V1 = c("A","B","C","A"), V2 = c("B","C","A","B")), method = "relative") cs <- centrality_stability(net, iter = 10, drop_prop = 0.3) summary(cs) set.seed(1) seqs <- data.frame( V1 = sample(c("A","B","C"), 30, TRUE), V2 = sample(c("A","B","C"), 30, TRUE), V3 = sample(c("A","B","C"), 30, TRUE) ) net <- build_network(seqs, method = "relative") stab <- centrality_stability(net, measures = c("InStrength","OutStrength"), iter = 10) summary(stab)
Per-network stability as a tidy data frame. Stacks summary()
results for each network with a group column.
## S3 method for class 'net_stability_group' summary(object, ...)## S3 method for class 'net_stability_group' summary(object, ...)
object |
A |
... |
Additional arguments (ignored). |
A data frame with columns group, measure,
drop_prop, mean_cor, sd_cor, prop_above.
net_transition_entropy
Returns a tidy per-state contribution table sorted by share of the
chain-level entropy rate (largest first), so the dominant contributors
to are visible at a glance. Each row contains the
stationary mass, the raw and normalised row entropy, the additive
contribution , and that contribution as a
percentage of .
## S3 method for class 'net_transition_entropy' summary(object, ...)## S3 method for class 'net_transition_entropy' summary(object, ...)
object |
A |
... |
Ignored. |
A summary.net_transition_entropy containing
tidy per-state data.frame, sorted by contribution_pct
descending
tidy chain-level data.frame with raw and normalised
, , redundancy, and ceiling
logarithm base used
Computes node count, edge count, density, mean shortest-path distance,
mean and SD of in/out strength, mean and SD of in/out degree, in/out
degree centralization (Freeman), and reciprocity. Mirrors the metric set
returned by tna::summary.tna() so a Nestimate netobject and the
equivalent tna model report numerically identical descriptive metrics.
## S3 method for class 'netobject' summary(object, ...)## S3 method for class 'netobject' summary(object, ...)
object |
A |
... |
Ignored. |
A data.frame with columns metric and value, of class
c("summary.netobject", "data.frame").
Returns one summary per constituent network. With combined = TRUE
(default) the per-group tables are joined into a single wide
data.frame with one column per group; with combined = FALSE
returns a named list.
## S3 method for class 'netobject_group' summary(object, combined = TRUE, ...)## S3 method for class 'netobject_group' summary(object, combined = TRUE, ...)
object |
A |
combined |
Logical. Combine into one wide data.frame? Default |
... |
Ignored. |
Either a data.frame (one column per group) or a named list of
summary.netobject objects, of class c("summary.netobject_group", ...).
Summary Method for wtna_boot_mixed
## S3 method for class 'wtna_boot_mixed' summary(object, ...)## S3 method for class 'wtna_boot_mixed' summary(object, ...)
object |
A |
... |
Additional arguments (ignored). |
A list with $transition and $cooccurrence summary data frames.
oh <- data.frame(A = c(1,0,1,0), B = c(0,1,0,1), C = c(1,1,0,0)) mixed <- wtna(oh, method = "both") boot <- bootstrap_network(mixed, iter = 10) summary(boot) set.seed(1) oh <- data.frame( A = c(1,0,1,0,1,0,1,0), B = c(0,1,0,1,0,1,0,1), C = c(1,1,0,0,1,1,0,0) ) mixed <- wtna(oh, method = "both") boot <- bootstrap_network(mixed, iter = 20) summary(boot)oh <- data.frame(A = c(1,0,1,0), B = c(0,1,0,1), C = c(1,1,0,0)) mixed <- wtna(oh, method = "both") boot <- bootstrap_network(mixed, iter = 10) summary(boot) set.seed(1) oh <- data.frame( A = c(1,0,1,0,1,0,1,0), B = c(0,1,0,1,0,1,0,1), C = c(1,1,0,0,1,1,0,0) ) mixed <- wtna(oh, method = "both") boot <- bootstrap_network(mixed, iter = 20) summary(boot)
Summary Method for wtna_perm_mixed
## S3 method for class 'wtna_perm_mixed' summary(object, ...)## S3 method for class 'wtna_perm_mixed' summary(object, ...)
object |
A |
... |
Additional arguments (ignored). |
A list with transition and co-occurrence permutation summaries.
Wide-format state sequences of student engagement over 15 weekly
observations. Each row is one student; columns 1..15
hold the engagement state for that week. States: "Active",
"Average", "Disengaged". Missing weeks are NA.
trajectoriestrajectories
A character matrix with 138 rows and 15 columns. Entries are
one of "Active", "Average", "Disengaged", or
NA.
sequence_plot(trajectories, main = "Engagement trajectories") sequence_plot(trajectories, k = 3) sequence_plot(trajectories, type = "distribution")sequence_plot(trajectories, main = "Engagement trajectories") sequence_plot(trajectories, k = 3) sequence_plot(trajectories, type = "distribution")
Computes per-state branching entropy, stationary entropy, and the chain-level entropy rate of a Markov transition process. The entropy rate is the Shannon-McMillan-Breiman per-step uncertainty of trajectories under the stationary distribution; it is the canonical information-theoretic summary of a transition matrix.
transition_entropy(x, base = 2, normalize = TRUE)transition_entropy(x, base = 2, normalize = TRUE)
x |
A |
base |
Numeric. Logarithm base. |
normalize |
Logical. If |
Convention is applied, so absorbing or
deterministic rows contribute zero per-row entropy. The chain need not be
irreducible; is computed from the eigendecomposition of
as elsewhere in the package. For non-ergodic chains the
returned is one stationary distribution among many - interpret
with the help of chain_structure.
The relation holds with equality iff successive
states are independent. The deficit is reported as
redundancy - a measure of how much memory the chain has at order 1.
An object of class "net_transition_entropy" with:
Named numeric vector, length . Per-state
branching entropy .
Named numeric vector. row_entropy
divided by the ceiling (in ; all zeros
when ).
Named numeric vector. Stationary distribution
.
Scalar.
- the entropy of treated as an i.i.d. distribution. Upper
bound on the entropy rate.
Scalar. stationary_entropy
divided by the ceiling .
Scalar. -
the Shannon-McMillan-Breiman entropy rate.
Scalar. entropy_rate divided by the
ceiling .
Scalar. , the entropy deficit
attributable to serial dependence; zero for an i.i.d. chain (rows of
all equal ).
Scalar. The relative redundancy
(the fraction of the stationary
entropy removed by order-1 memory), not
redundancy divided by ; 0 when
.
Scalar. The normalising ceiling .
Logarithm base used.
Character vector of state names.
Cover, T.M. & Thomas, J.A. (2006). Elements of Information Theory, 2nd ed., chapter 4. Wiley.
Shannon, C.E. (1948). A mathematical theory of communication. Bell System Technical Journal, 27, 379-423.
markov_stability, passage_time,
markov_order_test, chain_structure
net <- build_network(as.data.frame(trajectories), method = "relative") te <- transition_entropy(net) print(te) summary(te) plot(te)net <- build_network(as.data.frame(trajectories), method = "relative") te <- transition_entropy(net) print(te) summary(te) plot(te)
Cross-validates clique finding and Betti numbers against igraph and known topological invariants. Useful for testing.
verify_simplicial(mat, threshold = 0)verify_simplicial(mat, threshold = 0)
mat |
A square adjacency matrix. |
threshold |
Edge weight threshold. |
A list with $cliques_match (logical),
$n_simplices_ours, $n_simplices_igraph,
$betti, and $euler.
mat <- matrix(c(0,.6,.5,.6,0,.4,.5,.4,0), 3, 3) colnames(mat) <- rownames(mat) <- c("A","B","C") verify_simplicial(mat, threshold = 0.3)mat <- matrix(c(0,.6,.5,.6,0,.4,.5,.4,0), 3, 3) colnames(mat) <- rownames(mat) <- c("A","B","C") verify_simplicial(mat, threshold = 0.3)
Convert sequence data from wide format (one row per sequence, columns as time points) to long format (one row per action).
wide_to_long( data, id_col = NULL, time_prefix = "V", action_col = "Action", time_col = "Time", drop_na = TRUE )wide_to_long( data, id_col = NULL, time_prefix = "V", action_col = "Action", time_col = "Time", drop_na = TRUE )
data |
Data frame in wide format with sequences in rows. |
id_col |
Character. Name of the ID column, or NULL to auto-generate IDs. Default: NULL. |
time_prefix |
Character. Prefix for time point columns (e.g., "V" for V1, V2, ...). Default: "V". |
action_col |
Character. Name of the action column in output. Default: "Action". |
time_col |
Character. Name of the time column in output. Default: "Time". |
drop_na |
Logical. Whether to drop NA values. Default: TRUE. |
This function converts data from the format produced by simulate_sequences()
to the long format used by many TNA functions and analyses.
A data frame in long format with columns:
Sequence identifier (integer).
Time point within the sequence (integer).
The action/state at that time point (character).
Any additional columns from the original data are preserved.
long_to_wide for the reverse conversion,
prepare_for_tna for preparing data for TNA analysis.
wide_data <- data.frame( V1 = c("A", "B", "C"), V2 = c("B", "C", "A"), V3 = c("C", "A", "B") ) long_data <- wide_to_long(wide_data) head(long_data)wide_data <- data.frame( V1 = c("A", "B", "C"), V2 = c("B", "C", "A"), V3 = c("C", "A", "B") ) long_data <- wide_to_long(wide_data) head(long_data)
Computes networks from one-hot (binary indicator) data using temporal windowing. Supports transition (directed), co-occurrence (undirected), or both network types.
wtna( data, method = c("transition", "cooccurrence", "both"), type = c("frequency", "relative"), codes = NULL, window_size = 3L, mode = c("non-overlapping", "overlapping"), actor = NULL )wtna( data, method = c("transition", "cooccurrence", "both"), type = c("frequency", "relative"), codes = NULL, window_size = 3L, mode = c("non-overlapping", "overlapping"), actor = NULL )
data |
Data frame with one-hot encoded columns (0/1 binary). |
method |
Character. Network type: |
type |
Character. Output type: |
codes |
Character vector or NULL. Names of the one-hot columns to use. If NULL, auto-detects binary columns. Default: NULL. |
window_size |
Integer (>= 1). Number of consecutive rows to aggregate
per window. Default: 3 (windowed pairwise between-window counting). Set
|
mode |
Character. Window mode: |
actor |
Character or NULL. Name of the actor/ID column for per-group computation. If NULL, treats all rows as one group. Default: NULL. |
Transitions: Uses crossprod(X[-n,], X[-1,]) to count
how often state i is active at time t AND state j at time t+1.
Co-occurrence: Uses crossprod(X) to count states that are
simultaneously active in the same row.
Windowing: For window_size > 1, rows are aggregated into
windows before computing networks. Non-overlapping windows are fixed,
separate blocks; overlapping windows roll forward one row at a time.
Within each window, any active indicator (1) in any row makes that state
active for the window.
Per-actor: When actor is specified, networks are computed
per group and summed.
For method = "transition" or "cooccurrence": a
netobject (see build_network).
For method = "both": a wtna_mixed object with elements
$transition and $cooccurrence, each a netobject.
oh <- matrix(c(1,0,0, 0,1,0, 0,0,1, 1,0,0), nrow = 4, byrow = TRUE, dimnames = list(NULL, c("A","B","C"))) w <- wtna(oh) # Simple one-hot data df <- data.frame( A = c(1, 0, 1, 0, 1), B = c(0, 1, 0, 1, 0), C = c(0, 0, 1, 0, 0) ) # Transition network net <- wtna(df) print(net) # Both networks nets <- wtna(df, method = "both") print(nets$transition) print(nets$cooccurrence) # With windowing net <- wtna(df, window_size = 2, mode = "non-overlapping")oh <- matrix(c(1,0,0, 0,1,0, 0,0,1, 1,0,0), nrow = 4, byrow = TRUE, dimnames = list(NULL, c("A","B","C"))) w <- wtna(oh) # Simple one-hot data df <- data.frame( A = c(1, 0, 1, 0, 1), B = c(0, 1, 0, 1, 0), C = c(0, 0, 1, 0, 0) ) # Transition network net <- wtna(df) print(net) # Both networks nets <- wtna(df, method = "both") print(nets$transition) print(nets$cooccurrence) # With windowing net <- wtna(df, window_size = 2, mode = "non-overlapping")