Networks#

ergmx models binary networks, directed or undirected, given as an igraph or a networkx graph. There is no network class of its own: pass your graph, and the results (simulated networks, for example) come back as graphs of the same kind.

The bundled networks#

ergmx.datasets has the networks of R’s ergm documentation:

from ergmx import datasets

for name in datasets.names():
    g = datasets.load(name)
    if isinstance(g, list):  # a sample of networks
        print(f"{name:20} {len(g):5} networks, {sum(x.vcount() for x in g)} vertices in all")
        continue
    kind = "directed" if g.is_directed() else "undirected"
    print(f"{name:20} {g.vcount():5} vertices {g.ecount():5} edges  {kind}")
flomarriage             16 vertices    20 edges  undirected
flobusiness             16 vertices    15 edges  undirected
samplk1                 18 vertices    55 edges  directed
samplk2                 18 vertices    57 edges  directed
samplk3                 18 vertices    56 edges  directed
faux.mesa.high         205 vertices   203 edges  undirected
faux.dixon.high        248 vertices  1197 edges  directed
davis                   32 vertices    89 edges  undirected
linked_sim             150 vertices   600 edges  undirected
labs_sim               150 vertices   583 edges  undirected
faux.magnolia.high    1461 vertices   974 edges  undirected
Goeyvaerts             318 networks, 1266 vertices in all
print(datasets.describe("faux.mesa.high"))
A simulated friendship network of 205 students in a high school in the rural western US, from the Add Health study design (Resnick et al. 1997, doi:10.1001/jama.278.10.823). Undirected. Vertex attributes: Grade (7 to 12), Race and Sex.

The datasets’ sources, such as the Add Health study design (Resnick et al. 1997), are in the references, with links.

load() returns an igraph.Graph; load(name, backend="networkx") returns a networkx.Graph or networkx.DiGraph with the same vertices, in the same order.

Vertex attributes#

Terms such as nodematch('Grade') read vertex attributes. In igraph they are g.vs["Grade"]; in networkx, node data (G.nodes[v]["Grade"]):

import ergmx

mesa = datasets.load("faux.mesa.high")
mesa_nx = datasets.load("faux.mesa.high", backend="networkx")

formula = "edges + nodematch('Grade') + nodefactor('Race')"
ergmx.summary_stats(mesa, formula) == ergmx.summary_stats(mesa_nx, formula)
True

Categorical attributes can hold any sortable values (strings, integers…). Their levels are sorted, and terms with one statistic per level, like nodefactor, drop the first level, as ergm does. Numeric terms, like nodecov, need numbers.

Graph attributes#

Dyadic covariates for edgecov are n x n matrices stored as graph attributes, g["name"] in igraph and G.graph["name"] in networkx. ergm’s flobusiness network can be a covariate of flomarriage:

import numpy as np

flomarriage = datasets.load("flomarriage")
business = datasets.load("flobusiness")
flomarriage["business"] = np.array(business.get_adjacency().data)

ergmx.summary_stats(flomarriage, "edges + edgecov('business')")
{'edges': 20.0, 'edgecov.business': 8.0}

edgecov also accepts the matrix itself, or a graph on the same vertices: edgecov(business).

What is not supported#

A network must not have multiple edges between the same vertices (use igraph.Graph.simplify(), or nx.Graph rather than nx.MultiGraph) or self-loops. Edge attributes such as weights are ignored, as ERGMs model whether ties exist, not their values, except one: an edge with a true na attribute marks a dyad whose value is unknown (see Missing ties).