Extract all triads from a network, preserving node labels. This allows users to see which specific node combinations form each motif pattern.
Usage
extract_triads(
x,
type = NULL,
involving = NULL,
threshold = 0,
min_total = 5,
directed = NULL
)Arguments
- x
A matrix, igraph object, tna, or cograph_network
- type
Character vector of MAN codes to filter by (e.g., "030T", "030C"). Default NULL returns all types.
- involving
Character vector of node labels. Only return triads involving at least one of these nodes. Default NULL returns all triads.
- threshold
Minimum edge weight for an edge to be considered present. Type is determined by edges with weight > threshold. Default 0.
- min_total
Minimum total weight across all 6 edges. Excludes trivial triads with low overall activity. Default 5.
- directed
Logical. Treat network as directed? Default auto-detected.
Value
A data frame with columns:
- A, B, C
Node labels for the three nodes in the triad
- type
MAN code (003, 012, ..., 300)
- weight_AB, weight_BA, weight_AC, weight_CA, weight_BC, weight_CB
Edge weights (frequencies) for all 6 possible directed edges
- total_weight
Sum of all 6 edge weights
Details
This function complements motif_census() by showing the actual node
combinations that form each motif pattern. A typical workflow is:
Use
motif_census()to identify over/under-represented patternsUse
extract_triads()withtypefilter to see which nodes form those patternsSort by
total_weightto find the strongest triads
Type vs Weight distinction:
Type is determined by edge presence (weight > threshold)
Weights are the actual frequency counts, useful for ranking triads by strength
Examples
# Create a frequency matrix
mat <- matrix(c(
0, 3, 2, 0,
0, 0, 5, 1,
0, 0, 0, 4,
2, 0, 0, 0
), 4, 4, byrow = TRUE)
rownames(mat) <- colnames(mat) <- c("Plan", "Execute", "Monitor", "Adapt")
net <- as_cograph(mat)
# Extract all triads
triads <- extract_triads(net)
head(triads)
#> A B C type weight_AB weight_BA weight_AC weight_CA
#> 1 Plan Execute Monitor 030T 3 0 2 0
#> 2 Plan Execute Adapt 030C 3 0 0 2
#> 3 Plan Monitor Adapt 030C 2 0 0 2
#> 4 Execute Monitor Adapt 030T 5 0 1 0
#> weight_BC weight_CB total_weight
#> 1 5 0 10
#> 2 1 0 6
#> 3 4 0 8
#> 4 4 0 10
# Filter by motif type (feed-forward loops only)
ff_loops <- extract_triads(net, type = "030T")
# Filter by node involvement
plan_triads <- extract_triads(net, involving = "Plan")
# Find strongest triads
triads <- extract_triads(net)
strongest <- triads[order(triads$total_weight, decreasing = TRUE), ]
