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:

  1. An (optionally named) list of identically-dimensioned networks.

  2. Several networks as (optionally named) arguments.

  3. A single network, a character vector, and several optional arguments. Then, the layers are values of the named edge attributes. If the vector has named elements (e.g., c(a="advice", c="collaboration")), the layers will be renamed accordingly. The optional arguments .symmetric and .bipartite are then interpreted as described below.

.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 b1 vertices there are.

.active

A nodal attribute specification (? nodal_attributes) specifying which nodes on each network may have ties, or a list with an element for each network. The list will be recycled up to the number of layers.

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`))


[Package ergm.multi version 0.2.1 Index]