Perform social network simulations

simunet(
  Adj = NULL,
  samp.effort = NULL,
  mode = c("directed", "undirected", "max", "min", "upper", "lower", "plus", "vector"),
  n.scans = NULL,
  exp.design = NULL,
  ...,
  edge.Prob = NULL
)

Arguments

Adj

integer matrix, the reference adjacency matrix to base edge probabilities on. Users can either:

samp.effort

integer scalar, the sampling effort, or number of scans, that led to obtaining of Adj

mode

character scalar, specifies what igraph network mode should be used to convert the supplied matrix. Ignored if sampling.param is provided. Possible values are:

  • "directed" (the default): for non-symmetrical adjacency matrix where Adj[i,j] doesn't have the same meaning as Adj[j,i]

  • "undirected": same as "max"

  • "upper": undirected matrix focusing only on the upper triangle of Adj (relying on upper.tri). Either "upper" or "lower" could be favor if only one of Adj[i,j] and Adj[j,i] should be randomized

  • "lower": undirected matrix focusing only on the lower triangle of Adj (relying on lower.tri)

  • "max": from a "directed" randomization process (both Adj[i,j] and Adj[j,i] will be drawn at each scan), max(Adj[i,j],Adj[j,i]) will be kept for both

  • "min": from a "directed" randomization process (both Adj[i,j] and Adj[j,i] will be drawn at each scan), min(Adj[i,j],Adj[j,i]) will be kept for both

  • "plus.": from a "directed" randomization process (both Adj[i,j] and Adj[j,i] will be drawn at each scan), Adj[i,j] + Adj[j,i] will be kept for both

  • "vector": experimental. To consider adjacency matrices as flat vectors to be randomized. Relevance unexplored yet.

  • See details in the relevant igraph package documentation.

n.scans

integer scalar, number of scans to generate in the simulation

exp.design

expDesign object (cf. design_exp() function, or ?design_exp), that consists in a sequence of experimental manipulations (functions) to perform on the (theoretical) scanList to be simulated to obtain a empirical scanList.

...

additional arguments to be passed to the function. Specifically, this is used at the moment to pass more than one expDesign object to run multiple experiments on a given theoretical scanList. This cause the returned object to be a list of empirical scanList, i.e. a sLlist object.

edge.Prob

optional. An edgeProb object (cf. generate_edgeProb()) that consists in the edge presence probability matrix at each scan. The probability matrix is drawn from a beta distribution determined via Bayesian inference, from Adj and samp.effort.

edgeProb object are actually lists that contain the following components:

  • P: the edge presence probability matrix

  • Adj: the inputted adjacency matrix

  • samp.effort: the inputted sampling effort

  • mode: the inputted igraph mode

  • Adj.subfun: a matrix function, determined from the igraph mode (cf. ), that return a logical matrix with TRUE values only for matrix cells relevant to the igraph mode. e.g. only the upper triangle for mode = "upper"

Value

a scanList object, primarily a 3 dimensional array representing the (binary) adjacency matrices (coded within the first two dimensions of the 3D-array) obtained at each simulated scan (coded as the 3rd dimension of the 3D-array), and a list of attributes.

scanList objects have this common structure:

  • the 3D-array where the first 2 dimensions are the adjacency matrices (with the node names from Adj) and the 3rd dimension is the simulated scan number

  • an attribute named attrs: a list of objects - see attrs as a flat list of attributes - that are recorded throughout the simulation and subsequent experimental manipulations. We provide an equivalent to r base's attr() function - attrs() - to retrieve scanList objects' named attributes contained in their attrs

Examples

set.seed(42) n <- 5L samp.effort <- 241L # Adjacency matrix import ## random directed adjacency matrix Adj <- sample(1:samp.effort,n * n) |> matrix(nrow = 5,dimnames = list(letters[1:n],letters[1:n])) diag(Adj) <- 0L Adj
#> a b c d e #> a 0 228 47 165 111 #> b 229 0 24 110 131 #> c 65 122 0 20 41 #> d 153 241 100 0 227 #> e 74 128 89 114 0
## manual lower adjacency matrix Adj <- c(0, 0, 0, 0,0, 1, 0, 0, 0,0, 2, 3, 0, 0,0, 4, 5, 6, 0,0, 7, 8, 9,10,0) |> matrix(nrow = 5,byrow = TRUE,dimnames = list(as.character(1:n),as.character(1:n))) Adj
#> 1 2 3 4 5 #> 1 0 0 0 0 0 #> 2 1 0 0 0 0 #> 3 2 3 0 0 0 #> 4 4 5 6 0 0 #> 5 7 8 9 10 0
## upper adjacency matrix imported from ASNR (https://github.com/bansallab/asnr) if (FALSE) { Adj <- import_from_asnr(class = "Mammalia", species = "kangaroo_proximity_weighted", output = "adjacency",type = "upper") Adj } # this is retrieving and importing this matrix: node_names <- c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17) |> as.character() Adj <- c(0, 21, 10, 45, 54, 7, 16, 1, 3, 4, 7, 3, 2, 3, 3, 0, 0, 0, 0, 9, 19, 20, 3, 9, 1, 10, 4, 11, 2, 2, 2, 6, 0, 0, 0, 0, 0, 8, 10, 3, 5, 1, 9, 4, 10, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 45, 7, 17, 1, 1, 3, 6, 3, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 6, 17, 1, 3, 4, 6, 1, 2, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 4, 1, 2, 2, 3, 3, 3, 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 5, 3, 1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 9, 1, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) |> matrix(nrow = 17,byrow = TRUE,dimnames = list(node_names,node_names)) Adj
#> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #> 1 0 21 10 45 54 7 16 1 3 4 7 3 2 3 3 0 0 #> 2 0 0 9 19 20 3 9 1 10 4 11 2 2 2 6 0 0 #> 3 0 0 0 8 10 3 5 1 9 4 10 0 0 0 3 2 0 #> 4 0 0 0 0 45 7 17 1 1 3 6 3 2 3 4 0 0 #> 5 0 0 0 0 0 6 17 1 3 4 6 1 2 3 3 1 0 #> 6 0 0 0 0 0 0 4 1 2 2 3 3 3 1 4 0 0 #> 7 0 0 0 0 0 0 0 1 0 0 5 3 1 3 3 0 0 #> 8 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 #> 9 0 0 0 0 0 0 0 0 0 6 9 1 0 0 2 0 1 #> 10 0 0 0 0 0 0 0 0 0 0 8 1 0 0 0 0 0 #> 11 0 0 0 0 0 0 0 0 0 0 0 1 2 0 5 0 0 #> 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 #> 13 0 0 0 0 0 0 0 0 0 0 0 0 0 1 3 0 0 #> 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 #> 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 #> 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 #> 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
# social network simulations ## theoretical scans sL <- simunet(Adj = Adj,samp.effort = samp.effort,mode = "upper",n.scans = 120L) sL
#> #> scan: 1 #> 1 . . . . . . . . . . . . . . . . . #> 2 . . . . . . . . . . . . . . . . . #> 3 . . . . . . . . . . . . . . . . . #> 4 . . . . . 1 . . . . . . . 1 . . . #> 5 . . . . . . . . . . . . . . . . . #> 6 . . . . . . . . . . . . . . . . . #> 7 . . . . . . . . . . . . . . . . . #> 8 . . . . . . . . . . . . . . . . . #> 9 . . . . . . . . . . . . . . . . . #> 10 . . . . . . . . . . . . . . . . . #> 11 . . . . . . . . . . . . . . . . . #> 12 . . . . . . . . . . . . . . . . . #> 13 . . . . . . . . . . . . . . . . . #> 14 . . . . . . . . . . . . . . . . . #> 15 . . . . . . . . . . . . . . . . . #> 16 . . . . . . . . . . . . . . . . . #> 17 . . . . . . . . . . . . . . . . . #> #> scan: 2 #> 1 . . . . . . . . . . . . . . . . . #> 2 . . . . . . . . . . . . . . . . . #> 3 . . . . . . . . . . . . . . . . . #> 4 . . . . . . . . . . 1 . . . . . . #> 5 . . . . . . . . . . . . . . . . . #> 6 . . . . . . . . . . . . . . . . . #> 7 . . . . . . . 1 . . . . . . . . . #> 8 . . . . . . . . . . . . . . . . . #> 9 . . . . . . . . . . . . . . . . . #> 10 . . . . . . . . . . . . . . . . . #> 11 . . . . . . . . . . . . . . . . . #> 12 . . . . . . . . . . . . . . . . . #> 13 . . . . . . . . . . . . . . . . . #> 14 . . . . . . . . . . . . . . . . . #> 15 . . . . . . . . . . . . . . . . . #> 16 . . . . . . . . . . . . . . . . . #> 17 . . . . . . . . . . . . . . . . . #> #> ... ( 117 more scans) #> #> scan: 120 #> 1 . . . . . . . . . . . . . 1 . . . #> 2 . . . . . . 1 . . . . . . . . . . #> 3 . . . . . . . . . . . . . . . . . #> 4 . . . . . . . . . . . . . . . . . #> 5 . . . . . . . . . . . . . . . . . #> 6 . . . . . . . . . . . . . . . . . #> 7 . . . . . . . . . . . . . . . . . #> 8 . . . . . . . . . . . . . . . . . #> 9 . . . . . . . . . . . . . . . . . #> 10 . . . . . . . . . . . . . . . . . #> 11 . . . . . . . . . . . . . . . . . #> 12 . . . . . . . . . . . . . . . . . #> 13 . . . . . . . . . . . . . . . . . #> 14 . . . . . . . . . . . . . . . . . #> 15 . . . . . . . . . . . . . . . . . #> 16 . . . . . . . . . . . . . . . . . #> 17 . . . . . . . . . . . . . . . . . #> #> #> Hidden attributes: #> scanList.type - raw.scanList - Adj - samp.effort - n.scans - mode #> Adj.subfun - edge.Prob
sL |> sum_scans()
#> #> Weighted adjacency matrix #> 1 . 10 14 24 29 5 6 2 1 2 3 4 4 2 1 . . #> 2 . . 3 14 8 1 7 1 5 . 5 . 2 . 1 . . #> 3 . . . 6 6 2 2 . 9 2 3 1 . . . . . #> 4 . . . . 28 6 9 . 1 7 5 1 2 5 3 . . #> 5 . . . . . 2 6 . 1 1 2 . 5 2 4 . 1 #> 6 . . . . . . 2 1 2 3 . 2 1 . 1 3 . #> 7 . . . . . . . 1 . . 2 . . 2 . . . #> 8 . . . . . . . . . 1 . 2 . . 1 . . #> 9 . . . . . . . . . 3 7 . . . 1 . . #> 10 . . . . . . . . . . 1 2 1 . . . . #> 11 . . . . . . . . . . . . 1 . . . . #> 12 . . . . . . . . . . . . . . . 2 . #> 13 . . . . . . . . . . . . . 1 . . . #> 14 . . . . . . . . . . . . . . . . . #> 15 . . . . . . . . . . . . . . . . 1 #> 16 . . . . . . . . . . . . . . . . 3 #> 17 . . . . . . . . . . . . . . . . . #> #> #> Hidden attributes: #> scanList.type - raw.scanList - Adj - samp.effort - n.scans - mode #> Adj.subfun - edge.Prob - summed.scanList - sampled
## group-scan sampling ### Designing the experiment: setting a constant probability of not observing edges group.scan <- design_sampling(method = "group",sampling = 0.8) ### simulation can be directly run through the simunet() function simunet(Adj = Adj,samp.effort = samp.effort,mode = "upper",n.scans = 120L, exp.design = group.scan)
#> #> scan: 1 #> 1 . . . . . . 1 . . . . . . . . . NA #> 2 . . . . . . . . NA . . NA . . . . . #> 3 . . . . . . . . NA NA . . . . . NA NA #> 4 . . . . . NA . . . . . . . NA . . . #> 5 . . . . . NA . . . . . . . . NA . . #> 6 . . . . . . NA . 1 . . . NA . . . . #> 7 . . . . . . . . . . NA . . . . . . #> 8 . . . . . . . . NA . . . . NA . . . #> 9 . . . . . . . . . . . NA . . NA . . #> 10 . . . . . . . . . . . . NA . . . . #> 11 . . . . . . . . . . . . NA NA NA . . #> 12 . . . . . . . . . . . . . . . . . #> 13 . . . . . . . . . . . . . . . . . #> 14 . . . . . . . . . . . . . . . NA . #> 15 . . . . . . . . . . . . . . . . NA #> 16 . . . . . . . . . . . . . . . . . #> 17 . . . . . . . . . . . . . . . . . #> #> scan: 2 #> 1 . . . . . NA . NA . . . . NA . . . . #> 2 . . . NA . . NA . 1 . . . NA . NA . . #> 3 . . . NA . . . . . NA . . . . . . . #> 4 . . . . NA . . . . NA . . . NA . . . #> 5 . . . . . NA NA NA . . 1 . . . . NA . #> 6 . . . . . . NA . . . NA . . NA NA NA . #> 7 . . . . . . . . . . NA . NA . NA . NA #> 8 . . . . . . . . . NA NA . . NA . NA . #> 9 . . . . . . . . . . . . . . NA . . #> 10 . . . . . . . . . . . . . . NA . . #> 11 . . . . . . . . . . . . . . . . . #> 12 . . . . . . . . . . . . . . . . . #> 13 . . . . . . . . . . . . . . NA . . #> 14 . . . . . . . . . . . . . . . . NA #> 15 . . . . . . . . . . . . . . . . . #> 16 . . . . . . . . . . . . . . . . . #> 17 . . . . . . . . . . . . . . . . . #> #> ... ( 117 more scans) #> #> scan: 120 #> 1 . . . . . . . . . . . . . . NA . . #> 2 . . . . . . . NA NA . 1 NA . . . NA . #> 3 . . . . . . . . . NA . . . . NA . NA #> 4 . . . . . . . . NA . NA . . . . . . #> 5 . . . . . . . NA NA . . . . . . . . #> 6 . . . . . . NA NA . NA . . NA . . . NA #> 7 . . . . . . . . . . . . . . NA . . #> 8 . . . . . . . . . . NA . . NA NA NA . #> 9 . . . . . . . . . . . . NA . . . . #> 10 . . . . . . . . . . . . . NA . . . #> 11 . . . . . . . . . . . . . . . . . #> 12 . . . . . . . . . . . . . . NA . NA #> 13 . . . . . . . . . . . . . . NA NA . #> 14 . . . . . . . . . . . . . . . NA NA #> 15 . . . . . . . . . . . . . . . . . #> 16 . . . . . . . . . . . . . . . . . #> 17 . . . . . . . . . . . . . . . . . #> #> #> Hidden attributes: #> scanList.type - raw.scanList - Adj - samp.effort - n.scans - mode #> Adj.subfun - edge.Prob - obs.P - theoretical.scanList
### or the experiment can be applied to a theoretical scanList object group.sL <- perform_exp(sL,group.scan) group.sL |> count_nonNA()
#> #> Weighted adjacency matrix #> 1 . 90 96 92 95 99 97 99 93 103 96 90 99 92 88 98 93 #> 2 . . 99 94 85 96 93 103 97 97 101 98 95 100 103 95 98 #> 3 . . . 105 95 100 99 97 96 102 89 94 89 101 96 94 92 #> 4 . . . . 88 88 88 102 101 97 96 98 93 97 99 102 98 #> 5 . . . . . 97 93 92 96 97 93 94 87 96 91 92 99 #> 6 . . . . . . 85 96 92 97 101 94 97 97 98 94 94 #> 7 . . . . . . . 95 96 96 94 99 93 95 103 100 91 #> 8 . . . . . . . . 99 91 98 95 102 97 101 96 89 #> 9 . . . . . . . . . 89 95 92 89 91 97 99 99 #> 10 . . . . . . . . . . 95 102 99 97 94 95 96 #> 11 . . . . . . . . . . . 92 91 97 98 95 100 #> 12 . . . . . . . . . . . . 100 91 94 92 99 #> 13 . . . . . . . . . . . . . 96 97 94 96 #> 14 . . . . . . . . . . . . . . 95 96 89 #> 15 . . . . . . . . . . . . . . . 99 100 #> 16 . . . . . . . . . . . . . . . . 95 #> 17 . . . . . . . . . . . . . . . . . #> #> #> Hidden attributes: #> scanList.type - raw.scanList - Adj - samp.effort - n.scans - mode #> Adj.subfun - edge.Prob - obs.P - theoretical.scanList
group.sL |> sum_scans()
#> #> Weighted adjacency matrix #> 1 . 7 11 15 21 3 6 2 1 2 3 3 3 1 1 . . #> 2 . . 3 12 6 . 7 1 3 . 5 . 1 . . . . #> 3 . . . 4 5 2 2 . 6 1 1 1 . . . . . #> 4 . . . . 19 5 5 . 1 5 4 . 2 5 3 . . #> 5 . . . . . 1 5 . 1 1 2 . 5 2 3 . 1 #> 6 . . . . . . 2 1 1 2 . 2 1 . 1 2 . #> 7 . . . . . . . 1 . . 2 . . 2 . . . #> 8 . . . . . . . . . . . 1 . . 1 . . #> 9 . . . . . . . . . 3 5 . . . 1 . . #> 10 . . . . . . . . . . 1 2 1 . . . . #> 11 . . . . . . . . . . . . . . . . . #> 12 . . . . . . . . . . . . . . . 2 . #> 13 . . . . . . . . . . . . . 1 . . . #> 14 . . . . . . . . . . . . . . . . . #> 15 . . . . . . . . . . . . . . . . 1 #> 16 . . . . . . . . . . . . . . . . 1 #> 17 . . . . . . . . . . . . . . . . . #> #> #> Hidden attributes: #> scanList.type - raw.scanList - Adj - samp.effort - n.scans - mode #> Adj.subfun - edge.Prob - obs.P - theoretical.scanList - summed.scanList - sampled
## add more scans, perform even focal sampling, then remove the overall most peripheral node foc.peri_removed <- design_exp(function(x) add_scans(x,200), design_sampling(method = "focal",sampling = "even"), remove_mostPeripheral ) ### or the experiment can be applied to a theoretical scanList object foc.peri_removed.sL <- perform_exp(sL,foc.peri_removed) foc.peri_removed.sL |> count_nonNA()
#> #> Weighted adjacency matrix #> 1 . 36 37 36 37 37 37 37 37 37 37 37 37 37 37 37 #> 2 . . 37 36 37 37 37 37 37 37 37 37 37 37 37 37 #> 3 . . . 37 38 38 38 38 38 38 38 38 38 38 38 38 #> 4 . . . . 37 37 37 37 37 37 37 37 37 37 37 37 #> 5 . . . . . 38 38 38 38 38 38 38 38 38 38 38 #> 6 . . . . . . 38 38 38 38 38 38 38 38 38 38 #> 7 . . . . . . . 38 38 38 38 38 38 38 38 38 #> 8 . . . . . . . . 38 38 38 38 38 38 38 38 #> 9 . . . . . . . . . 38 38 38 38 38 38 38 #> 10 . . . . . . . . . . 38 38 38 38 38 38 #> 11 . . . . . . . . . . . 38 38 38 38 38 #> 12 . . . . . . . . . . . . 38 38 38 38 #> 13 . . . . . . . . . . . . . 38 38 38 #> 14 . . . . . . . . . . . . . . 38 38 #> 15 . . . . . . . . . . . . . . . 38 #> 17 . . . . . . . . . . . . . . . . #> #> #> Hidden attributes: #> scanList.type - raw.scanList - Adj - samp.effort - n.scans - mode #> Adj.subfun - edge.Prob - focalList - theoretical.scanList
foc.peri_removed.sL |> sum_scans()
#> #> Weighted adjacency matrix #> 1 . 2 2 6 7 2 1 . . 1 1 1 . 2 . . #> 2 . . 1 5 6 . 3 . . . 2 1 . . . . #> 3 . . . . 3 1 . . 1 2 2 1 . . . . #> 4 . . . . 5 3 2 . 1 . . . . 1 1 . #> 5 . . . . . 2 . . . 1 3 . 1 1 1 . #> 6 . . . . . . 1 . . . . . . . 1 . #> 7 . . . . . . . 1 . . . . . . . . #> 8 . . . . . . . . . 1 1 1 . . . . #> 9 . . . . . . . . . 2 4 . . . . . #> 10 . . . . . . . . . . 1 1 1 . . . #> 11 . . . . . . . . . . . . . . 1 . #> 12 . . . . . . . . . . . . . . . . #> 13 . . . . . . . . . . . . . . 2 . #> 14 . . . . . . . . . . . . . . . . #> 15 . . . . . . . . . . . . . . . . #> 17 . . . . . . . . . . . . . . . . #> #> #> Hidden attributes: #> scanList.type - raw.scanList - Adj - samp.effort - n.scans - mode #> Adj.subfun - edge.Prob - focalList - theoretical.scanList - summed.scanList - sampled