Skip to content

Conversation

@sgoodreau
Copy link
Contributor

in the lines extracting vectors of tails and heads.
The issue was identified by Lin Zhu, and explained in an email exchange.
I have dived into the code to understand the logic. I agree that her edits are logically correct. I have tested with and without the edits and confirmed that the edits work.

Code below to demonstrate:

# load packages, all LATEST versions as of 2025.10.07-------

library(ergm)                # 4.9.0
library(tergm)               # 4.2.2
library(network)             # 1.19.0
library(networkDynamic)      # 0.11.5
library(sna)                 # 2.8
library(tsna)                # 0.3.6
library(statnet.common)      # 4.12.0

# clear env
rm(list=ls())
set.seed(1)

# create networkDynamic object
nw <- network(100, directed = FALSE)
nwd <- as.networkDynamic(nw) 
nwd <- activate.vertices(nwd, onset=0, terminus = Inf)
nwd <- activate.edges(nwd, onset = 0, terminus = Inf)
set.network.attribute(nwd,'vertex.pid','vertex.names')

# fit model
myergm <- ergm(nwd~edges + degree(1), target.stats = c(150, 30)) 

# adjust formation coef
myergm_adj <- myergm
myergm_adj$coefficients[1]  <- coef(myergm)[1] - 3.555348
  
# fit model without deleting node
at <- 2
my_sim_1 <- simulate(nwd,
                seed = 12345,
                formation = ~edges + degree(1),
                dissolution = ~offset(edges),
                coef.form = coef(myergm_adj),
                coef.diss = 3.555348,
                time.start = at,
                time.slices = 10,
                time.offset = 0,
                control = control.simulate.network(MCMC.burnin.min = 1e5))

# delete one vertex

nwd_del <- nwd
nwd_del <- delete.vertices(nwd_del, 1)

# fit model on network with one vertex deleted
at <- 2
my_sim_del <- simulate(nwd_del,
                     seed = 12345,
                     formation = ~edges + degree(1),
                     dissolution = ~offset(edges),
                     coef.form = coef(myergm_adj),
                     coef.diss = 3.555348,
                     time.start = at,
                     time.slices = 10,
                     time.offset = 0,
                     control = control.simulate.network(MCMC.burnin.min = 1e5))

# without fix, returns error: Error in lttails[w2] <- ltheads[w2] : 
#      NAs are not allowed in subscripted assignments

# traceback:
# 11: network.extract.with.lasttoggle(object, start)
# etc.

# Inside network.extract.with.lasttoggle:
# line 4: lts <- unlist(lapply(lapply(lapply(nwd$mel, "[[", "atl"), 
#                  "[[", "active"), function(x) suppressWarnings(max(x[x <= 
#                  at]))))[valid_eids]
# yields:
# [1] 80 25 16 71 27  2 57 43 57  6 14  3 20 53 19  7  9  4 56 34 35 27 74 15 24 45 22 30
# [29] 16 67 59 74 64 13 28 23 29 34 18  5 11 12 20 53 18  4 12 52 12 21 38 55 91 14  5  2
# [57] 40 49 16  9 75 10 39  3  7 27 12 45 55 18  5 51  5 41 50 48 21 20 14 75 22  3 29 60
# [85]  3 11  3 14 13 20 34 64  7  2 NA NA NA NA

# the NAs are because the code in network.extract.with.lasttoggle says:
#   tails <- unlist(lapply(nwd$mel, "[[", "outl"))[valid_eids]
#   heads <- unlist(lapply(nwd$mel, "[[", "inl"))[valid_eids]
# and this code first pulls out the entries, then checks for valid_eids, then unlists.  
# But it should check for valid_ids, then pull out the entries, then unlist.  I.e.:
#   tails <- unlist(lapply(nwd$mel, "[[", "outl")[valid_eids])
#   heads <- unlist(lapply(nwd$mel, "[[", "inl")[valid_eids])
# It appears that the code might actually also work as:
#   tails <- unlist(lapply(nwd$mel, "[[", "outl"))
#   heads <- unlist(lapply(nwd$mel, "[[", "inl"))
# because during the lapply any with NULL values get dropped anyway, so there's 
#   no need to re-drop them by using [valid_eids]. But the first version seems safer.

@krivit krivit merged commit 65e16d5 into master Oct 15, 2025
21 checks passed
@krivit
Copy link
Member

krivit commented Oct 15, 2025

Thanks!

@krivit krivit deleted the fix_bug_in_network_extract_with_lasttoggle branch October 15, 2025 23:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants