knitr::opts_chunk$set( collapse = TRUE, comment = "#>" )
Within experimental designs, sampling via a given method is considered similarly to other "building blocks" manipulations. Conceptually, they also:
scanList
as an inputNA
in the
scanList regardless of them being 1
or 0
originallyNA
sscanList
Designing a sampling method - or creating a expDesign
object in SimuNet
- relies on
design_sampling()
:
design_sampling()
creates an expDesign
object containing a sampling function of scanList
method
and sampling
can be used to:method
: choose between performing a group-scan or focal-scan samplingsampling
: specify sampling parameters for the chosen method
. This can include:"random"
or "even"
See below to see how to specify varied sampling designs. Sampling can be only part of the overall experimental design, and for instance follow a sequence of other manipulations. See them in action in the following examples!
Group-scan sampling is the act of looking at the whole group during scans, and seeing who is associated/interacting with whom.
method = "group"
obs.P
, and stored in resulting
scanList
's attributes list attrs
.library(SimuNet) design_sampling(method = "group",sampling = "random")
The returned expDesign
can be passed to design_exp()
to make it a component of a larger
experimental design:
group.rand <- design_sampling(method = "group",sampling = "random") design_exp(remove_mostPeripheral,group.rand) # or design_exp(remove_mostPeripheral,design_sampling(method = "group",sampling = "random"))
Let's apply it to a scanList
:
set.seed(42) n <- 5L samp.effort <- 100L 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 sL.group <- simunet(Adj,samp.effort,"upper",10,group.rand) sL.group sL <- simunet(Adj,samp.effort,"upper",10) sL |> perform_exp(group.rand)
We can for instance compare the second scan before and after group-scan sampling:
sL.group$theoretical.scanList[,,2] sL.group[,,2]
As you can see, the edge present between nodes b and e has been missed, but not the ones between a and b.
obs.P
can be defined via several routines
Like in the previous example, observation probabilities can be determined at random. Input
sampling
as the character string "random"
design_sampling("group",sampling = "random")
Note that with sampling = "random"
, obs.P
is randomly drawn before being applied to a
scanList
, but that for all scans the same obs.P
is used to mask edges.
sL |> perform_exp(group.rand) |> attrs("obs.P") # Retrieve the obs.P drawn and applied to the same sL |> perform_exp(group.rand) |> attrs("obs.P") # scanList.
All probabilities can be set to a constant probability. Input this constant as the sampling argument:
group.cst <- design_sampling("group",sampling = 0.8) # an edge has 80% chances of being observed group.cst sL.cst <- sL |> perform_exp(group.cst) sL.cst sL.cst |> count_nonNA() # Inputting `sampling` as the string "constant" returns an error leading to inputting the constant # sL |> perform_exp(design_sampling("group",sampling = "constant"))
By inputting a function of Adj returning a similarly-dimensioned probability matrix, you can design
several routines. To do so, pass the function as the sampling
argument
central.bias_fun <- function(Adj) { str <- Adj |> igraph::graph.adjacency(mode = "upper",weighted = TRUE) |> igraph::strength() obs.P <- str %o% str diag(obs.P) <- 0 obs.P / (max(obs.P) + 1) } central.bias_fun(Adj) # each edge presence probability is the product of the nodes' strength group.bias <- design_sampling("group",sampling = central.bias_fun) sL.bias <- sL |> perform_exp(group.bias) sL.bias sL.bias |> count_nonNA() sL.bias$obs.P # you can note that obs.P is internally a triangular matrix like Adj sL |> scale_scans() sL.bias |> scale_scans()
Focal(-scan) sampling is the act of following a focal individual, and record all associations/interactions involving it.
A focal-scan sampling would be recording data "on the tick", but focal scans can also be defined as continuous.
We argue that by dividing a continuous focal sampling into segments and observing association within each segments, one can "binarize" a continuous sampling into a scan equivalent, should it require dividing the continuous scan into the smallest segments sampling resolution allows (e.g. each minute).
method = "focal"
focalList
, and stored
in resulting scanList
's attributes list attrs
.## randomly select focals focal.rand <- design_sampling(method = "focal",sampling = "random") sL.foc <- sL |> perform_exp(focal.rand) sL.foc sL.foc |> attrs("focalList")
We can again compare for instance the fifth scan before and after focal-scan sampling:
sL.foc$theoretical.scanList[,,5] sL.foc[,,5]
focalList
can be defined via several routines
Like in the previous example, focals can be selected at random. Input sampling
as the character
string "random"
## randomly select focals design_sampling(method = "focal",sampling = "random")
Again, note that with sampling = "random"
, focalList
is randomly drawn before being applied to a
scanList
.
sL |> perform_exp(focal.rand) |> attrs("focalList") # Retrieve the focalList drawn and applied to sL |> perform_exp(focal.rand) |> attrs("focalList") # the same scanList.
Efforts can be made to draw a focal list as evenly as possible (each node is sampled almost as many
time). Input sampling
as the character string "even"
(the default).
## randomly select focals focal.even <- design_sampling(method = "focal",sampling = "even") sL.even <- sL |> perform_exp(focal.even) sL.even sL.even$focalList
By inputting a function of Adj returning a probability vector (which length is the number of nodes),
you can design several focal selection routines. To do so, pass the function as the
sampling
argument
trait_bias <- function(Adj) { n <- nrow(Adj) 1:n # imagine the node index to be a trait that biases (favors) the selection of the node as focal } trait_bias(Adj) # focal.bias <- design_sampling("focal",sampling = trait_bias) sL.bias <- sL |> perform_exp(focal.bias) sL.bias sL.bias |> count_nonNA() sL.bias$focalList sL |> scale_scans() sL.bias |> scale_scans()
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.