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, ...)

Arguments

.data

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().

attribute

Name of a nodal attribute, mark, measure, or membership vector.

...

Not used, but kept for symmetry with net_x_triad().

Value

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.

Dyad census

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.

Triad census

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.

Tetrad census

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).

Splitting motifs

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.

Multilevel triad census

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.

References

On the dyad census

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

On the triad census

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

On the tetrad census

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

Examples

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>