The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
R has several network packages — igraph for graph algorithms, qgraph for psychometric networks, tidygraph for dplyr-style manipulation. Each does one thing well but forces you into its own data format and API. Going from a raw matrix to a filtered, annotated, publication-ready figure typically means loading three packages, converting between formats, and writing boilerplate code to stitch the results together.
cograph was designed to eliminate that friction. Every function —
plotting, centrality, community detection, filtering — accepts any major
network format directly: matrices, edge lists, igraph, statnet, qgraph,
and tna objects. No manual conversion. Centrality returns a tidy data
frame, not a list of separate calls. Community detection is one function
with 11 algorithms behind it. Statistical annotations (confidence
intervals, p-values, significance stars) render directly on the figure.
And when you need igraph or statnet for something cograph does not do,
to_igraph() and to_network() convert back
without data loss.
Beyond standard network analysis, cograph visualizes higher-order sequential pathways as simplicial blob diagrams, renders bootstrap stability results with forest plots (linear, circular, and grouped layouts), and performs motif analysis that identifies specific named node triples — not just abstract type counts.
The result is a single package that covers the full workflow from data import to publication-ready output, while remaining interoperable with the rest of the R network ecosystem.
set.seed(42)
n <- 10
states <- c("Explore", "Plan", "Monitor", "Adapt", "Reflect",
"Discuss", "Synthesize", "Evaluate", "Create", "Share")
mat <- matrix(0, n, n, dimnames = list(states, states))
# Sparse: ~30% of edges populated
edges <- sample(which(row(mat) != col(mat)), 30)
mat[edges] <- round(runif(30, 0.05, 0.5), 2)splot() is the main plotting function. One call,
publication-ready output.
Key parameters: layout, minimum,
node_fill, node_size,
edge_labels, curvature,
scale_nodes_by, theme,
tna_styling.
splot(mat, layout = "spring")
splot(mat, minimum = 0.1, edge_labels = TRUE)
splot(mat, scale_nodes_by = "betweenness")
splot(mat, theme = "dark")
splot(mat, tna_styling = TRUE)Layouts: "oval", "spring",
"circle", "grid", "mds",
"star", "bipartite", "groups", or
a custom coordinate matrix.
Themes: "default", "dark",
"minimal", "gray", "nature",
"colorblind", "viridis".
Node shapes: "circle", "square",
"triangle", "diamond",
"pentagon", "hexagon", "star",
"heart", "ellipse", "cross",
"rectangle", "pie", "donut", or
custom SVG via register_svg_shape().
| Function | Purpose |
|---|---|
splot() |
Network graph (base R) |
soplot() |
Grid/ggplot2 network |
plot_tna() / tplot() |
TNA-style wrappers with qgraph-compatible parameters |
plot_chord() |
Chord diagram (directed/undirected ribbons) |
plot_heatmap() |
Adjacency heatmap with clustering |
plot_ml_heatmap() |
Multi-layer comparison heatmap |
plot_transitions() / plot_alluvial() |
Alluvial / Sankey flow diagrams |
plot_trajectories() |
Individual trajectory tracking |
plot_compare() |
Difference network between two matrices |
plot_comparison_heatmap() |
Side-by-side heatmap comparison |
plot_mixed_network() |
Directed + undirected edges combined |
plot_bootstrap_forest() |
Bootstrap CI forest plots (linear, circular, grouped) |
plot_edge_diff_forest() |
Edge difference plots (linear, circular, chord, tile) |
plot_simplicial() |
Higher-order pathway blob overlays |
overlay_communities() |
Community blob overlays on network |
plot_mcml() |
Two-layer hierarchical cluster visualization |
plot_mtna() |
Flat multi-cluster layout |
plot_mlna() |
Stacked multilayer 3D perspective |
plot_htna() |
Multi-group heterogeneous TNA layout |
plot_robustness() |
Robustness degradation curves |
plot_permutation() /
plot_group_permutation() |
Permutation test results |
plot_simplicial(mat,
c("Explore Plan -> Monitor",
"Monitor Adapt -> Reflect",
"Discuss Synthesize -> Evaluate",
"Create Share -> Explore"),
dismantled = TRUE, ncol = 2,
title = "Higher-Order Pathways")Every function accepts six formats directly.
| Format | Example |
|---|---|
| Matrix | splot(mat) |
| Edge list | splot(data.frame(from = "A", to = "B", weight = 1)) |
| igraph | splot(igraph::make_ring(5)) |
| statnet | splot(network::network(mat)) |
| qgraph | from_qgraph(q) |
| tna | splot(tna::tna(data)) |
Conversion utilities:
| Function | Output |
|---|---|
as_cograph(x) |
cograph_network object |
to_igraph(x) |
igraph object |
to_matrix(x) |
Adjacency matrix |
to_data_frame(x) / to_df(x) |
Edge list data frame |
to_network(x) |
statnet network object |
from_qgraph(q) |
Extract qgraph styles into cograph |
Filter edges and nodes with expressions. Centrality measures are
lazy-computed inside filter_nodes().
strong <- filter_edges(mat, weight > 0.3)
get_edges(strong)
#> from to weight
#> 1 8 3 0.33
#> 2 10 3 0.49
#> 3 8 4 0.43
#> 4 10 4 0.39
#> 5 1 5 0.35
#> 6 6 5 0.35
#> 7 7 5 0.42
#> 8 2 6 0.40
#> 9 4 6 0.34
#> 10 2 8 0.49
#> 11 9 8 0.39
#> 12 3 9 0.37
#> 13 2 10 0.36top3 <- select_nodes(mat, top = 3, by = "betweenness")
get_labels(top3)
#> [1] "Plan" "Monitor" "Adapt"| Function | Purpose |
|---|---|
filter_edges(x, ...) |
Filter by weight, from, to |
filter_nodes(x, ...) |
Filter by degree, centrality, label |
select_nodes(x, ...) |
Top-N by centrality, by name, neighbors |
select_edges(x, ...) |
Top-N, involving, between, bridges, mutual |
select_neighbors(x, of) |
Ego-network extraction (multi-hop) |
select_component(x) |
Largest or named component |
select_top(x, n, by) |
Top-N nodes by any centrality |
select_bridges(x) |
Bridge edges only |
select_top_edges(x, n) |
Top-N edges by weight |
select_edges_involving(x, nodes) |
Edges touching specific nodes |
select_edges_between(x, s1, s2) |
Edges between two node sets |
subset_nodes(x, ...) /
subset_edges(x, ...) |
Base R-style subsetting |
simplify(x) |
Remove multi-edges and self-loops |
Getters and setters:
| Function | Purpose |
|---|---|
get_nodes(x) / set_nodes(x, df) |
Node data frame |
get_edges(x) / set_edges(x, df) |
Edge data frame |
get_labels(x) |
Node label vector |
n_nodes(x) / n_edges(x) |
Counts |
is_directed(x) |
Directedness |
set_groups(x) / get_groups(x) |
Group assignments |
set_layout(x, layout) |
Layout coordinates |
summarize_network(x) |
Network summary |
centrality() computes up to 25 measures and returns a
data frame.
centrality(mat, measures = c("degree", "betweenness", "pagerank"))
#> node degree_all betweenness pagerank
#> 1 Explore 6 5.0 0.11846147
#> 2 Plan 7 15.5 0.03640953
#> 3 Monitor 8 18.0 0.18376724
#> 4 Adapt 6 15.0 0.12356096
#> 5 Reflect 6 10.0 0.12513119
#> 6 Discuss 5 0.5 0.06803638
#> 7 Synthesize 4 6.5 0.03760071
#> 8 Evaluate 5 3.0 0.07386400
#> 9 Create 7 13.0 0.13821279
#> 10 Share 6 9.0 0.09495573Individual functions return named vectors:
centrality_degree(mat)
#> Explore Plan Monitor Adapt Reflect Discuss Synthesize
#> 6 7 8 6 6 5 4
#> Evaluate Create Share
#> 5 7 6
centrality_pagerank(mat)
#> Explore Plan Monitor Adapt Reflect Discuss Synthesize
#> 0.11846147 0.03640953 0.18376724 0.12356096 0.12513119 0.06803638 0.03760071
#> Evaluate Create Share
#> 0.07386400 0.13821279 0.09495573All 25 measures:
| Category | Functions |
|---|---|
| Degree | centrality_degree(),
centrality_strength(), centrality_indegree(),
centrality_outdegree(),
centrality_instrength(),
centrality_outstrength() |
| Path | centrality_betweenness(),
centrality_closeness(), centrality_harmonic(),
centrality_eccentricity() (each with in/out variants) |
| Spectral | centrality_eigenvector(),
centrality_pagerank(), centrality_authority(),
centrality_hub(), centrality_alpha(),
centrality_power(), centrality_subgraph() |
| Structural | centrality_coreness(),
centrality_constraint(),
centrality_transitivity(),
centrality_laplacian() |
| Flow | centrality_current_flow_closeness(),
centrality_current_flow_betweenness(),
centrality_load() |
| Spreading | centrality_diffusion(),
centrality_leverage(), centrality_kreach(),
centrality_voterank(),
centrality_percolation() |
Edge centrality: edge_centrality(),
edge_betweenness().
network_summary() computes up to 37 network-level
metrics.
network_summary(mat)
#> node_count edge_count density component_count diameter mean_distance min_cut
#> 1 10 30 0.333 1 0.97 0.435 1
#> centralization_degree centralization_in_degree centralization_out_degree
#> 1 0.123 0.333 0.222
#> centralization_betweenness centralization_closeness centralization_eigen
#> 1 0.149 0.238 0.479
#> transitivity reciprocity assortativity_degree hub_score authority_score
#> 1 0.423 0.111 -0.116 NA NA| Function | Purpose |
|---|---|
network_summary() |
37 metrics (density, diameter, clustering, etc.) |
network_small_world() |
Small-world coefficient |
network_rich_club() |
Rich-club coefficient |
network_global_efficiency() |
Global efficiency |
network_local_efficiency() |
Local efficiency |
degree_distribution() |
Degree histogram |
network_girth() |
Shortest cycle |
network_radius() |
Minimum eccentricity |
network_bridges() |
Bridge edges |
network_cut_vertices() |
Articulation points |
network_vertex_connectivity() |
Minimum vertices to disconnect |
network_clique_size() |
Largest complete subgraph |
11 algorithms with a consistent interface.
comms <- communities(mat, method = "walktrap")
comms
#> Community structure (walktrap)
#> Nodes: 10 | Communities: 2 | Modularity: 0.1976
#> Sizes: 5, 5
#>
#> node community
#> Explore 1
#> Plan 2
#> Monitor 2
#> Adapt 1
#> Reflect 1
#> Discuss 1
#> Synthesize 1
#> Evaluate 2
#> Create 2
#> Share 2
community_sizes(comms)
#> [1] 5 5| Function | Algorithm | Alias |
|---|---|---|
community_louvain() |
Louvain modularity | com_lv() |
community_leiden() |
Leiden (improved Louvain) | com_ld() |
community_fast_greedy() |
Fast greedy | com_fg() |
community_walktrap() |
Random walk | com_wt() |
community_infomap() |
Information flow | com_im() |
community_label_propagation() |
Label propagation | com_lp() |
community_edge_betweenness() |
Edge betweenness | com_eb() |
community_leading_eigenvector() |
Leading eigenvector | com_le() |
community_spinglass() |
Spin glass | com_sg() |
community_optimal() |
Exact optimization | com_op() |
community_fluid() |
Fluid communities | com_fl() |
Additional community functions:
| Function | Purpose |
|---|---|
community_consensus() |
Run algorithm N times, keep stable assignments |
compare_communities() |
Compare partitions (NMI, VI, Rand, adjusted Rand) |
modularity() |
Modularity score |
community_sizes() |
Size of each community |
color_communities() |
Color vector from community membership |
cluster_quality() |
Quality metrics (silhouette, Dunn index) |
cluster_significance() |
Permutation-based significance testing |
detect_communities() |
Alternative interface (returns data frame) |
Motif analysis identifies recurring 3-node patterns using the MAN classification (16 directed triad types).
mot <- motifs(mat, significance = FALSE)
mot
#> Motif Census
#> Level: aggregate | States: 10 | Pattern: triangle
#>
#> Type distribution:
#>
#> 030C 030T 120C 120D 120U
#> 1 1 1 1 1
#>
#> Top 5 results:
#> type count
#> 030T 11
#> 120C 3
#> 030C 2
#> 120D 2
#> 120U 1| Function | Purpose |
|---|---|
motifs() |
MAN type census with significance testing |
subgraphs() |
Named node triples forming each pattern |
motif_census() |
Low-level triad census |
extract_motifs() |
Per-individual motif extraction |
extract_triads() |
Extract specific triad types |
triad_census() |
Raw 16-type triad count |
get_edge_list() |
Edge list from tna for motif input |
Plot types: plot(mot, type = "types"),
"significance", "triads",
"patterns".
Simulate network degradation under targeted and random removal.
robustness(mat, type = "vertex", measure = "betweenness", n_iter = 100)
plot_robustness(x = mat, measures = c("betweenness", "degree", "random"))| Function | Purpose |
|---|---|
robustness() |
Simulate removal attacks (vertex or edge) |
plot_robustness() |
Plot robustness curves for multiple strategies |
robustness_summary() |
AUC and summary statistics |
robustness_auc() |
Area under the robustness curve |
Backbone extraction using the disparity filter (Serrano et al. 2009).
clusters <- list(
Cognitive = c("Explore", "Plan", "Monitor", "Adapt", "Reflect"),
Social = c("Discuss", "Synthesize", "Share"),
Evaluative = c("Evaluate", "Create")
)
plot_mcml(mat, clusters, mode = "tna")
plot_mtna(mat, clusters)| Function | Architecture |
|---|---|
plot_mcml() |
Two-layer: detail nodes + summary pies |
plot_mtna() |
Flat cluster layout |
plot_mlna() |
Stacked 3D multilayer |
plot_htna() |
Multi-group heterogeneous TNA |
cluster_summary() / build_mcml() |
Pre-compute cluster aggregation |
as_tna() / as_mcml() |
Convert cluster summaries to tna objects |
cluster_network() |
Extract cluster-level network |
Construct and analyze supra-adjacency matrices for multilayer/multiplex networks.
| Function | Purpose |
|---|---|
mlna() / supra_adjacency() |
Build supra-adjacency matrix |
supra_layer() / supra_interlayer() |
Extract individual layers |
aggregate_layers() /
aggregate_weights() |
Combine layers |
plot_mlna() |
3D perspective visualization |
plot_ml_heatmap() |
Multi-layer heatmap comparison |
Detect sequential dependencies beyond first-order Markov models. Requires the Nestimate package.
| Function | Purpose |
|---|---|
build_hon() |
Higher-Order Network construction |
build_hypa() |
Path anomaly detection (hypergeometric null) |
build_mogen() |
Multi-order model selection (AIC/BIC) |
path_counts() |
k-step path frequencies |
plot_simplicial() |
Visualize pathways as blob overlays |
build_simplicial() |
Simplicial complex from cliques |
persistent_homology() |
Topological persistence across thresholds |
q_analysis() |
Multi-level structural connectivity |
verify_simplicial() |
Cross-validate via Euler-Poincare theorem |
Direct support for all tna package objects:
| Object | What splot() does |
|---|---|
tna |
Network with donut rings, TNA styling |
group_tna |
Multi-panel grid per group |
tna_bootstrap |
Stability-styled edges |
tna_permutation |
Colored difference network |
group_tna_permutation |
Multi-panel permutation results |
tna_disparity |
Backbone filter visualization |
| Function | Colors |
|---|---|
palette_viridis(n) |
Viridis scale |
palette_pastel(n) |
Soft pastel |
palette_blues(n) |
Blue gradient |
palette_reds(n) |
Red gradient |
palette_diverging(n) |
Blue-white-red |
palette_colorblind(n) |
Colorblind-safe |
palette_rainbow(n) |
Rainbow |
The sn_* functions provide a chainable builder for the
grid/ggplot2 rendering path.
mat |>
cograph() |>
sn_layout("spring") |>
sn_theme("minimal") |>
sn_nodes(size = 8, fill = "steelblue") |>
sn_edges(curvature = 0.2) |>
sn_render(title = "My Network")
mat |> cograph() |> sn_save("network.pdf")
p <- mat |> cograph() |> sn_ggplot()| Function | Purpose |
|---|---|
cograph() / as_cograph() |
Create network object |
sn_nodes() |
Node aesthetics |
sn_edges() |
Edge aesthetics |
sn_layout() |
Layout algorithm |
sn_theme() |
Visual theme |
sn_palette() |
Color palette |
sn_render() |
Render to screen |
sn_save() / sn_save_ggplot() |
Save to file |
sn_ggplot() |
Convert to ggplot2 object |
register_theme() / register_layout() /
register_shape() |
Register custom themes, layouts, shapes |
Package resources:
Blog posts:
References:
Saqr, M., López-Pernas, S., Conde, M. A., & Hernández-García, A. (2024). Social Network Analysis: A Primer, a Guide and a Tutorial in R. In Learning Analytics Methods and Tutorials. Springer. https://doi.org/10.1007/978-3-031-54464-4_15
Hernández-García, Á., Cuenca-Enrique, C., Traxler, A., López-Pernas, S., Conde-González, M. Á., & Saqr, M. (2024). Community detection in learning networks using R. In Learning Analytics Methods and Tutorials (pp. 519–540). Springer. https://doi.org/10.1007/978-3-031-54464-4_16
Saqr, M., López-Pernas, S., Törmänen, T., Kaliisa, R., Misiejuk, K., & Tikka, S. (2025). Transition Network Analysis: A Novel Framework for Modeling, Visualizing, and Identifying the Temporal Patterns of Learners and Learning Processes. In Proceedings of the 15th LAK Conference (pp. 351–361). ACM. https://doi.org/10.1145/3706468.3706513
Tikka, S., López-Pernas, S., & Saqr, M. (2025). tna: An R Package for Transition Network Analysis. Applied Psychological Measurement. https://doi.org/10.1177/01466216251348840
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.