Retrieve, create, and edit the nodal attributes of the main
netsim_dat object of network models, from inside module
functions. Each nodal attribute is a vector with one value per
node, indexed by the positional identifiers of the nodes
(posit_ids).
get_attr()returns one attribute, for all nodes or for the nodes inposit_ids.get_attr_list()returns several attributes as a named list.set_attr()replaces the values of an attribute, for all nodes or for the nodes inposit_ids, and creates the attribute if it does not exist.add_attr()creates an attribute set toNAfor all nodes.append_core_attr()addsn.newnodes and sets their core attributes.append_attr()then adds the values of each other attribute for the same nodes.remove_node_attr()removes the nodes inposit_idsfrom every attribute.get_core_attributes()lists the core attributes with their types.
See net-accessor for an overview of the accessors.
Usage
get_attr(dat, item, posit_ids = NULL, override.null.error = FALSE)
get_attr_list(dat, item = NULL)
set_attr(dat, item, value, posit_ids = NULL, override.length.check = FALSE)
add_attr(dat, item)
append_attr(dat, item, value, n.new)
append_core_attr(dat, at, n.new)
remove_node_attr(dat, posit_ids)
get_core_attributes()Arguments
- dat
Main
netsim_datobject containing anetworkDynamicobject and other initialization information passed fromnetsim().- item
Name of the nodal attribute. For
get_attr_list(), a character vector of names, orNULL(default) for all attributes.- posit_ids
Positional identifiers of the nodes. For
get_attr()andset_attr(), the nodes to get or edit, withNULL(default) for all nodes; forremove_node_attr(), the nodes to remove.- override.null.error
If
TRUE, returnNULLinstead of an error whenitemdoes not exist (default =FALSE).- value
New values of the attribute. For
set_attr(), one value per node, or withposit_ids, one value per selected node or a single value for all of them. Forappend_attr(), one value per new node or a single value for all of them.- override.length.check
If
TRUE,set_attr()accepts avaluewhose length differs from the number of nodes (default =FALSE). Every attribute must again hold one value per node by the end of the time step.- n.new
Number of new nodes: for
append_core_attr(), the nodes to add; forappend_attr(), the number of values to append at the end ofitem.- at
Current time step, recorded as the entry time (
entrTime) of the new nodes.
Value
For get_attr(), the attribute vector, or its values for the
nodes in posit_ids; for get_attr_list(), a named list of
attribute vectors; for get_core_attributes(), a named list with a
value of the correct type for each core attribute. The other
functions return the updated netsim_dat object.
Core Attributes
The append_core_attr function initializes the attributes necessary for
EpiModel to work (the four core attributes are: "active", "unique_id",
"entrTime", and "exitTime"). These attributes are used in the initialization
phase of the simulation, to create the nodes (see
initialize.net()); and also used when adding nodes during the
simulation (see arrivals.net()).
One Value Per Node
Every nodal attribute holds exactly one value per node, and netsim()
checks this at the end of each time step. When set_attr and append_attr
create an attribute, the nodes they do not write to are filled with NA to
preserve that: set_attr with posit_ids fills the unselected nodes, and
append_attr fills the nodes that predate the ones being appended. This
means append_core_attr must be called before append_attr when adding new
nodes, as it is what makes those nodes known to the rest of the object.
Intended Usage
These accessors operate on the live netsim_dat object that EpiModel
constructs internally when a simulation starts and passes through each
module at every time step. The expected calling context is inside a
user-supplied module function (e.g., a custom infection.FUN,
recovery.FUN, or arrivals/departures module) registered with
control.net().
They are not a general-purpose tool for editing the user-facing input
or output objects of netsim():
Calling them on a
param.net(),init.net(), orcontrol.net()object before a run will appear to succeed (those objects are also list-like) but produces an object that is not a valid simulation input.Calling them on the object returned by
netsim()modifies only the saved input slot, not anything that would change the result of a re-run. Note also thatnetsim()strips the*.FUNentries from its returnedcontrolslot, so feeding that slot back into a new simulation will fail.
For modifications outside a running simulation, use the following instead:
Editing parameters before a run:
update_params()for aparam.netobject, or direct list assignment (e.g.,p$inf.prob <- 0.5).Editing init or control before a run: direct list assignment (e.g.,
ctrl$nsteps <- 1000), or rebuild with a fresh call to theinit.net()/control.net()constructor.Scheduled mid-simulation changes: the
.param.updater.listargument toparam.net()and the.control.updater.listargument tocontrol.net(). See the "model-parameters" vignette for the underlying updater module and the scenario API built on top of it.
Mutability
The set_, append_, and add_ functions DO NOT modify the
netsim_dat object in place. The result must be assigned back to
dat in order to be registered: dat <- set_*(dat, item, value).
See also
net-accessor for an overview of the accessors, and get_epi()
and get_param() for the other groups; arrive_nodes() and
depart_nodes() for adding and removing nodes from the networks;
get_unique_ids() and get_posit_ids() for converting node identifiers.
Examples
dat <- create_dat_object(control = list(nsteps = 150))
dat <- append_core_attr(dat, at = 1, n.new = 10)
dat <- add_attr(dat, "age")
dat <- set_attr(dat, "age", runif(10, 15, 65))
dat <- set_attr(dat, "status", rep(c("s", "i"), c(8, 2)))
get_attr_list(dat)
#> $active
#> [1] 1 1 1 1 1 1 1 1 1 1
#>
#> $entrTime
#> [1] 1 1 1 1 1 1 1 1 1 1
#>
#> $exitTime
#> [1] NA NA NA NA NA NA NA NA NA NA
#>
#> $unique_id
#> [1] 1 2 3 4 5 6 7 8 9 10
#>
#> $age
#> [1] 55.47115 35.53215 46.12376 19.40064 42.05494 45.12422 59.13545 24.87035
#> [9] 44.30690 17.36665
#>
#> $status
#> [1] "s" "s" "s" "s" "s" "s" "s" "s" "i" "i"
#>
get_attr_list(dat, c("age", "active"))
#> $age
#> [1] 55.47115 35.53215 46.12376 19.40064 42.05494 45.12422 59.13545 24.87035
#> [9] 44.30690 17.36665
#>
#> $active
#> [1] 1 1 1 1 1 1 1 1 1 1
#>
get_attr(dat, "status")
#> [1] "s" "s" "s" "s" "s" "s" "s" "s" "i" "i"
get_attr(dat, "status", posit_ids = c(1, 9))
#> [1] "s" "i"
# Edit selected nodes
dat <- set_attr(dat, "status", "i", posit_ids = 3)
get_attr(dat, "status")
#> [1] "s" "s" "i" "s" "s" "s" "s" "s" "i" "i"
# Add 5 nodes: core attributes first, then the others
dat <- append_core_attr(dat, at = 2, n.new = 5)
dat <- append_attr(dat, "status", "s", 5)
dat <- append_attr(dat, "age", 15, 5)
get_attr(dat, "age")
#> [1] 55.47115 35.53215 46.12376 19.40064 42.05494 45.12422 59.13545 24.87035
#> [9] 44.30690 17.36665 15.00000 15.00000 15.00000 15.00000 15.00000
get_attr(dat, "entrTime")
#> [1] 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2