Skip to content

Commit 591f4f0

Browse files
committed
Merge branch '47-split-behaviors-patch' into 47-split-behaviors-rdiffnet
2 parents 6399374 + 746f310 commit 591f4f0

File tree

2 files changed

+71
-3
lines changed

2 files changed

+71
-3
lines changed

R/rdiffnet.r

+44-3
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,8 @@ rdiffnet <- function(
320320
exposure.args = list(),
321321
name = "A diffusion network",
322322
behavior = "Random contagion",
323-
stop.no.diff = TRUE
323+
stop.no.diff = TRUE,
324+
disadopt = NULL
324325
) {
325326

326327
# Checking options
@@ -451,6 +452,8 @@ rdiffnet <- function(
451452
# Step 3.0: Running the simulation -------------------------------------------
452453

453454
for (i in 2:t) {
455+
456+
# 3.1 Computing exposure
454457
if (exists("attrs_arr")){
455458
exposure.args[c("attrs")] <- list(attrs_arr[,i, ,drop=FALSE])
456459
}
@@ -460,24 +463,62 @@ rdiffnet <- function(
460463

461464
for (q in 1:num_of_behaviors) {
462465

466+
# 3.2 Identifying who adopts based on the threshold
463467
whoadopts <- which( (expo[,,q] >= thr[,q]) )
468+
469+
# 3.3 Updating the cumadopt
464470
cumadopt[whoadopts, i:t, q] <- 1L
465-
# ADD SOMETHING TO DISADOPT
466471

472+
# 3.4` Updating the toa
473+
# toa[cbind(whoadopts, q)] <- i
467474
toa[, q] <- apply(cumadopt[,, q], 1, function(x) {
468475
first_adopt <- which(x == 1)
469476
if (length(first_adopt) > 0) first_adopt[1] else NA
470477
})
471478

472479
}
480+
481+
if (length(disadopt)) {
482+
483+
# Run the disadoption algorithm. This will return the following:
484+
# - A list of length q with the nodes that disadopted
485+
disadopt_res <- disadopt(expo, cumadopt, i)
486+
487+
for (q in seq_along(disadopt_res)) {
488+
489+
# So only doing this is there's disadoption
490+
if (length(disadopt_res[[q]]) == 0)
491+
next
492+
493+
# Checking this makes sense (only adopters can disadopt)
494+
q_adopters <- which(!is.na(toa[, q]))
495+
496+
if (length(setdiff(disadopt_res[[q]], q_adopters)) > 0)
497+
stop("Some nodes that disadopted were not adopters.")
498+
499+
# Updating the cumadopt
500+
cumadopt[disadopt_res[[q]], i:t, q] <- 0L
501+
502+
# Updating toa
503+
toa[cbind(disadopt_res[[q]], q)] <- NA
504+
505+
}
506+
507+
508+
}
473509
}
474510

475511
for (i in 1:num_of_behaviors) {
476512
reachedt <- max(toa[,i], na.rm=TRUE)
477513

478514
if (reachedt == 1) {
479515
if (stop.no.diff)
480-
stop(paste("No diffusion in this network for behavior", i, "(Ups!) try changing the seed or the parameters."))
516+
stop(
517+
paste(
518+
"No diffusion in this network for behavior", i,
519+
"(Ups!) try changing the seed or the parameters."
520+
)
521+
)
481522
else
482523
warning(paste("No diffusion for behavior", i, " in this network."))
483524
}

tests/testthat/test-rdiffnet.R

+27
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,33 @@ test_that("toa, adopt, and cumadopt should be equal! (split_behaviors tests)", {
180180
expect_equal(net_single_from_multiple_1$cumadopt, net_single$cumadopt)
181181
})
182182

183+
test_that("Disadoption works", {
184+
185+
186+
set.seed(1231)
187+
n <- 500
188+
189+
d_adopt <- function(expo, cumadopt, time) {
190+
191+
# Id double adopters
192+
ids <- which(apply(cumadopt[, 3, , drop=FALSE], 1, sum) > 1)
193+
194+
if (length(ids) == 0)
195+
return(list(integer(), integer()))
196+
197+
# Otherwise, make them pick one (literally, you can only adopt
198+
# A single behavior, will drop the second)
199+
return(list(ids, integer()))
200+
201+
}
202+
203+
ans <- rdiffnet(n = n, t = 10, disadopt = d_adopt, seed.p.adopt = list(0.1, 0.1))
204+
205+
tmat <- toa_mat(ans)
206+
should_be_ones_or_zeros <- tmat[[1]]$cumadopt[, 10] + tmat[[2]]$cumadopt[, 10]
207+
expect_true(all(should_be_ones_or_zeros %in% c(0,1)))
208+
209+
})
183210

184211
#rdiffnet(100, 5, seed.p.adopt = 0.9, threshold.dist = 2, exposure.args = list(normalized=FALSE))
185212

0 commit comments

Comments
 (0)