# Using `ergm.sign` to analyse the signed Read’s Highland Tribes dataset

#### Marc Schalberger

    ## Loading required package: network

    ##
    ## '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

    ##
    ## 'ergm' 4.12.0 (2026-02-17), part of the Statnet Project
    ## * 'news(package="ergm")' for changes since last version
    ## * 'citation("ergm")' for citation information
    ## * 'https://statnet.org' for help, support, and other information

    ## 'ergm' 4 is a major update that introduces some backwards-incompatible
    ## changes. Please type 'news(package="ergm")' for a list of major
    ## changes.

    ##
    ## 'ergm.multi' 0.3.0 (2025-06-14), part of the Statnet Project
    ## * 'news(package="ergm.multi")' for changes since last version
    ## * 'citation("ergm.multi")' for citation information
    ## * 'https://statnet.org' for help, support, and other information

    ##
    ## Attaching package: 'ergm.multi'

    ## The following object is masked from 'package:ergm':
    ##
    ##     snctrl

    library(ergm.sign)

# Obtaining data

The highland tribes dataset from Read (1954) is included in the `ergm.sign` package:

    data("tribes")

This gives us a multilayer network construct with a positive and a negative layer encoding the allied and hostile relationships between the tribes.

# Desctiptive statistics

The summary `summary` function returns a matrix with the most important descriptive statistics for the signed network:

    summary(tribes)

    ## Network Attributes:

    ##  Directed Loops Nodes Edges Edges+ Edges- Triads +++ --- ++- +-- Density
    ##     FALSE FALSE    16    58     29     29     68  19   7   2  40   0.483

If we would like to get other descriptive statistics using the `summary_formula` function:

    summary(tribes ~ edges + Pos(~ edges) + Neg(~ edges))

    ##     edges Pos~edges Neg~edges
    ##        58        29        29

# Plotting the network

It is also possible to plot the signed network using the `plot` function. Which requires the `UnLayer` function that turns the multilayer network into a single layer network:

    plot(tribes, displaylabels = TRUE)

# Fitting a model

Just like in the unsigned case, we can call the `ergm.sign` function to fit a model to the signed network. The `ergm.sign` function requires a formula that specifies the model to be fitted. In addition to the normal ergm terms we can also use the `Pos` and the `Neg` function to specify terms that only apply to the positive or negative layer of the network.

    fit <- ergm.sign(tribes ~ Pos(~ edges) + Neg(~ edges))
    summary(fit)

    ## Call:
    ## ergm::ergm(formula = formula, control = control)
    ##
    ## Monte Carlo Maximum Likelihood Results:
    ##
    ##           Estimate Std. Error MCMC % z value Pr(>|z|)
    ## Pos~edges  -0.7483     0.2290      0  -3.268 0.001082 **
    ## Neg~edges  -0.7363     0.2217      0  -3.321 0.000898 ***
    ## ---
    ## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
    ##
    ##      Null Deviance:   0.00  on 240  degrees of freedom
    ##  Residual Deviance: -17.12  on 238  degrees of freedom
    ##
    ## Note that the null model likelihood and deviance are defined to be 0. This means that all likelihood-based inference (LRT, Analysis of
    ## Deviance, AIC, BIC, etc.) is only valid between models with the same reference distribution and constraints.
    ##
    ## AIC: -13.12  BIC: -6.158  (Smaller is better. MC Std. Err. = 0.3322)

Triadic effects are of particular interest in the context of signed networks.

    triad_fit <- ergm.sign(tribes ~ gwese(0.5, base = "+") + gwesf(0.5, base = "+"))
    summary(triad_fit)

    ## Call:
    ## ergm::ergm(formula = formula, control = control)
    ##
    ## Monte Carlo Maximum Likelihood Results:
    ##
    ##              Estimate Std. Error MCMC % z value Pr(>|z|)
    ## gwese(+).0.5 -0.34709    0.15897      0  -2.183    0.029 *
    ## gwesf(+).0.5 -0.02882    0.07952      0  -0.362    0.717
    ## ---
    ## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
    ##
    ##      Null Deviance:  0.000  on 240  degrees of freedom
    ##  Residual Deviance: -5.196  on 238  degrees of freedom
    ##
    ## Note that the null model likelihood and deviance are defined to be 0. This means that all likelihood-based inference (LRT, Analysis of
    ## Deviance, AIC, BIC, etc.) is only valid between models with the same reference distribution and constraints.
    ##
    ## AIC: -1.196  BIC: 5.765  (Smaller is better. MC Std. Err. = 0.3478)

Here, the `gwese` (geometrically weighted edgewise shared enemies) term models enemy of my enemy is my friend configuration and the `gwesf` (geometrically weighted edgewise shared friends) term models friend of a friend is a friend configuration.

# Goodness of fit

In order to assess the goodness of fit of the model we can use the `gof_sign` function, which compares the observed network statistics to the statistics of simulated networks. The `nsim` argument specifies the number of simulations to be performed. For example, to perform 20 simulations we can use the following code:

    gof_data <- gof(triad_fit, nsim = 20)
    plot(gof_data)

# References

Read, Kenneth E. 1954. “Cultures of the Central Highlands, New Guinea.” Southwestern Journal of Anthropology 10 (1): 1–43.