These functions include ways to take a census of the motifs in a network:

  • net_x_dyad() returns a census of dyad motifs in a network.

  • net_x_triad() returns a census of triad motifs in a network.

  • net_x_tetrad() returns a census of tetrad motifs in a network.

The sections below first say how to read each census, and then how signs, layers, and attributes add to it.

net_x_dyad(.data, attribute = NULL, ...)

net_x_triad(.data, attribute = NULL, ...)

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

...

Only net_x_triad() reads this, and only to take a second, two-mode network for the mixed census, which is deprecated; see the section on multiplex and multilevel networks.

Value

A network_motif named numeric vector or sometimes a data frame with one row and a column for each motif type, giving the count of each motif in the network. This is printed as a tibble to avoid greedy printing of long vectors.

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 signed and attributed censuses

Schoch, David. 2023. "signnet: An R package for analyzing signed networks". Journal of Open Source Software 8(81): 4987. doi:10.21105/joss.04987

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

Wasserman, Stanley, and Katherine Faust. 1994. "Social Network Analysis: Methods and Applications". Cambridge: Cambridge University Press.

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

net_x_dyad(manynet::ison_algebra)
#> # A tibble: 1 × 13
#>   Mutual_f.f Mutual_s.s Mutual_sf.s Mutual_sf.st Mutual_st.s Mutual_st.st
#>        <dbl>      <dbl>       <dbl>        <dbl>       <dbl>        <dbl>
#> 1          2         13           8            2           2           12
#> # ℹ 7 more variables: Mutual_st.t <dbl>, Mutual_stf.st <dbl>,
#> #   Mutual_stf.stf <dbl>, Asymmetric_f <dbl>, Asymmetric_s <dbl>,
#> #   Asymmetric_t <dbl>, Null <dbl>
net_x_triad(manynet::ison_adolescents)
#> # A tibble: 1 × 6
#>   `003` `012` `102` `201` `210` `300`
#>   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1    13     0    29    11     0     3
net_x_triad(ison_networkers, attribute = "Discipline")
#> # A tibble: 1 × 65
#>   `003_!!!` `003_!!=` `003_===` `012_!!!` `012_!!=` `012_!=!` `012_=!!`
#>       <dbl>     <dbl>     <dbl>     <dbl>     <dbl>     <dbl>     <dbl>
#> 1       260       563       173       115        94        74        96
#> # ℹ 58 more variables: `012_===` <dbl>, `102_!!!` <dbl>, `102_!!=` <dbl>,
#> #   `102_=!!` <dbl>, `102_===` <dbl>, `021D_!!!` <dbl>, `021D_!!=` <dbl>,
#> #   `021D_!=!` <dbl>, `021D_===` <dbl>, `021U_!!!` <dbl>, `021U_!!=` <dbl>,
#> #   `021U_!=!` <dbl>, `021U_===` <dbl>, `021C_!!!` <dbl>, `021C_!!=` <dbl>,
#> #   `021C_!=!` <dbl>, `021C_=!!` <dbl>, `021C_===` <dbl>, `111D_!!!` <dbl>,
#> #   `111D_!!=` <dbl>, `111D_!=!` <dbl>, `111D_=!!` <dbl>, `111D_===` <dbl>,
#> #   `111U_!!!` <dbl>, `111U_!!=` <dbl>, `111U_!=!` <dbl>, `111U_=!!` <dbl>, …
net_x_triad(to_uniplex(fict_marvel, "relationship"))
#> # A tibble: 1 × 10
#>   `003` `102_+` `102_-` `201_++` `201_+-` `201_--` `300_+++` `300_++-` `300_+--`
#>   <dbl>   <dbl>   <dbl>    <dbl>    <dbl>    <dbl>     <dbl>     <dbl>     <dbl>
#> 1  7304    3860    5561      998     1977     1661       436       287       944
#> # ℹ 1 more variable: `300_---` <dbl>
net_x_triad(fict_marvel)
#> # A tibble: 1 × 10
#>    `22`  `21`  `20`  `12` `11D` `11U`  `10`  `02`  `01`   `00`
#>   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>  <dbl>
#> 1  1248     0  1591 10289     0     0 19549 47683     0 113938
net_x_tetrad(ison_southern_women)
#> # A tibble: 1 × 11
#>      E4    I4    H4    L4    D4    U4    Y4    P4    C4    Z4    X4
#>   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 12388 11869  1146  7458     0  1552  1206     0   341     0     0