scanList
R/expDesign_sampling.R
design_sampling.Rd
This function returns an expDesign
object containing a sampling function to apply to
scanList
objects (see perform_exp()
). It is written as a convenient wrapper
for commonly used sampling methods: group-scan sampling and focal-scan sampling.
design_sampling( method = c("group", "focal"), sampling = c("constant", "matrix", "even", "random", "function"), all.sampled = TRUE )
method | character scalar, either |
---|---|
sampling | depending on chosen
|
all.sampled | logical scalar, should all nodes be sampled at least once? (TO CHECK: does it work with group-scan sampling?) |
an expDesign
object containing a function of a theoretical scan.list
simulating the
empirical sampling of the network's edges at each scan. To be used as part of an expDesign
object (see design_exp()
)
design_sampling()
accepts as sampling
parameter:
character scalar: common options like random edge observation probability or even focal sampling
for method = "group"
: numeric scalar (constant) or matrix representing edge observation
probabilities
user-defined functions of the adjacency matrix Adj
that returns either an edge observation
probability matrix, or a vector of the probabilities of selecting a given node at each focal
scan. If the user-defined function returns invalid probabilities e.g.:
a value > 1 for method = "group"
: the function tries to rescale values via scales
package's rescale_max()
function
some probabilities of being a focal = 0 for method = "focal"
: the function adds the
non-null minimum probability to all probabilities (values > 1 should be handled correctly as
the prob
argument of the sample()
function)
The empirical sampling works by replacing unobserved edges by NA
s in the 3D array, either:
because a given edge hasn't been observed during the group-scan sampling
or because the masked edge was not involving the focal node during the scan
Convenience "building blocks" functions - respectively count_NA()
and
count_nonNA()
- can be used to count masked and sampled edges throughout the
whole simulation.
New attributes are added to attrs
:
in the case of method = "group"
:
obs.P
: matrix of probabilities of observing an edge (whether it is 0 or 1)
in the case of method = "focal"
:
focalList
: named integer vector representing the node's index (row/column) to be sampled
for each scan. Names are obtain from the adjacency matrix Adj
, the vector's length is equal
to n.scans
simunet()
, design_exp()
, perform_exp()
, group_sample()
, determine_obsProb()
,
focal_sample()
, draw_focalList()
, mask_non.focals()
, count_NA()
, count_nonNA()
.
set.seed(42) n <- 5L samp.effort <- 100L # 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])) Adj[lower.tri(Adj,diag = TRUE)] <- 0L Adj#> a b c d e #> a 0 100 37 27 58 #> b 0 0 20 36 42 #> c 0 0 0 5 93 #> d 0 0 0 0 30 #> e 0 0 0 0 0# Designing sampling regimes: ## setting a constant probability of not observing edges group.constant <- design_sampling(method = "group",sampling = 0.8) group.constant#> Theoretical scanList -> #> ------------ #> group-scan sampling: constant -> #> ------------ #> empirical scanList #> #> See `$FUN.seq` for the functions source code.## setting a random probability of not observing edges group.random <- design_sampling(method = "group",sampling = "random") ## setting probability of not observing edges via user-defined functions g.fun1 <- function(Adj) Adj # observation proportional to the network's weights, # will be rescaled as probabilities internally group.fun1 <- design_sampling(method = "group",sampling = g.fun1) ### user-defined functions can also be passed as anonymous functions group.fun2 <- design_sampling(method = "group",sampling = function(Adj) Adj^2) ## evenly select focals focal.even <- design_sampling(method = "focal",sampling = "even") ## randomly select focals focal.random <- design_sampling(method = "focal",sampling = "random") ## setting probability of selecting focals via user-defined functions f.fun1 <- function(Adj) 1:nrow(Adj) # linear increase of probability of being focal, # akin to a linear trait focal.fun1 <- design_sampling(method = "focal",sampling = f.fun1) ### user-defined functions can also be passed as anonymous functions focal.fun2 <- design_sampling(method = "focal",sampling = function(Adj) Adj |> igraph::graph.adjacency(mode = "upper",weighted = TRUE) |> igraph::eigen_centrality() |> {function(x) x$vector}() ) # probabilities proportional to nodes' eigen-vector centralities # Design and run experiment based on these sampling regime ## sampling regimes can be included in an `expDesign` object and passed to `simunet()`... g.const.exp <- design_exp(group.constant) simunet(Adj = Adj,samp.effort = samp.effort,mode = "upper",n.scans = 120L,g.const.exp)#> #> scan: 1 #> a . 1 NA . 1 #> b . . . . . #> c . . . . 1 #> d . . . . . #> e . . . . . #> #> scan: 2 #> a . 1 . . . #> b . . . . 1 #> c . . . . 1 #> d . . . . . #> e . . . . . #> #> ... ( 117 more scans) #> #> scan: 120 #> a . 1 . . 1 #> b . . 1 1 . #> c . . . . 1 #> d . . . . NA #> e . . . . . #> #> #> Hidden attributes: #> scanList.type - raw.scanList - Adj - samp.effort - n.scans - mode #> Adj.subfun - edge.Prob - obs.P - theoretical.scanList## ... or passed to `perform_exp()`... g.rand.periRemoved <- design_exp(remove_mostPeripheral,group.random) sL <- simunet(Adj = Adj,samp.effort = samp.effort,mode = "upper",n.scans = 120L) sL |> perform_exp(g.rand.periRemoved)#> #> scan: 1 #> a . 1 1 1 #> b . . 1 . #> c . . . 1 #> e . . . . #> #> scan: 2 #> a . NA . . #> b . . . NA #> c . . . NA #> e . . . . #> #> ... ( 117 more scans) #> #> scan: 120 #> a . NA 1 . #> b . . NA NA #> c . . . 1 #> e . . . . #> #> #> Hidden attributes: #> scanList.type - raw.scanList - Adj - samp.effort - n.scans - mode #> Adj.subfun - edge.Prob - obs.P - theoretical.scanList## ... or used "in situ" in either `simunet()` or `perform_exp()`, ## but need to be passed to `design_exp()` ## (TO DO: recognize sampling regime and manage this automatically) simunet(Adj = Adj,samp.effort = samp.effort,mode = "upper",n.scans = 120L,design_exp(group.fun2))#> #> scan: 1 #> a . 1 NA NA NA #> b . . NA NA NA #> c . . . NA 1 #> d . . . . NA #> e . . . . . #> #> scan: 2 #> a . 1 1 NA NA #> b . . NA NA NA #> c . . . NA 1 #> d . . . . NA #> e . . . . . #> #> ... ( 117 more scans) #> #> scan: 120 #> a . 1 NA NA NA #> b . . NA NA NA #> c . . . NA NA #> d . . . . NA #> e . . . . . #> #> #> Hidden attributes: #> scanList.type - raw.scanList - Adj - samp.effort - n.scans - mode #> Adj.subfun - edge.Prob - obs.P - theoretical.scanList#> #> scan: 1 #> a . NA 1 NA NA #> b . . 1 NA NA #> c . . . . 1 #> d . . . . NA #> e . . . . . #> #> scan: 2 #> a . 1 . 1 . #> b . . NA NA NA #> c . . . NA NA #> d . . . . NA #> e . . . . . #> #> ... ( 117 more scans) #> #> scan: 120 #> a . 1 NA NA NA #> b . . 1 . . #> c . . . NA NA #> d . . . . NA #> e . . . . . #> #> #> Hidden attributes: #> scanList.type - raw.scanList - Adj - samp.effort - n.scans - mode #> Adj.subfun - edge.Prob - focalList - theoretical.scanList#> #> scan: 1 #> a . 1 1 1 1 #> b . . NA NA NA #> c . . . NA NA #> d . . . . NA #> e . . . . . #> #> scan: 2 #> a . 1 . 1 . #> b . . NA NA NA #> c . . . NA NA #> d . . . . NA #> e . . . . . #> #> ... ( 117 more scans) #> #> scan: 120 #> a . NA 1 NA NA #> b . . 1 NA NA #> c . . . . 1 #> d . . . . NA #> e . . . . . #> #> #> Hidden attributes: #> scanList.type - raw.scanList - Adj - samp.effort - n.scans - mode #> Adj.subfun - edge.Prob - focalList - theoretical.scanList