These functions include ways to take a census of the positions of nodes in a network:
node_x_dyad() returns a census of the dyad configurations
nodes are embedded in.
node_x_triad() returns a census of the triad configurations
nodes are embedded in.
node_x_tetrad() returns a census of nodes' positions
in motifs of four nodes.
The sections below first say how to read each census,
and then how signs, layers, and attributes add to it.
The node_x_*() functions use the same labels as the net_x_*() functions,
with one row per node, counting the motifs that each node takes part in.
They do not tell apart the positions a node can hold within a motif,
so in the chain A->B->C all three nodes count one 021C.
node_x_dyad(.data, attribute = NULL, ...)
node_x_triad(.data, attribute = NULL, ...)
node_x_tetrad(.data, attribute = NULL, ...)A network object of class stocnet, igraph, tbl_graph, network, or similar.
Internally any of these will be coerced to an efficient implementation.
For more information on possible coercions, see e.g. manynet::as_stocnet().
Name of a nodal attribute, mark, measure, or membership vector.
Not used, but kept for symmetry with net_x_triad().
A node_motif matrix with one row for each node in the network and
a column for each motif type,
giving the count of each motif in which each node participates.
It is printed as a tibble, however, to avoid greedy printing.
If the network is labelled,
then the node names will be in a column named names.
The dyad census counts each pair of nodes by the ties between them, using the MAN labels of Holland and Leinhardt (1970):
Mutual: a tie in both directions
Asymmetric: a tie in one direction only
Null: no tie
In an undirected or two-mode network every tie is mutual,
so only Mutual and Null are reported.
The triad census counts each set of three nodes by the ties among them, using the labels of Davis and Leinhardt (1967) and Holland and Leinhardt (1970). The three digits give the number of mutual, asymmetric, and null dyads in the triad, and a letter tells apart triads with the same digits: D(own), U(p), C(yclic), or T(ransitive).
003: no ties
012: one asymmetric tie, A->B
102: one mutual tie, A<->B
021D: A<-B->C, one node sending to the two others
021U: A->B<-C, one node receiving from the two others
021C: A->B->C, a chain
111D: A<->B<-C
111U: A<->B->C
030T: A->B<-C and A->C, a transitive triad
030C: A<-B<-C and A->C, a cycle
201: A<->B<->C, with A and C not tied
120D: A<-B->C and A<->C
120U: A->B<-C and A<->C
120C: A->B->C and A<->C
210: A->B<->C and A<->C
300: A<->B<->C and A<->C, all ties mutual
In an undirected network every tie is read as mutual,
so only 003, 102, 201, and 300 can occur.
The tetrad census counts each set of four nodes by the ties among them. Ties are read as undirected. Each label gives a letter whose shape recalls the motif, and the number of nodes:
E4 (co-K4): no ties
I4 (co-diamond): one tie
H4 (co-C4): two ties that share no node
L4 (co-paw): two ties that share a node, and an isolate
D4 (co-claw): a triangle, and an isolate
U4 (P4): three ties in a line
Y4 (claw): three ties from one node
P4 (paw): a triangle, with one more tie to the fourth node
C4 (C4): four ties in a cycle
Z4 (diamond): a cycle with one diagonal
X4 (K4): all six ties
See also graph classes and McMillan and Felmlee (2020).
For signed networks, dyads and triads are split by the signs of
their ties.
Each label is followed by the signs of the motif's ties, e.g. 300_++-
for a triangle with one negative tie, or Mutual_+- for a mutual dyad
whose two ties differ in sign.
The ties are listed in a fixed order over the motif's positions
(1-2, 1-3, 2-1, 2-3, 3-1, 3-2 in a directed triad;
1-2, 1-3, 2-3 in an undirected one), skipping the pairs that are not
tied, with the positions ordered so that ties, and then positive ties,
come as early as they can.
A pair holding both a positive and a negative tie counts as negative.
The tetrad census sets signs aside.
Only the motifs that occur are reported.
Summing the variants of a motif gives the unsigned census.
Use manynet::to_unsigned() first for a coarser census.
For multiplex networks, which hold several one-mode layers,
dyads and triads are split by the layers of their ties.
Each layer is given a letter, the first letter of its name where these
differ, and the letters are kept in the "layers" attribute of the result.
Each tie lists the letters of the layers that carry it, separated from the
next tie by a ., in the order described for signed networks.
A lowercase letter marks a positive tie and an uppercase letter a
negative one, so 201_f.ft is a two-path, one of whose ties is in the
friends layer, and the other in both the friends and tasks layers.
Only the motifs that occur are reported.
Summing the variants of a motif gives the census of all layers together.
Use manynet::to_uniplex() first for a census of one layer.
The tetrad census counts every tie whatever its layer.
Where an attribute is given, each motif is further split by how its
nodes compare on that attribute, after any signs or layers.
The comparison is given for each pair of positions in turn
(1-2 in a dyad; 1-2, 1-3, 2-3 in a triad;
1-2, 1-3, 1-4, 2-3, 2-4, 3-4 in a tetrad), using the same order of
positions as the ties.
For a categorical attribute (character, factor, or logical),
= marks a pair that shares a category and ! a pair that does not,
so 021D_!!= is a node sending ties to two nodes that share a category
other than its own.
Missing values are a category of their own.
For an ordered attribute (numeric, or an ordered factor),
<, =, and > mark whether the first of the pair is lower than,
equal to, or higher than the second, so 021D_>>< is a node sending ties
to two nodes with lower values than its own.
Missing values cannot be compared, so are not allowed.
A numeric attribute that codes categories should be passed through
as.factor() first.
Since only these comparisons are kept, an attribute may have any number of categories or values. Only the motifs that occur are reported, and summing the variants of a motif gives the census without the attribute. To see which categories take part in which motifs, take a node census and summarise its rows by the attribute.
For multilevel networks that hold exactly one one-mode layer and one
two-mode layer, such as fict_marvel, the triad census is instead the
multilevel census of Hollway et al. (2017), over triads of two nodes of
the first mode and one of the second.
Its ten motifs are labelled by two digits: first, how many of the two
first-mode nodes are tied to the second-mode node (2, 1, or 0);
second, the tie between the two first-mode nodes
(2 mutual, 1 asymmetric, 0 none):
22, 21, 20, 12, 11D, 11U, 10, 02, 01, 00.
So 21 counts pairs tied in one direction that share an affiliation.
Where only one of the pair is affiliated and the tie is asymmetric,
11D has the affiliated node sending the tie, and 11U receiving it.
This census sets weights and signs aside, and takes no attribute.
Passing the one-mode and two-mode networks separately still works,
but is deprecated.
Other combinations of one-mode and two-mode layers are not yet available.
Holland, Paul W., and Samuel Leinhardt. 1970. "A Method for Detecting Structure in Sociometric Data". American Journal of Sociology, 76: 492-513. doi:10.1016/B978-0-12-442450-0.50028-6
Davis, James A., and Samuel Leinhardt. 1967. “The Structure of Positive Interpersonal Relations in Small Groups.” 55.
Schoch, David. 2023. "signnet: An R package for analyzing signed networks". Journal of Open Source Software 8(81): 4987. doi:10.21105/joss.04987
Hollway, James, Alessandro Lomi, Francesca Pallotti, and Christoph Stadtfeld. 2017. “Multilevel Social Spaces: The Network Dynamics of Organizational Fields.” Network Science 5(2): 187–212. doi:10.1017/nws.2017.8
Ortmann, Mark, and Ulrik Brandes. 2017. “Efficient Orbit-Aware Triad and Quad Census in Directed and Undirected Graphs.” Applied Network Science 2(1):13. doi:10.1007/s41109-017-0027-2 .
McMillan, Cassie, and Diane Felmlee. 2020. "Beyond Dyads and Triads: A Comparison of Tetrads in Twenty Social Networks". Social Psychology Quarterly 83(4): 383-404. doi:10.1177/0190272520944151
Other cohesion:
mark_triangles,
measure_breadth,
measure_cohesion,
measure_fragmentation,
motif_net
Other motifs:
motif_accuracy_node,
motif_brokerage_net,
motif_brokerage_node,
motif_clique,
motif_composition,
motif_exposure,
motif_hazard,
motif_hierarchy,
motif_homophily,
motif_net,
motif_path,
motif_periods
Other nodal:
mark_core,
mark_degree,
mark_diff,
mark_nodes,
mark_select_node,
measure_accuracy_node,
measure_assort_node,
measure_broker_node,
measure_brokerage,
measure_central_between,
measure_central_close,
measure_central_degree,
measure_central_eigen,
measure_closure_node,
measure_core,
measure_diffusion_node,
measure_diverse_node,
member_brokerage,
member_cliques,
member_community,
member_community_hier,
member_community_modular,
member_community_partition,
member_community_spread,
member_components,
member_core,
member_diffusion,
member_equivalence,
motif_accuracy_node,
motif_brokerage_node,
motif_clique,
motif_composition,
motif_exposure,
motif_path
node_x_dyad(ison_networkers)
#> # A tibble: 32 × 4
#> names Mutual Asymmetric Null
#> <chr> <dbl> <dbl> <dbl>
#> 1 Lin Freeman 29 2 0
#> 2 Doug White 21 10 0
#> 3 Ev Rogers 3 8 20
#> 4 Richard Alba 17 2 12
#> 5 Phipps Arabie 8 20 3
#> 6 Carol Barner-Barry 12 4 15
#> # ℹ 26 more rows
node_x_dyad(ison_networkers, attribute = "Discipline")
#> # A tibble: 32 × 7
#> names Mutual_. Mutual_..1 Asymmetric_. Asymmetric_..1 Null_. Null_..1
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 Lin Freeman 15 14 0 2 0 0
#> 2 Doug White 17 4 9 1 0 0
#> 3 Ev Rogers 3 0 5 3 18 2
#> 4 Richard Alba 10 7 1 1 4 8
#> 5 Phipps Arabie 7 1 16 4 3 0
#> 6 Carol Barner-… 10 2 3 1 13 2
#> # ℹ 26 more rows
task_eg <- to_named(to_uniplex(ison_algebra, "tasks"))
(triad_cen <- node_x_triad(task_eg))
#> # A tibble: 16 × 17
#> names X003 X012 X102 X021D X021U X021C X111D X111U X030T X030C X201 X120D
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 Abrah… 23 11 39 0 0 0 2 2 0 0 17 0
#> 2 Belle 21 6 47 0 0 0 5 6 0 0 10 0
#> 3 Charl… 34 3 46 0 0 0 2 1 0 0 13 0
#> 4 Dawson 52 6 28 0 0 0 0 0 0 0 18 0
#> 5 Eileen 17 11 37 1 0 1 6 7 0 0 15 1
#> 6 Franc… 23 8 40 1 0 0 3 3 0 0 18 1
#> # ℹ 10 more rows
#> # ℹ 4 more variables: X120U <dbl>, X120C <dbl>, X210 <dbl>, X300 <dbl>
node_x_tetrad(ison_southern_women)
#> # A tibble: 18 × 12
#> names E4 I4 H4 L4 D4 U4 Y4 P4 C4 Z4 X4
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 Evelyn 1241 1347 176 1138 0 272 246 0 75 0 0
#> 2 Laura 1365 1389 180 1077 0 213 203 0 68 0 0
#> 3 Theresa 1333 1244 123 1137 0 286 281 0 91 0 0
#> 4 Brenda 1384 1356 176 1093 0 210 205 0 71 0 0
#> 5 Charlotte 1728 1562 157 836 0 117 74 0 21 0 0
#> 6 Frances 1840 1433 114 810 0 134 134 0 30 0 0
#> # ℹ 12 more rows
#> # A tibble: 14 × 12
#> names E4 I4 H4 L4 D4 U4 Y4 P4 C4 Z4 X4
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 E1 1877 1632 96 710 0 113 52 0 15 0 0
#> 2 E2 1886 1631 84 698 0 122 58 0 16 0 0
#> 3 E3 1368 1611 190 1006 0 168 98 0 54 0 0
#> 4 E4 1681 1673 131 784 0 138 64 0 24 0 0
#> 5 E5 1061 1557 232 1208 0 216 140 0 81 0 0
#> 6 E6 1085 1576 178 1142 0 287 156 0 71 0 0
#> # ℹ 8 more rows
node_x_tetrad(ison_adolescents, attribute = rep(c("x", "y"), 4))
#> # A tibble: 8 × 23
#> names E4_...... E4_.......1 I4_...... I4_.......1 I4_.......2 I4_.......3
#> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 Betty 1 1 6 7 1 1
#> 2 Sue 0 0 2 1 0 1
#> 3 Alice 0 0 2 2 1 1
#> 4 Jane 1 0 5 6 0 1
#> 5 Dale 0 1 4 2 1 1
#> 6 Pam 1 1 2 3 0 1
#> # ℹ 2 more rows
#> # ℹ 16 more variables: H4_...... <dbl>, H4_.......1 <dbl>, L4_...... <dbl>,
#> # L4_.......1 <dbl>, L4_.......2 <dbl>, L4_.......3 <dbl>, D4_...... <dbl>,
#> # D4_.......1 <dbl>, U4_...... <dbl>, U4_.......1 <dbl>, U4_.......2 <dbl>,
#> # Y4_...... <dbl>, P4_...... <dbl>, P4_.......1 <dbl>, Z4_...... <dbl>,
#> # Z4_.......1 <dbl>