These functions are similar to the create_* functions,
but include some element of randomisation.
They are particularly useful for creating a distribution of networks
for exploring or testing network properties.
generate_random() generates a random network with ties appearing at some probability.
generate_degree() generates a random network consistent with a
given degree distribution, as the random counterpart of create_degree().
generate_configuration() is an alias, since this is the configuration
model.
generate_man() generates a random network conditional on the dyad census
of Mutual, Asymmetric, and Null dyads, respectively.
generate_utilities() generates the utility that each node finds in
each other node, as a signed and weighted network.
These functions can create either one-mode or two-mode networks.
To create a one-mode network, pass the main argument n a single integer,
indicating the number of nodes in the network.
To create a two-mode network, pass n a vector of two integers,
where the first integer indicates the number of nodes in the first mode,
and the second integer indicates the number of nodes in the second mode.
As an alternative, an existing network can be provided to n
and the number of modes, nodes, and directedness will be inferred.
generate_random(n, p = 0.5, directed = FALSE, with_attr = TRUE)
generate_degree(n, p = 1, directed = FALSE, outdegree = NULL, indegree = NULL)
generate_configuration(
n,
p = 1,
directed = FALSE,
outdegree = NULL,
indegree = NULL
)
generate_man(n, p = NULL, directed = NULL, ...)
generate_utilities(
n,
p = 1,
directed = TRUE,
form = c("normal", "uniform", "relative"),
steps = 1,
volatility = 0.1,
inertia = 0
)Given:
A single integer, e.g. n = 10,
a one-mode network will be created.
A vector of two integers, e.g. n = c(5,10),
a two-mode network will be created.
A manynet-compatible object, a network of the same dimensions will be created.
The main probability of the model,
which is what makes a network of it more or less random.
It always follows n, and what it is the probability of depends on
the model.
For generate_random(), it is the proportion of possible ties in the network that are realised or, if an integer greater than 1, the number of ties in the network, by default 0.5. For generate_degree(), it is the share of the ties that are switched with one another, by default 1, so that 0 returns the network as it was. For generate_man(), it is a vector of three: the proportions of Mutual, Asymmetric, and Null dyads, which is inferred from n if that is a network and is otherwise c(0.25, 0.5, 0.25). For generate_utilities(), it is the share of the utilities that are ties, by default 1.
Logical whether the network should be directed.
By default directed = FALSE,
but for the functions that the usage above shows another default for.
A network given as n sets the direction instead.
If the opposite direction is desired,
use to_redirected() on the output of these functions.
In two-mode networks, the directed argument is ignored.
Logical whether any attributes of the object should be retained. By default TRUE.
Numeric scalar or vector indicating the
desired outdegree distribution.
Note that a scalar (single number) will result in a k-regular graph.
By default NULL.
If n is an existing network object and the outdegree is not specified,
then the outdegree distribution will be inferred from that of the network.
If only the indegree is specified, then in one-mode networks the outdegree
will mirror it, and in two-mode networks the same number of ties will be
spread as evenly as possible across the nodes in the first mode.
If neither is specified, the sparsest connected structure is created:
a cycle in one-mode networks, and in two-mode networks one in which the
larger mode is 1-regular.
Numeric vector indicating the desired indegree distribution.
By default NULL but not required unless a directed network is desired.
If n is an existing directed network object and the indegree is not specified,
then the indegree distribution will be inferred from that of the network.
Otherwise it is filled in from the outdegree as described above.
Arguments under the names they had in earlier versions,
which still work: man for p in generate_man().
How the utilities are distributed between -1 and 1.
"normal" (the default) draws them from a normal distribution around 0, so that most nodes are close to indifferent about most others and only a few are much liked or much disliked.
"uniform" draws every utility between -1 and 1 as likely as any other.
"relative" draws them from a normal distribution and then divides each node's utilities by the largest of them, whether liked or disliked, so that each node's utilities are relative to the node it feels most strongly about.
Number of moments at which to return the utilities.
By default 1.
If more than 1, the utilities change from each moment to the next
by as much as volatility allows,
and a longitudinal network with a wave for each moment is returned.
How much the utilities change between moments.
At each step a new set of utilities is drawn as form describes,
multiplied by volatility, and added to those there are.
By default 0.1, so that a utility changes by a tenth of a new draw.
The share of utilities that keep their value at each step, from 0 to 1. These are the utilities that would have changed the least, so that with some inertia utilities stay as they are until a change large enough comes along, rather than all drifting a little at every step. By default 0, so that every utility changes at every step.
A stocnet object is returned,
which can be coerced into other types of objects
using as_edgelist(), as_matrix(),
as_tidygraph(), as_igraph(), or as_network().
create_ring(), create_lattice(),
generate_random(), generate_smallworld(), and
generate_scalefree() return a tbl_graph or igraph object for now,
since the released versions of the packages built on this one expect
one from them.
By default, most networks are created as undirected.
This can be overruled with the argument directed = TRUE.
This will return a directed network in which the arcs are
out-facing or equivalent.
This direction can be swapped using to_redirected().
In two-mode networks, the directed argument is ignored.
generate_degree() keeps the degree of every node and is random
in which nodes are tied.
The degrees are those of the network given as n,
or those given as outdegree and indegree, as for create_degree().
It then switches the ends of pairs of ties, which changes who is tied to
whom but not how many ties anyone has.
With p = 1, the default, a network is drawn anew from those degrees.
With a lower p only that share of the ties are switched,
so that the result is in part the network it started from.
For generate_man(), counts such as p = c(10, 0, 20) are read as
relative weights and normalised,
so the dyad census is reproduced in expectation rather than exactly.
The default is the dyad distribution of a random (Erdős-Rényi) digraph
in which each arc is present with probability 0.5.
The network is directed unless there are no asymmetric dyads,
as with p = c(0.1, 0, 0.1), since it then has no direction to speak of.
directed overrules this either way, and where an undirected network
is asked for from asymmetric dyads, a dyad is tied where it would have
been mutual or asymmetric.
The same holds for two-mode networks, whose ties are undirected,
so only the sum of the mutual and asymmetric dyads is consequential there.
A utility is how much a node gains or loses from a tie to another node,
from -1 for the most it could lose to 1 for the most it could gain.
generate_utilities() returns these as the weights of a signed network.
In a one-mode network every node has a utility for every other node.
In a two-mode network each node of the first mode has a utility for
each node of the second mode.
Utilities say what ties nodes would like, not what ties there are, so they can serve as the basis for a model of how ties come about. The examples show two such models. Where a node can tie to another without its consent, the ties are the positive utilities. Where a tie needs the consent of both nodes, the ties are those where the lower of the two utilities is positive.
With p below 1, a node is indifferent to the utilities closest to 0,
and only the share p of them that are furthest from 0 are ties,
whether positive or negative.
With directed = FALSE, the two nodes of a pair find the same in each
other, and the network is undirected.
Where there is more than one step, how far from 0 a utility must be to be a tie is set at the first moment and kept, so a tie can come and go as a utility crosses it. A utility cannot rise above 1 or fall below -1, and one that a change would take further stays at that limit until a change brings it back. Over many steps the utilities therefore spread out towards the limits, and more of them are far enough from 0 to be ties than at the start.
Erdos, Paul, and Alfred Renyi. 1959. "On Random Graphs I" Publicationes Mathematicae. 6: 290–297.
Other makes:
make_collect,
make_create,
make_ego,
make_emails,
make_explicit,
make_groups,
make_growth,
make_learning,
make_play,
make_read,
make_write
generate_random(12, 0.4)
#> IGRAPH cb1accc U--- 12 28 -- Erdos-Renyi (gnp) graph
#> + attr: name (g/c), type (g/c), loops (g/l), p (g/n)
#> + edges from cb1accc:
#> [1] 1-- 2 1-- 3 2-- 3 1-- 4 4-- 5 3-- 6 4-- 6 1-- 7 3-- 7 4-- 7 6-- 7 2-- 8
#> [13] 5-- 8 2-- 9 3-- 9 5-- 9 7-- 9 4--10 7--10 8--10 4--11 6--11 8--11 1--12
#> [25] 5--12 6--12 8--12 9--12
# generate_random(c(6, 6), 0.4)
generate_degree(12, outdegree = 3)
#>
#> ── # Configuration network ─────────────────────────────────────────────────────
#> # A undirected network of 12 nodes and 18 ties
#>
#> ── Ties
#> # A tibble: 18 × 2
#> from to
#> <int> <int>
#> 1 1 2
#> 2 1 7
#> 3 1 10
#> 4 2 3
#> 5 2 4
#> 6 3 7
#> # ℹ 12 more rows
#>
generate_degree(create_core(12), p = 0.25)
#> ── # Configuration network ─────────────────────────────────────────────────────
#> # A undirected network of 12 nodes and 51 ties
#>
#> ── Ties
#> # A tibble: 51 × 2
#> from to
#> <int> <int>
#> 1 1 2
#> 2 1 3
#> 3 1 4
#> 4 1 5
#> 5 1 6
#> 6 1 7
#> # ℹ 45 more rows
#>
generate_man(6)
#> ── # Dyad census network ───────────────────────────────────────────────────────
#> # A directed network of 6 nodes and 15 arcs
#>
#> ── Ties
#> # A tibble: 15 × 2
#> from to
#> <int> <int>
#> 1 1 3
#> 2 1 4
#> 3 1 5
#> 4 2 1
#> 5 2 6
#> 6 3 2
#> # ℹ 9 more rows
#>
generate_man(6, p = c(0.3, 0, 0.7))
#> ── # Dyad census network ───────────────────────────────────────────────────────
#> # A undirected network of 6 nodes and 7 ties
#>
#> ── Ties
#> # A tibble: 7 × 2
#> from to
#> <int> <int>
#> 1 1 2
#> 2 1 3
#> 3 2 3
#> 4 1 4
#> 5 1 5
#> 6 4 6
#> # ℹ 1 more row
#>
generate_man(c(4, 6))
#> ── # Dyad census network ───────────────────────────────────────────────────────
#> # A two-mode network of 4 FALSEs and 6 TRUEs and 20 ties
#>
#> ── Nodes
#> # A tibble: 10 × 1
#> mode
#> <chr>
#> 1 FALSE
#> 2 FALSE
#> 3 FALSE
#> 4 FALSE
#> 5 TRUE
#> 6 TRUE
#> # ℹ 4 more rows
#>
#> ── Ties
#> # A tibble: 20 × 2
#> from to
#> <int> <int>
#> 1 1 5
#> 2 1 6
#> 3 1 7
#> 4 1 9
#> 5 2 5
#> 6 2 6
#> # ℹ 14 more rows
#>
(utils <- generate_utilities(6))
#> ── # Utilities network ─────────────────────────────────────────────────────────
#> # A signed, weighted, directed network of 6 nodes and 30 arcs
#>
#> ── Ties
#> # A tibble: 30 × 3
#> from to weight
#> <int> <int> <dbl>
#> 1 1 2 0.250
#> 2 1 3 0.0156
#> 3 1 4 -0.104
#> 4 1 5 0.465
#> 5 1 6 -0.493
#> 6 2 1 0.610
#> # ℹ 24 more rows
#>
generate_utilities(6, p = 0.25)
#> ── # Utilities network ─────────────────────────────────────────────────────────
#> # A signed, weighted, directed network of 6 nodes and 8 arcs
#>
#> ── Ties
#> # A tibble: 8 × 3
#> from to weight
#> <int> <int> <dbl>
#> 1 3 1 0.475
#> 2 3 2 0.427
#> 3 4 3 -0.991
#> 4 5 3 0.506
#> 5 5 6 -0.412
#> 6 6 1 -0.462
#> # ℹ 2 more rows
#>
generate_utilities(6, directed = FALSE)
#> ── # Utilities network ─────────────────────────────────────────────────────────
#> # A signed, weighted, undirected network of 6 nodes and 15 ties
#>
#> ── Ties
#> # A tibble: 15 × 3
#> from to weight
#> <int> <int> <dbl>
#> 1 1 2 -0.454
#> 2 1 3 -0.454
#> 3 1 4 -0.301
#> 4 1 5 -0.0818
#> 5 1 6 -0.0227
#> 6 2 3 -0.229
#> # ℹ 9 more rows
#>
generate_utilities(c(4, 6), form = "uniform")
#> ── # Utilities network ─────────────────────────────────────────────────────────
#> # A signed, weighted, two-mode network of 4 FALSEs and 6 TRUEs and 24 ties
#>
#> ── Nodes
#> # A tibble: 10 × 1
#> mode
#> <chr>
#> 1 FALSE
#> 2 FALSE
#> 3 FALSE
#> 4 FALSE
#> 5 TRUE
#> 6 TRUE
#> # ℹ 4 more rows
#>
#> ── Ties
#> # A tibble: 24 × 3
#> from to weight
#> <int> <int> <dbl>
#> 1 1 5 0.231
#> 2 2 5 0.859
#> 3 3 5 0.963
#> 4 4 5 -0.0679
#> 5 1 6 0.776
#> 6 2 6 0.969
#> # ℹ 18 more rows
#>
generate_utilities(6, steps = 3)
#> ── # Utilities network ─────────────────────────────────────────────────────────
#> # A longitudinal, signed, weighted, directed network of 6 nodes and 90 arcs
#> over 3 waves
#>
#> ── Ties
#> # A tibble: 90 × 4
#> from to weight time
#> <int> <int> <dbl> <int>
#> 1 1 2 0.550 1
#> 2 1 3 0.368 1
#> 3 1 4 0.103 1
#> 4 1 5 0.384 1
#> 5 1 6 -0.157 1
#> 6 2 1 -0.0695 1
#> # ℹ 84 more rows
#>
generate_utilities(6, steps = 3, volatility = 0.5, inertia = 0.8)
#> ── # Utilities network ─────────────────────────────────────────────────────────
#> # A longitudinal, signed, weighted, directed network of 6 nodes and 90 arcs
#> over 3 waves
#>
#> ── Ties
#> # A tibble: 90 × 4
#> from to weight time
#> <int> <int> <dbl> <int>
#> 1 1 2 0.260 1
#> 2 1 3 0.242 1
#> 3 1 4 -0.914 1
#> 4 1 5 -0.0883 1
#> 5 1 6 -0.443 1
#> 6 2 1 -0.139 1
#> # ℹ 84 more rows
#>
# the ties that one node wants
to_unsigned(utils, keep = "positive")
#> ── # Utilities network ─────────────────────────────────────────────────────────
#> # A weighted, directed network of 6 nodes and 17 arcs
#> # Transformed by exclusion: negative ties (13 ties excluded)
#>
#> ── Ties
#> # A tibble: 17 × 3
#> from to weight
#> <int> <int> <dbl>
#> 1 1 2 0.250
#> 2 1 3 0.0156
#> 3 1 5 0.465
#> 4 2 1 0.610
#> 5 2 5 0.348
#> 6 2 6 0.259
#> # ℹ 11 more rows
#>
# the ties that both nodes want
to_unsigned(to_undirected(utils, rule = "min"), keep = "positive")
#> # A weighted, undirected network of 6 nodes and 6 ties
#> # Transformed by symmetrisation: min and exclusion: negative ties
#>
#> ── Ties
#> # A tibble: 6 × 3
#> from to weight
#> <int> <int> <dbl>
#> 1 1 2 0.250
#> 2 1 3 0.0156
#> 3 2 5 0.154
#> 4 2 6 0.0388
#> 5 3 4 0.115
#> 6 5 6 0.0204
#>