These functions offer tools for projecting manynet-consistent data:
to_mode() projects a two-mode network to a one-mode network
of the node set given by the mode argument, which accepts either the
index of the mode or its name.
to_mode1() projects a two-mode network to a one-mode network
of the first node set's (e.g. rows) joint affiliations to nodes in the second node set (columns).
to_mode2() projects a two-mode network to a one-mode network
of the second node set's (e.g. columns) joint affiliations to nodes in the first node set (rows).
to_linegraph() projects a network to its line graph,
where the ties become nodes and incident nodes become their ties.
to_hypergraph() projects one-mode or two-mode network data into hypergraph data,
where ties can connect more than two nodes.
to_mode1(
.data,
similarity = c("count", "jaccard", "rand", "pearson", "yule", "match", "overlap",
"crossmin", "maxcrossmin", "sqdiff", "covariance", "bonacich", "ochiai", "ochiai2",
"czekanowski", "sokalsneath", "hamann", "rogerstanimoto", "euclidean", "manhattan",
"hamming", "cosine", "spearman", "kendall")
)
to_mode2(
.data,
similarity = c("count", "jaccard", "rand", "pearson", "yule", "match", "overlap",
"crossmin", "maxcrossmin", "sqdiff", "covariance", "bonacich", "ochiai", "ochiai2",
"czekanowski", "sokalsneath", "hamann", "rogerstanimoto", "euclidean", "manhattan",
"hamming", "cosine", "spearman", "kendall")
)
to_mode(
.data,
mode = 1,
similarity = c("count", "jaccard", "rand", "pearson", "yule", "match", "overlap",
"crossmin", "maxcrossmin", "sqdiff", "covariance", "bonacich", "ochiai", "ochiai2",
"czekanowski", "sokalsneath", "hamann", "rogerstanimoto", "euclidean", "manhattan",
"hamming", "cosine", "spearman", "kendall")
)
to_linegraph(.data)
to_hypergraph(.data)An object of a {manynet}-consistent class:
adjacency or incidence matrix from {base} R
edgelist data.frame from {base} R or tbl/tbl_df from {tibble}
stocnet stocnet, from the {manynet} package
igraph igraph, from the {igraph} package
network network, from the {network} package
tidygraph tbl_graph, from the {tidygraph} package
Method for establishing ties in the projection, "count" by default.
The measures are grouped below by what they are sensitive to. Within a group they are monotone transformations of one another, and so rank dyads identically, differing only in their scale. Choosing between the groups therefore matters rather more than choosing within one.
Measures defined for valued as well as binary data:
"count" counts the coinciding ties, the cross-product \(XX'\).
For valued data it sums the products of tie strengths.
Interpret it as the degree of opportunity between two nodes.
This is the default, and the quickest, since it can use
igraph::bipartite_projection() directly.
"match" counts the cells in which two nodes hold exactly the same value, joint absences included. For binary data this is "rand" multiplied by the number of nodes in the other mode, but for valued data it is the more general measure, since it registers agreement at any tie strength. Use it where the level of involvement is meaningful in itself.
"overlap" divides the count by the smaller of the two nodes' total tie strength, the Szymkiewicz-Simpson coefficient. Use it where one node is much more active than the other, and the less active node's rarity should not depress the score.
"crossmin" sums the smaller of each pair of tie strengths. Interpret it as the capacity two nodes could jointly bring to bear. For binary data it reduces to "count".
"maxcrossmin" takes the largest such minimum rather than their sum, so that a single strong shared affiliation stands for the pair. For binary data it collapses to an indicator of any shared affiliation, and so is of little use there.
"sqdiff" inverts the sum of squared differences in tie strength, as \(1/(1+d)\), so that identical rows give 1 and larger values mean more alike, as for every other measure here. Recover the raw sum of squared differences as \(1/x - 1\).
"pearson" gives Pearson's product-moment correlation and "covariance" its unstandardised counterpart. Use "covariance" where the variance in involvement is itself of interest, and "pearson" where it is not.
"spearman" and "kendall" are the rank counterparts of "pearson". Use them where tie strengths order the affiliations reliably but their spacing does not, as with ordinal ratings.
"cosine" gives the cosine of the angle between two nodes' rows. It differs from "pearson" in not centring them first, so that it reads two nodes as alike where their involvements are proportional rather than where they depart from the average in the same direction. For binary data it agrees with "ochiai", except that a node with no ties at all is reported as no more similar to another than any other node, where "ochiai" would divide by zero.
"euclidean" and "manhattan" invert the straight-line and the city-block distance between two rows, again as \(1/(1+d)\). "manhattan" sums the absolute differences in tie strength, so that a large discrepancy on one affiliation counts no more than the same total spread over several; "euclidean" penalises the concentrated discrepancy more heavily, as "sqdiff" does. Recover either raw distance as \(1/x - 1\).
Measures defined for binary data only, where a valued network is dichotomised at zero with a warning. Writing \(a\) for the cells in which both nodes are present, \(b\) and \(c\) for those in which just one is, and \(d\) for those in which neither is:
Sensitive to co-presence, ignoring joint absence: "jaccard" is \(a/(a+b+c)\), opportunity weighted by participation; "czekanowski" (the Dice or Sorensen coefficient) is \(2a/(2a+b+c)\), which double-weights co-presence; and "sokalsneath" is \(a/(a+2(b+c))\), which instead double-weights mismatch. Use these where joint non-participation says nothing, as in a sparse affiliation network with many events.
Sensitive to matching, counting joint absence as evidence: "rand", the Simple Matching Coefficient, is \((a+d)/(a+b+c+d)\); "hamann" is \(((a+d)-(b+c))/(a+b+c+d)\), the same quantity rescaled onto \([-1,1]\) so that its sign reports whether matches outnumber mismatches; and "rogerstanimoto" is \((a+d)/(a+2(b+c)+d)\), which double-weights mismatch. Interpret these as the degree of behavioural mirroring between two nodes, and use them where not attending is as informative as attending.
Sensitive to association, through the odds ratio \(ad/bc\): "yule" is Yule's Q, \((ad-bc)/(ad+bc)\), which has a straightforward reading as a rescaled odds ratio; and "bonacich" is \(\sqrt{ad}/(\sqrt{ad}+\sqrt{bc})\), which is Yule's Y rescaled onto \([0,1]\). Both saturate at 1 wherever \(b\) or \(c\) is zero.
Geometric: "ochiai" is \(a/\sqrt{(a+b)(a+c)}\), the cosine of the angle between two nodes' affiliation vectors, and "ochiai2" (also known as Sokal and Sneath's fifth measure) is \(ad/\sqrt{(a+b)(a+c)(d+b)(d+c)}\), its counterpart including joint absence. Neither is monotone in any of the above, so both are worth trying alongside them.
"hamming" inverts the Hamming distance, the number of cells in which the two nodes differ, as \(1/(1+d)\). It is a monotone transformation of "rand", and so ranks dyads identically, but states the disagreement as a count rather than as a proportion of agreement.
Which mode to project the network to, either as an index, 1 or 2, or as the name of the mode. Mode 1 is the first node set, e.g. the rows, and is the default.
A name is matched against the names of the modes,
which mode_names() returns and add_info() sets.
The match ignores case, plurals, and any other words in the name,
so that a network whose modes are named "women" and "social events"
can be projected with either "social events", "events", or "event".
Where a name matches both modes, as "events" would where they are named
"social events" and "work events", the function reports the ambiguity
and asks for a name that tells them apart, or an index.
The network must have two modes. Projecting one mode of a network of three or more would need a second mode to project through, which this function does not yet accept, so it reports the modes it found instead.
An object of the same class as the function was given, modified as explained in the function description, details, or section. Functions that split a network return a list of such objects.
Not all functions have methods available for all object classes. Below are the currently implemented S3 methods:
| Category | Feature | manynet::to_mode1()/to_mode2() | igraph::bipartite_projection() | network/sna manual |
| Input | Dedicated function | yes | yes | no |
| Accepted input classes | igraph, network, tidygraph, matrix, edgelist | igraph only | any (manual extraction) | |
| Detects mode membership from | mode node attribute | type vertex attribute | bipartite network attr (positional) | |
| Projection | Returns both projections at once | no — one per call | yes — list of two | two manual calls |
| Projects mode 1 (actors) | to_mode1() | which = "true" | A %*% t(A) | |
| Projects mode 2 (events) | to_mode2() | which = "false" | t(A) %*% A | |
| Weights | Raw co-membership counts | yes | yes (multiplicity = TRUE) | yes |
| Binary (unweighted) output | yes | yes (multiplicity = FALSE) | threshold manually | |
| Jaccard normalisation | yes | no | code manually | |
| Cosine normalisation | yes | no | code manually | |
| Other similarity measures | 24 in all, see similarity | no | code manually | |
| Attributes | Retains node attributes | yes | yes | no — lost in matrix round-trip |
| Retains edge attributes | weight only | weight only | no | |
| Removes self-loops automatically | yes | yes | diag(P) <- 0 manually | |
| Output | Output class matches input | yes | no | no |
| Directed projection support | limited | no — undirected only | yes — asymmetric matrix | |
| Usability | Lines of code (basic case) | 1 | 1 | 4–6 |
| Lines of code (Jaccard weights) | 1 | ~8 manual | ~8 manual | |
| Pipe-friendly | yes | with wrappers | no |
This function projects one-mode or two-mode network data into hypergraph data, where ties can connect more than two nodes. The projection differs depending on whether the network is one-mode or two-mode, and the output can differ by class of the input/output data.
For two-mode networks, the hyperedges are the nodes of the second mode,
and the nodes of the first mode are connected to them if they share a tie.
In a 'stocnet' object, the hyperedges are stored in the ties data frame,
with the from column containing a list of nodes connected to each hyperedge.
This is thus a compact representation of the hypergraph.
igraph-like objects do not have a native representation of hyperedges,
so the output is a two-mode graph where the hyperedges are represented
as nodes of the second mode.
For one-mode networks, the hyperedges are the maximal cliques of the network. Again, while 'stocnet' objects can store the hyperedges in a compact form, igraph-like objects represent them as nodes of the second mode in a two-mode graph.
Borgatti, Stephen P., and Daniel S. Halgin. 2011. "Analyzing affiliation networks". In The SAGE Handbook of Social Network Analysis, 417-433. London: SAGE.
Bonacich, Phillip. 1972. "Technique for analyzing overlapping memberships". Sociological Methodology 4: 176-185. doi:10.2307/270732
to_proximity(), which applies these same measures to a one-mode
network, comparing nodes on their ties to one another rather than on
their affiliations to a second mode.
to_cosine(), which takes the cosine over the columns of a
matrix without projecting it.
Other modifications:
modif_backbone,
modif_direction,
modif_from,
modif_labels,
modif_levels,
modif_miss,
modif_motifs,
modif_paths,
modif_permutation,
modif_plexity,
modif_proximity,
modif_scope,
modif_split,
modif_weight
to_mode1(ison_southern_women)
#>
#> ── # Projection of Southern Women Data ─────────────────────────────────────────
#> # A labelled, weighted, undirected network of 18 womens and 139 co-social event
#> ties
#>
#> ── Nodes
#> # A tibble: 18 × 3
#> name Surname Title
#> <chr> <chr> <chr>
#> 1 Evelyn Jefferson Mrs
#> 2 Laura Mandeville Miss
#> 3 Theresa Anderson Miss
#> 4 Brenda Rogers Miss
#> 5 Charlotte McDowd Miss
#> 6 Frances Anderson Miss
#> # ℹ 12 more rows
#>
#> ── Ties
#> # A tibble: 139 × 3
#> from to weight
#> <int> <int> <dbl>
#> 1 1 2 6
#> 2 1 4 6
#> 3 1 3 7
#> 4 1 5 3
#> 5 1 6 4
#> 6 1 7 3
#> # ℹ 133 more rows
#>
to_mode2(ison_southern_women)
#> ── # Projection of Southern Women Data ─────────────────────────────────────────
#> # A labelled, weighted, undirected network of 14 social events and 66 co-women
#> ties
#>
#> ── Nodes
#> # A tibble: 14 × 3
#> name Surname Title
#> <chr> <chr> <chr>
#> 1 E1 6/27 NA
#> 2 E2 3/2 NA
#> 3 E3 4/12 NA
#> 4 E4 9/26 NA
#> 5 E5 2/25 NA
#> 6 E6 5/19 NA
#> # ℹ 8 more rows
#>
#> ── Ties
#> # A tibble: 66 × 3
#> from to weight
#> <int> <int> <dbl>
#> 1 1 2 2
#> 2 1 3 3
#> 3 1 4 2
#> 4 1 5 3
#> 5 1 6 3
#> 6 1 8 3
#> # ℹ 60 more rows
#>
to_mode(ison_southern_women, 2)
#> ── # Projection of Southern Women Data ─────────────────────────────────────────
#> # A labelled, weighted, undirected network of 14 social events and 66 co-women
#> ties
#>
#> ── Nodes
#> # A tibble: 14 × 3
#> name Surname Title
#> <chr> <chr> <chr>
#> 1 E1 6/27 NA
#> 2 E2 3/2 NA
#> 3 E3 4/12 NA
#> 4 E4 9/26 NA
#> 5 E5 2/25 NA
#> 6 E6 5/19 NA
#> # ℹ 8 more rows
#>
#> ── Ties
#> # A tibble: 66 × 3
#> from to weight
#> <int> <int> <dbl>
#> 1 1 2 2
#> 2 1 3 3
#> 3 1 4 2
#> 4 1 5 3
#> 5 1 6 3
#> 6 1 8 3
#> # ℹ 60 more rows
#>
to_mode(ison_southern_women, "events")
#> ── # Projection of Southern Women Data ─────────────────────────────────────────
#> # A labelled, weighted, undirected network of 14 social events and 66 co-women
#> ties
#>
#> ── Nodes
#> # A tibble: 14 × 3
#> name Surname Title
#> <chr> <chr> <chr>
#> 1 E1 6/27 NA
#> 2 E2 3/2 NA
#> 3 E3 4/12 NA
#> 4 E4 9/26 NA
#> 5 E5 2/25 NA
#> 6 E6 5/19 NA
#> # ℹ 8 more rows
#>
#> ── Ties
#> # A tibble: 66 × 3
#> from to weight
#> <int> <int> <dbl>
#> 1 1 2 2
#> 2 1 3 3
#> 3 1 4 2
#> 4 1 5 3
#> 5 1 6 3
#> 6 1 8 3
#> # ℹ 60 more rows
#>
to_linegraph(ison_adolescents)
#> IGRAPH a3667e8 UN-- 10 20 -- Line graph
#> + attr: name (g/c), name (v/c)
#> + edges from a3667e8 (vertex names):
#> [1] Betty-Sue --Sue-Alice Sue-Alice --Alice-Jane Betty-Sue --Sue-Dale
#> [4] Sue-Alice --Sue-Dale Sue-Dale --Alice-Dale Sue-Alice --Alice-Dale
#> [7] Alice-Jane--Alice-Dale Sue-Dale --Jane-Dale Alice-Dale--Jane-Dale
#> [10] Alice-Jane--Jane-Dale Betty-Sue --Sue-Pam Sue-Alice --Sue-Pam
#> [13] Sue-Dale --Sue-Pam Sue-Pam --Alice-Pam Sue-Alice --Alice-Pam
#> [16] Alice-Jane--Alice-Pam Alice-Dale--Alice-Pam Sue-Pam --Pam-Carol
#> [19] Alice-Pam --Pam-Carol Pam-Carol --Carol-Tina