ergm.multi
to analyse the signed Read’s Highland Tribes datasetergm.multi
version 0.1.4108 (2022-07-27)library(ergm.multi)
The highland tribes dataset can be found in the latentnet
package:
data(tribes, package = "latentnet")
It contains a number of edge attributes, providing various encodings of the allied and hostile relations between tribes:
list.edge.attributes(tribes)
## [1] "na" "neg" "pos" "sign" "sign.012"
We will use pos
and neg
for a multilayer construct. Note that there’s no rule that says we can’t name them something descriptive, though we must quote these operators with backticks:
Layer(tribes, c(`+`="pos", `-`="neg")) Ltribes <-
This is now a multilayer network construct, with metadata set for it to be understood by layer-aware terms.
A signed network differs from a multilayer network in that a given dyad cannot have a relationship in both a positive and a negative layer. in the language of Layer Logic, this is forbidding `+`&`-`
from changing. This is specified by a layer-aware constraint fixL(~`+`&`-`)
, which can be specified in one of two ways:
ergm(Ltribes~..., constraints=~. + fixL(~`+`&`-`))
where ...
is the model formula. The dot is important, since it indicates that the constraints attached to the network via the ergmlhs
API should not be replaced but appended to. The other approach is to append this constraint to the network:
%ergmlhs% "constraints" Ltribes
## ~blockdiag(".LayerID")
## <environment: base>
%ergmlhs% "constraints" <- update(Ltribes %ergmlhs% "constraints", ~ . + fixL(~`+`&`-`))
Ltribes %ergmlhs% "constraints" Ltribes
## ~blockdiag(".LayerID") + fixL(~`+` & `-`)
## <environment: base>
We can now call ergm()
without additional arguments, and the constraint will be enforced.
Let’s start by fitting a simple density model
ergm(Ltribes ~ L(~edges, ~`+`) + L(~edges, ~`-`))
##
## Call:
## ergm(formula = Ltribes ~ L(~edges, ~`+`) + L(~edges, ~`-`))
##
## Last MCMC sample of size 243 based on:
## L(+)~edges L(-)~edges
## -0.7613 -0.7461
##
## Monte Carlo Maximum Likelihood Coefficients:
## L(+)~edges L(-)~edges
## -0.7486 -0.7388
Are these correct? Well,
summary(Ltribes ~ L(~edges, ~`+`))) (e.p <-
## L(+)~edges
## 29
summary(Ltribes ~ L(~edges, ~`-`))) (e.n <-
## L(-)~edges
## 29
network.dyadcount(tribes)) # original, not combined network (d <-
## [1] 120
This model happens to be a baseline-category logit, with 0 being baseline, so
function(p) log(p/(1-p))
logit <-
logit(e.p / (d-e.n))
## L(+)~edges
## -0.7598386
logit(e.n / (d-e.p))
## L(-)~edges
## -0.7598386
So far so good!
Let’s try to fit something with triadic effects. (1/2 here is a bit arbitrary.)
ergm(Ltribes ~ L(~edges, ~`+`) + gwespL(1/2, fix=TRUE, L.base=~`+`, Ls.path=c(~`+`,~`+`)) + L(~edges, ~`-`) + gwespL(1/2, fix=TRUE, L.base=~`-`, Ls.path=c(~`+`,~`-`)))
fit <-summary(fit)
## Call:
## ergm(formula = Ltribes ~ L(~edges, ~`+`) + gwespL(1/2, fix = TRUE,
## L.base = ~`+`, Ls.path = c(~`+`, ~`+`)) + L(~edges, ~`-`) +
## gwespL(1/2, fix = TRUE, L.base = ~`-`, Ls.path = c(~`+`,
## ~`-`)))
##
## Monte Carlo Maximum Likelihood Results:
##
## Estimate Std. Error MCMC % z value Pr(>|z|)
## L(+)~edges -3.4234 0.5984 0 -5.721 < 1e-04 ***
## L(pth=(+),bse=+,inord=FALSE)~gwesp.fixed.0.5 1.0861 0.3362 0 3.231 0.001234 **
## L(-)~edges -4.8101 1.2294 0 -3.913 < 1e-04 ***
## L(pth=(+,-),bse=-,inord=FALSE)~gwesp.fixed.0.5 2.5192 0.7647 0 3.294 0.000986 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Null Deviance: 0.00 on 240 degrees of freedom
## Residual Deviance: -48.21 on 236 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: -40.21 BIC: -26.29 (Smaller is better. MC Std. Err. = 0.9366)
Here, the first gwespL()
term models friend-of-a-friend-is-a-friend configurations: the base of the triad is positive, and the 2-path is positive and positive. The second one models friend-of-an-enemy-is-an-enemy and enemy-of-a-friend-is-an-enemy: the base is negative, and the 2-path requires a positive and a negative relation (in any order).