Layer {ergm.multi} | R Documentation |
A multilayer network representation.
Description
A function for specifying the LHS of a multilayer (a.k.a. multiplex, a.k.a. multirelational, a.k.a. multivariate) ERGM in the framework of Krivitsky et al. (2020).
Usage
Layer(..., .symmetric = NULL, .bipartite = NULL, .active = NULL)
Arguments
... |
layer specification, in one of three formats:
|
.symmetric |
If the layer specification is via a single network with edge attributes and the network is directed, an optional logical vector to specify which of the layers should be treated as undirected. |
.bipartite |
If the layer specification is via a single
network with edge attributes and the network is unipartite, an
optional integer vector to specify which of the layers should be
treated as bipartite and how many |
.active |
A nodal attribute specification
( |
Value
A network object with layer metadata.
Specifying models for multilayer network
In order to fit a model for multilayer
networks, first use Layer
construct an LHS network that
ergm()
will understand as multilayered.
Used in the formula directly, most, but not all, ergm terms will sum their statistics over the observed layers.
Some terms are layer-aware, however. By convention, layer-aware
terms have capital L
appended to them. For example,
mutualL
is a layer-aware generalization of
mutual
. These terms have one or more explicit
(usually optional) layer specification arguments. By convention, an
argument that requires one layer specification is named L=
and
one that requires a list of specifications (constructed by list()
or c()
) is named Ls=
; and a specification of the form ~.
is a
placeholder for all observed layers.
Operator L(formula, Ls=...)
can be used to evaluate
arbitrary terms in the formula
on specified layers.
Layer specification documentation follows.
Layer Logic
Each formula's right-hand side describes an observed layer or some "logical" layer, whose ties are a function of corresponding ties in observed layers. (Krivitsky et al. 2020)
The observed layers can be referenced either by name or by number (i.e.,
order in which they were passed to Layer
). When referencing by
number, enclose the number in quotation marks (e.g., "1") or
backticks (e.g., “1
”).
Arithmetical, relational,
and logical operators can be used to combine them. All
listed operators are implemented, as well as functions abs
,
round
, and sign
. Standard
operator precedence applies, so use of parentheses is
recommended to ensure the logical expression is what it looks like.
Important: For performance reasons, ergm.multi's
Layer Logic implementation uses integer arithmetic. This means, in
particular, that /
will round down instead of returning a
fraction (as %/%
does in R), and round()
function without a
second argument (which can be negative to round to the nearest 10,
100, etc.) is not meaningful and will be ignored.
For example, if LHS is Layer(A=nwA, B=nwB)
, both ~`2`
and
~B
refer to nwB
, while A&!B
refers to a
“logical” layer that has ties that are in nwA
but not in
nwB
.
Transpose function t
applied to a directed layer will reverse
the direction of all relations (transposing the sociomatrix). Unlike the
others, it can only be used on an observed layer directly. For example,
~t(`1`)&t(`2`)
is valid but ~t(`1`&`2`)
is not.
At this time, logical expressions that produce complete graphs from empty
graph inputs (e.g., A==B
or !A
) are not supported.
Summing layers
Some of the terms that call for a list of layers (i.e., have Ls=
arguments) will sum the statistic over the layers. For example,
Layer(nw1,nw2)~L(~edges, c(~`1`,~(`2`&!`1`)))
produces the
number of edges in layer 1 plus the number of edges in layer 2 but
not in layer 1.
For these formulas, one can specify the layer's weight on its left-handside.
For example, Layer(nw1,nw2)~L(~edges, c(3~`1`,-1~(`2`&!`1`)))
will
produce three times the number of edges in layer 1, minus the number of
edges in layer 2 but not in layer 1.
Note
The resulting network will be the "least common denominator"
network: if not all layers have the same bipartedness, all layers
will appear as unipartite to the statistics, and if any are
directed, all will be. However, certain operator terms, particularly Symmetrize()
and S()
, can be
used to construct a bipartite subgraph of a unipartite graph or
change directedness.
References
Krivitsky PN, Koehly LM, Marcum CS (2020). “Exponential-family Random Graph Models for Multi-layer Networks.” Psychometrika, 85(3), 630–659. doi:10.1007/s11336-020-09720-7.
See Also
Help on model specification for specific terms.
Examples
data(florentine)
# Method 1: list of networks
flo <- Layer(list(m = flomarriage, b = flobusiness))
ergm(flo ~ L(~edges, ~m)+L(~edges, ~b))
# Method 2: networks as arguments
flo <- Layer(m = flomarriage, b = flobusiness)
ergm(flo ~ L(~edges, ~m)+L(~edges, ~b))
# Method 3: edge attributes (also illustrating renaming):
flo <- flomarriage | flobusiness
flo[,, names.eval="marriage"] <- as.matrix(flomarriage)
flo[,, names.eval="business"] <- as.matrix(flobusiness)
flo # edge attributes
flo <- Layer(flo, c(m="marriage", b="business"))
ergm(flo ~ L(~edges, ~m)+L(~edges, ~b))
### Specifying modes and mixed bipartitedness
# Suppose we have a two-mode network with 5 nodes on Mode 1 and 15
# on Mode 2, and suppose that we observe two layers, one only among
# actors of Mode 1 and the other bipartite between Modes 1 and 2.
# Construct the two layers' networks:
nw1 <- network.initialize(20, dir=FALSE)
nw12 <- network.initialize(20, dir=FALSE, bipartite=5)
nw1 %v% "mode" <- rep(1:2,c(5,15))
# For testing: the maximal set of edges for each type of network:
nw1[1:5,1:5] <- 1
nw12[1:5,6:20] <- 1
# The .active argument specifies the following:
# * nw1's vertices are only active if their mode=1 (i.e., 1-2, 2-1,
# and 2-2 can't have edges).
# * nw12's vertices are all active, but the network is bipartite,
# so constraints will be adjusted automatically.
lnw <- Layer(nw1, nw12, .active=list(~mode==1, ~TRUE))
summary(lnw~
edges+ # 5*4/2+5*15 = 10+75 = 85
L(~edges,~`1`)+ # 5*4/2 = 10
L(~edges,~`2`)+ # 5*15 = 75
L(~edges,~(`1`|`2`))+ # This logical layer has contents of both, so also 85.
L(~edges,~(`1`&`2`)) # There is no overlap between the two layers, so 0.
)
# Layer-aware terms can be used:
nw1[,] <-0
nw1[1,2:3] <- 1
nw1[2,3] <- 1
nw12[,] <- 0
nw12[1,6:7] <- 1
nw12[2,6:7] <- 1
lnw <- Layer(nw1, nw12, .active=list(~mode==1,~TRUE))
summary(lnw~L(~triangles, ~`1`)+ # 1-2-3 triangle.
L(~triangles, ~`1`|`2`)+ # 1-2-3, 1-2-6, 1-2-7 triangles
dgwespL(L.base=~`1`, Ls.path=list(~`2`,~`2`)) # 1-2-6 and 1-2-7 only
)
# Because the layers are represented as a block-diagonal matrix,
# this will only count triangles entirely contained within a single
# layer, i.e., 1-2-3:
summary(lnw~triangles)
# If you need to evaluate bipartite-only statistics on the second
# layer, you need to use the S() operator to select the bipartite
# view:
summary(lnw~L(~S(~b1degree(1:3)+b2degree(1:3),1:5~6:20), ~`2`))