This vignette uses the `Knecht`

data from Knecht (2006) and Knecht (2008) to provide an illustrative example of estimating an ego-Temporal Exponential Random Graph Model (ego-TERGM) using the `egoTERGM`

package (Knecht 2006). It begins by estimating an ego-TERGM on the Knecht friendship network, a network of 26 students in a Dutch classroom measured across four time-periods. In addition to data on the friendships between students there is nodal attribute data on a variety of demographic and behavioral factors. For a detailed explanation of the data, I refer the reader to the original publications on the data or to the `xergm.common`

help page for the `knecht`

data: `??knecht`

.

Much of the code for estimating the ego-TERGM is a modification of code originally produced for its cross-sectional equivalent (Salter-Townshend and Brendan Murphy 2015). This vignette will proceed step-by-step in presenting the typical workflow for estimating and interpreting an ego-TERGM using `egoTERGM`

.

*Note: The code presented here is not built given the runtime for the ego-TERGM presented here. As such, the code presented is purely illustrative. It will successfully run, however.*

The following chunk of code imports the Knecht friendship network gathered by Andrea Knecht and provided in the `xergm.common`

package (Leifeld, Cranmer, and Desmarais 2014, leifeld2017temporal). It also uses some code from the `xergm.common`

package to prepare the network for the `ego_tergm`

function, note that it produces a list of network objects.

```
library(xergm.common)
set.seed(1)
data("knecht")
for (i in 1:length(friendship)) {
rownames(friendship[[i]]) <- paste("Student.", 1:nrow(friendship[[i]]), sep="")
colnames(friendship[[i]]) <- paste("Student.", 1:nrow(friendship[[i]]), sep="")
}
rownames(primary) <- rownames(friendship[[1]])
colnames(primary) <- colnames(friendship[[1]])
sex <- demographics$sex
names(sex) <- rownames(friendship[[1]])
# step 2: imputation of NAs and removal of absent nodes:
friendship <- xergm.common::handleMissings(friendship, na = 10, method = "remove")
friendship <- xergm.common::handleMissings(friendship, na = NA, method = "fillmode")
# step 3: add nodal covariates to the networks
for (i in 1:length(friendship)) {
s <- xergm.common::adjust(sex, friendship[[i]])
friendship[[i]] <- network::network(friendship[[i]])
friendship[[i]] <- network::set.vertex.attribute(friendship[[i]], "sex", s)
idegsqrt <- sqrt(sna::degree(friendship[[i]], cmode = "indegree"))
friendship[[i]] <- network::set.vertex.attribute(friendship[[i]],
"idegsqrt", idegsqrt)
odegsqrt <- sqrt(sna::degree(friendship[[i]], cmode = "outdegree"))
friendship[[i]] <- network::set.vertex.attribute(friendship[[i]],
"odegsqrt", odegsqrt)
}
sapply(friendship, network::network.size)
net <- friendship
rm(list=setdiff(ls(), "net"))
```

Once the data is imported and transformed into a `list`

of `network`

objects with relevant attributes appended to each network in that list, we can proceed with estimating the ego-TERGM using `ego_tergm`

. Underneath the hood, quite a bit is occuring when the user calls this function. First, the function transforms the list of longitudinally observed networks into a list of longitudinally observed ego-networks. From that point, the initialization proceedure described by Campbell (2018) is used, including the estimation of a TERGM via bootstrapped pseudolikelihood and subsequent clustering of TERGM parameters using k-means clustering (Campbell 2018). Upon initialization, an Expectation Maximization (EM) algorithm is used to find group-centroids and role assignments.

The `ego_tergm`

function requires a few arguments:

`net`

: The list of network objects previously discussed.`form`

: A vector of comma-seperated`ergm-terms`

used to distinguish between role assignments.`core_size`

: The number of alters out from the ego to include and connections among them.`min_size`

: The minimum size that an ego-network at a particular time period must achieve to be included.`roles`

: The number of roles to be fit.`add_drop`

: Whether nodes drop in or drop out of the network.`directed`

: If the network is directed or not.`edge_covariates`

: In the`form`

call, are edge or dyad covariates required?`seed`

: Seed set for replication.`R`

: The number of bootstrap replications for the TERGM to be used to generate initial values.`forking`

: Should parallel computing via forking be used?`ncpus`

: If parallel computing is to be used, how many CPUs should be used.`steps`

: The maximum number of steps that the EM process should go through.`tol`

: The acceptance level to assess the convergence of the EM algorithm.

```
library(egoTERGM)
ego_tergm_fit <- ego_tergm(net = net,
form = c("edges", "mutual", "triangle", "nodeicov('idegsqrt')",
"nodeocov('odegsqrt')", "nodematch('sex')"),
core_size = 1,
min_size = 5,
roles = 3,
add_drop = TRUE,
directed = TRUE,
edge_covariates = FALSE,
seed = 12345,
R = 10,
forking = FALSE,
ncpus = 1,
steps = 50,
tol = 1e-06)
```

Once the ego-TERGM is fit using the `ego_tergm`

function, there are two auxilliary functions that can be used to assist in interpreting model results. First, I have provided an `interpret_ego_tegm`

function that cleans up the group-based centroids estimated. A warning message is coded into the function that emphasizes that these centroids should not be interpreted as TERGM parameters, but instead, as a means of understanding the distinctions between role assignments. Second, there is a `plot_ego_tergm`

function that plots the role assignments for the reduced networks. The code is as follows.

To assist in interpreting the role generative structure of role assignments, I have included a simple function, `prepare_for_tergm`

, that takes the output of an `ego_tergm`

call and transforms it into a format that can be used by the `btergm`

function (Leifeld, Cranmer, and Desmarais 2017). The code for this is as follows:

```
net_list <- prepare_for_tergm(ego_tergm_fit = ego_tergm_fit)
# Indexing of the output for prepare_for_tergm refers to the
# role numbering from initial ego_tergm_fit
role1_btergm <- btergm(net_list[[1]] ~ edges + mutual + triangle + nodeicov('idegsqrt') +
nodeocov('odegsqrt') + nodematch('sex'),
R = 500)
# You could then continue this for all remaining network sets
# in net_list
```

Campbell, Benjamin W. 2018. “Detecting Heterogeneity and Inferring Latent Roles in Longitudinal Networks.” *Political Analysis* 26 (3). Cambridge University Press: 292–311.

Knecht, Andrea. 2006. “Networks and Actor Attributes in Early Adolescence.” *ICS Codebook* 61.

Leifeld, Philip, Skyler J Cranmer, and Bruce A Desmarais. 2014. “Xergm: Extensions of Exponential Random Graph Models.” *R Package Version 0.51*.

———. 2017. “Temporal Exponential Random Graph Models with Btergm: Estimation and Bootstrap Confidence Intervals.” *Journal of Statistical Software*. Foundation for Open Access Statistics.

Salter-Townshend, Michael, and Thomas Brendan Murphy. 2015. “Role Analysis in Networks Using Mixtures of Exponential Random Graph Models.” *Journal of Computational and Graphical Statistics* 24 (2). Taylor; Francis: 520–38.