These functions combine an appropriate node_x_*() function
together with methods for calculating the hierarchical clusters
provided by how alike nodes' profiles are.
node_in_equivalence() assigns nodes membership based on their equivalence
with respective to some motif/class.
The following functions call this function, together with an appropriate motif.
node_in_structural() assigns nodes membership based on their
having equivalent ties to the same other nodes.
node_in_regular() assigns nodes membership based on their
having equivalent patterns of ties to equivalent others.
node_in_automorphic() assigns nodes membership based on their
having equivalent distances to other nodes.
node_in_motif() assigns nodes membership based on their
participating in local structures at similar rates.
A plot() method exists for investigating the dendrogram
of the hierarchical cluster and showing the returned cluster
assignment.
node_in_equivalence(
.data,
motif,
k = c("silhouette", "elbow", "strict"),
cluster = c("hierarchical", "concor"),
distance = NULL,
max_k = 8L,
proximity = "pearson",
Kmax = NULL
)
node_in_structural(
.data,
k = c("silhouette", "elbow", "strict"),
cluster = c("hierarchical", "concor"),
distance = NULL,
max_k = 8L,
proximity = "pearson",
Kmax = NULL
)
node_in_regular(
.data,
k = c("silhouette", "elbow", "strict"),
cluster = c("hierarchical", "concor"),
distance = NULL,
max_k = 8L,
regularity = c("rolesim", "rege"),
decay = 0.15,
beta = NULL,
Kmax = NULL
)
node_in_motif(
.data,
k = c("silhouette", "elbow", "strict"),
cluster = c("hierarchical", "concor"),
distance = NULL,
max_k = 8L,
proximity = "pearson",
Kmax = NULL
)
node_in_automorphic(
.data,
k = c("silhouette", "elbow", "strict"),
cluster = c("hierarchical", "concor"),
distance = NULL,
max_k = 8L,
proximity = "pearson",
Kmax = NULL
)
node_in_block(
.data,
k = 2L,
blocks = c("nul", "com"),
times = NULL,
search = c("tabu", "iterated")
)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().
A matrix returned by a node_x_*() function.
Typically a character string indicating which method
should be used to select the number of clusters to return.
By default "silhouette", other options include "elbow" and "strict".
"strict" returns classes with members only when strictly equivalent.
"silhouette" and "elbow" select classes based on the distance between
clusters or between nodes within a cluster.
Fewer, identifiable letters, e.g. "e" for elbow, is sufficient.
Alternatively, if k is passed an integer, e.g. k = 3,
then all selection routines are skipped in favour of this number of clusters.
Character string indicating whether clusters should be
clustered hierarchically ("hierarchical") or
through convergence of correlations ("concor").
Fewer, identifiable letters, e.g. "c" for CONCOR, is sufficient.
"cosine" is deprecated; use proximity = "cosine" instead.
Character string indicating which distance metric
to pass on to stats::dist to compare nodes a second time,
on their profiles of dissimilarities to all nodes.
By default NULL, so that the proximities are clustered directly.
Options include "euclidean",
"maximum", "manhattan", "canberra", "binary", and "minkowski".
Fewer, identifiable letters, e.g. "e" for Euclidean, is sufficient.
Before v1.1.0 the default was "euclidean",
so pass that to reproduce earlier results.
Ignored when cluster = "concor".
Integer indicating the maximum number of (k) clusters
to evaluate.
Ignored when k = "strict" or a discrete number is given for k.
Character string indicating how nodes' profiles
should be compared, passed on to manynet::to_proximity().
By default "pearson", their correlation,
but any measure offered there can be used,
e.g. "cosine", "ruzicka", "overlap", "euclidean", or "hamming".
Note that "jaccard" dichotomises a valued census;
"ruzicka" is the weighted counterpart that keeps the counts.
The proximities themselves are in the proximity element of the
clustering, e.g. attr(node_in_structural(.data), "hc")$proximity,
or can be made with manynet::to_proximity() from any census,
using across = "rows" and dyad = "include".
Ignored when cluster = "concor".
"asis" clusters a motif that is already a node-by-node similarity.
node_in_regular() does not take it,
since regularity_*() already returns a node-by-node similarity,
which is clustered as it is.
Deprecated. The former spelling of max_k.
Still accepted, but warns; please use max_k instead.
Character string indicating which algorithm should be
used to calculate how regularly equivalent nodes are.
By default "rolesim"; "rege" is also available.
Fewer, identifiable letters, e.g. "ro" for RoleSim, is sufficient.
See regularity_rolesim() and regularity_rege() for how they differ.
A proportion between 0 and 1 giving how much of a contribution
survives each additional step of distance or walk length.
Lower values discount more steeply, so that only nearby others count;
higher values discount less, so that longer walks continue to contribute.
The measures that take a decay differ in what they discount and in what
value leaves the measure in its most familiar form,
so each documents its own default.
Deprecated; use decay instead.
A character vector of permitted ideal block types,
or a list-matrix giving the permitted types per block position.
See net_by_inconsistency() for the available types.
Integer number of steps the search takes.
By default the number of nodes times the number of positions.
For search = "tabu" this is the most steps that each of its runs may
take, since a run also ends once it stops improving.
Which method to use to search the space of partitions. One of "tabu" (the default) or "iterated"; see method_search for what each does.
A node_member character vector the length of the nodes in the network,
of group memberships "A", "B", etc for each node.
If the network is labelled,
then the assignments will be labelled with the nodes' names.
Two nodes are regularly equivalent if each has ties to the same kinds of others, even where those others are not the same individuals and are not equally numerous. A manager with three subordinates and a manager with ten are regularly equivalent, because what makes them alike is that they both have subordinates, not how many or which.
The definition is recursive: nodes are equivalent if their alters are
equivalent, whose equivalence depends in turn on their alters.
node_in_regular() therefore computes a similarity matrix by iterating
that definition to a fixed point, and then clusters that similarity
directly, rather than comparing nodes' profiles first as
the other functions here do.
Give distance to compare the nodes' similarities a second time.
Note that this differs from node_in_motif(), which compares nodes on how
often they appear embedded in local structures.
Two nodes can have very similar triad profiles without being regularly equivalent,
and vice versa, since a motif census counts a node's local configurations
while regular equivalence asks who its alters are.
Where the other functions here compare nodes on whom they are tied to,
node_in_motif() compares them on what kinds of local structure they sit
in, by clustering a census of the triads (or, for two-mode networks,
tetrads) each node participates in.
Note that the census counts the types of motif a node takes part in, and not the position it holds within them. In the path \(i \rightarrow k \rightarrow j\), for example, all three nodes return a profile of one 021C triad, although \(i\) sends, \(k\) mediates and \(j\) receives. This is therefore neither Burt's role equivalence, which distinguishes those positions, nor the orbit-aware census of Ortmann and Brandes, which netrics does not yet offer.
What it captures is similarity of local embedding.
It is well suited to distinguishing nodes that sit in dense,
closed neighbourhoods from those that bridge open ones,
but it is not regular equivalence: see node_in_regular() for that.
This function was called node_in_regular() prior to version 1.0.0.
The other functions here are indirect: they build a similarity between
nodes, cluster it, and read a partition off the result.
node_in_block() is direct. It searches the space of partitions for
the one that best fits an ideal block structure, scoring each candidate
with net_by_inconsistency() and keeping whichever is most consistent.
The advantage is that the criterion being optimised is the one you
actually care about, rather than a similarity that stands in for it,
and that ideal types other than "null and complete" become available —
blocks = c("nul", "reg") searches directly for a regular-equivalence
blockmodel.
The cost is that the number of positions k must be chosen in advance,
and that the search is stochastic: it begins from random partitions,
so repeated runs may return different partitions and a
longer search is more likely to find a good one.
By default the search is a tabu search, search_tabu(), which lets the
positions take any size, and so can find a small core or one large
position where the network has them.
search = "iterated" uses search_iterated(), the only search available
prior to version 1.1.0. It is quicker on a large network, but it holds
the positions at near-equal size.
Set a seed for reproducibility, and compare runs with net_by_inconsistency().
Burt, Ronald S. 1990. "Detecting role equivalence". Social Networks 12(1): 83-97. doi:10.1016/0378-8733(90)90023-3
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
Doreian, Patrick, Vladimir Batagelj, and Anuska Ferligoj. 2005. Generalized Blockmodeling. Cambridge: Cambridge University Press. doi:10.1017/CBO9780511584176
Other memberships:
member_brokerage,
member_cliques,
member_community,
member_community_hier,
member_community_link,
member_community_modular,
member_community_partition,
member_community_spread,
member_components,
member_core,
member_diffusion
Other nodal:
mark_core,
mark_degree,
mark_diff,
mark_nodes,
mark_select_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,
motif_brokerage_node,
motif_clique,
motif_composition,
motif_exposure,
motif_node,
motif_path
(nse <- node_in_structural(ison_algebra))
#> 7 groups
#> V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13
#> 1 A B C A D D B B E E F A B
#> # ... and 3 more values from this nodeset. Use `print_all(...)` to print all values.
(nre <- node_in_regular(ison_southern_women))
#> 7 groups
#> Evelyn Laura Theresa Brenda Charlotte Frances Eleanor Pearl Ruth Verne Myra
#> 1 A A A A B B B C B B B
#> # ... and 7 more values from this nodeset. Use `print_all(...)` to print all values.
#> E1 E2 E3 E4 E5 E6 E7 E8 E9 E10 E11 E12 E13
#> 1 D D E E F F F F F E G E D
#> # ... and 1 more values from this nodeset. Use `print_all(...)` to print all values.
(nme <- node_in_motif(ison_southern_women, cluster = "concor"))
#> 8 groups
#> Evelyn Laura Theresa Brenda Charlotte Frances Eleanor Pearl Ruth Verne Myra
#> 1 A B A B C C D D D D C
#> # ... and 7 more values from this nodeset. Use `print_all(...)` to print all values.
#> E1 E2 E3 E4 E5 E6 E7 E8 E9 E10 E11 E12 E13
#> 1 E E F E F F G H G E E F E
#> # ... and 1 more values from this nodeset. Use `print_all(...)` to print all values.
if(require("sna", quietly = TRUE)){
(nae <- node_in_automorphic(ison_southern_women,
k = "elbow"))
}
#>
#> Attaching package: ‘statnet.common’
#> The following objects are masked from ‘package:base’:
#>
#> attr, order, replace
#>
#> ‘network’ 1.20.0 (2026-02-06), part of the Statnet Project
#> * ‘news(package="network")’ for changes since last version
#> * ‘citation("network")’ for citation information
#> * ‘https://statnet.org’ for help, support, and other information
#> sna: Tools for Social Network Analysis
#> Version 2.8 created on 2024-09-07.
#> copyright (c) 2005, Carter T. Butts, University of California-Irvine
#> For citation information, type citation("sna").
#> Type help(package="sna") to get started.
#> 3 groups
#> Evelyn Laura Theresa Brenda Charlotte Frances Eleanor Pearl Ruth Verne Myra
#> 1 A A A A A A A B B B B
#> # ... and 7 more values from this nodeset. Use `print_all(...)` to print all values.
#> E1 E2 E3 E4 E5 E6 E7 E8 E9 E10 E11 E12 E13
#> 1 A A A A A A A B B C C C C
#> # ... and 1 more values from this nodeset. Use `print_all(...)` to print all values.
(nbm <- node_in_block(ison_adolescents, k = 3))
#> 3 groups
#> Betty Sue Alice Jane Dale Pam Carol Tina
#> 1 C B B C C C A A
net_by_inconsistency(ison_adolescents, nbm)
#> # Blockmodel inconsistency [0, Inf)
#> [1] 0.143