R/class_stocnet.R, R/class_validate.R
make_stocnet.RdThe 'stocnet' class of network object is a list of six elements: nodes, ties, (nodal) changes, globals, missings, and info metadata about the network as a whole. Every element but info is a table, which is what its plural name signifies, and any of them may be NULL. This offers a consistent and flexible structure that enables more complex forms of networks to be contained in a single object.
Unlike 'mnet' objects, 'stocnet' objects are not layered on top of 'igraph' or 'tbl_graph' objects, but instead are a list of tibbles and metadata. Unlike 'igraph' or 'tbl_graph' objects, 'stocnet' objects typically include more complex multimodal, longitudinal, or dynamic networks. They also typically include more metadata about the network, such as the names of the types of nodes and ties in the network. In other words, they are made not just for network analysis, but also network modelling.
make_stocnet(
info = NULL,
nodes = NULL,
ties = NULL,
changes = NULL,
globals = NULL,
missings = NULL
)
# S3 method for class 'stocnet'
print(x, ..., n = 12)
validate_stocnet(.data)A list of metadata about the network as a whole. This can include the name of the network, as well as the names of the types of nodes and ties in the network. For example, the info component could include a 'name' element with the name of the network, a 'modes' element with a character vector of the names of the types of nodes in the network, and a 'layers' element with a character vector of the names of the types of ties in the network. By default NULL.
A tibble of nodes in the network, with one row per node and one column for the node labels, which should be called 'label'. Additional columns can be included for node attributes, such as 'active' for changing networks and 'mode' for multimodal networks. By default NULL.
A tibble of ties in the network, with one row per tie and at least two columns for the node labels of the tie endpoints, which should be called 'from' and 'to', even if the network is not directed. Additional columns can be included for tie attributes, such as 'weight' for weighted networks and 'layer' for multiplex networks. By default NULL.
A tibble of nodal changes in the network, with one row per change and at least three columns for the node label of the change, which should be called 'node', the variable to which the change applies, which should be called 'var', and the new value to be applied, which should be called 'value'. Additional columns can be included for the time of the change, such as 'wave' or 'time'. By default NULL.
A tibble of global variables in the network, with one row per change and at least three columns for the variable to which the change applies, which should be called 'var', the time of the change, which should be called 'time', and the new value to be applied, which should be called 'value'. By default NULL.
A tibble of the ties the network could have observed and did not, with one row per tie and at least two columns for its endpoints, which should be called 'from' and 'to'. Only the ties that no node's non-response implies need be listed here; see the Missingness section. By default NULL.
An object of class "mnet" or "tbl_graph".
Other arguments passed to or from other methods.
Number of observations to print across all network components, i.e. nodes, changes, and ties. By default 12.
An object of a {manynet}-consistent class:
adjacency or incidence matrix from {base} R
edgelist data.frame from {base} R or tbl/tbl_df from {tibble}
stocnet stocnet, from the {manynet} package
igraph igraph, from the {igraph} package
network network, from the {network} package
tidygraph tbl_graph, from the {tidygraph} package
The package includes a validation function for stocnet objects, validate_stocnet().
This checks that the object has the correct structure and required components,
and suggests improvements to the structure (e.g. correcting or adding reserved names) where possible.
The required and reserved names for the components of a stocnet object are described below.
There are several reserved names for the elements of the info component of a stocnet object.
'name' should be a single character string with the name of the network.
'modes' should be a character vector of the names of the modes of the nodes in a multimodal network.
'layers' should be a character vector of the names of the layers of the ties in a multiplex or multilayer network.
'directed' should be a logical indicating whether each layer is directed or undirected. If there are multiple layers, this can be a named logical vector with the directedness of each layer, where the names correspond to the layer names. An undirected layer holds one row per dyad in the ties component, whether or not the other layers are directed. Since an 'igraph' or 'network' object is directed or undirected as a whole, coercion reciprocates the undirected layers of a network that has any directed layer, and coercion back collapses them again. This keeps the degree of a node in an undirected layer the same in every class, and makes the round trip lossless.
'focal' should be a character vector indicating which variables are dependent (endogenous). These may be tie layers (dependent networks) and/or nodal variables recorded in the changes component (dependent behaviours), as used when modelling with e.g. 'RSiena'.
'centered' should be a named logical vector indicating, for each covariate (nodal or dyadic), whether it should be centered when modelling. The names correspond to the covariate variable or layer names.
'siena' can hold a list of metadata specific to 'RSiena' 'sienadata' objects
that has no native meaning elsewhere (e.g. the 'allowOnly', 'uponly', and
'downonly' estimation constraints of dependent variables, the composition
change option, node set relations, and the originating 'RSiena' version).
This is populated by as_stocnet() and consumed by as_siena() so that
coercion to and from 'sienadata' objects is lossless.
'doi' can be a character string with the DOI of the network, if it is from a published source.
'date' can be an integer of the year or the date the network represents.
'location' can be a character string with the location of the network.
'source' can be a character string indicating whether the network is observed or synthetic. If it is observed, the 'method' of data collection can be further specified. For example, the source could be 'observed', 'synthetic', 'survey', 'archival', 'digital trace', etc. If it is synthetic, then more details about how the network was generated can be included.
Many of these elements are drawn from the GRAND project's metadata standards for networks, which are designed to be consistent with the FAIR principles for data management.
In addition to these reserved names, the info component can include metadata relating to each layer of the network, such as the names of the types of nodes and ties in each layer, as well as the names of the dependent and independent layers in a multiplex network. These must be named as one of the layer names. There are some reserved names for these elements too:
'sender' should be a character string naming the type of node that sends ties in this layer.
'recipient' should be a character string naming the type of node that receives ties in this layer.
'observation' should be a character string naming how the network was observed: "cross-sectional" for a single observation, "panel" for a few complete re-observations, "event" for a stream of many records, and "egocentric" or "cognitive" for the two designs that ask each respondent about a network of their own. Where the layers were observed differently, this can be a layer-named character vector. A layer named "cross-sectional" in an otherwise longitudinal or dynamic network states something that holds throughout, a constant dyadic covariate, and is carried into every moment the network is scoped to.
'update' should be a character string indicating how each record of a
tie relates to the record before it: "replace", where each states the
tie's value afresh, or "increment", where each adds to it.
Where the layers are updated differently, this can be a layer-named
character vector.
This says nothing about a tie recorded as an interval, in 'begin' and
'end' columns, since such a tie carries its own lifespan.
See the Time section of to_time() for how the two are scoped.
There are several reserved names for the columns of the nodes component of a stocnet object.
'label' should be a character vector of the labels of the nodes in the network.
'mode' should be a character vector of the modes of the nodes in a multimodal network.
'active' should be a logical vector indicating the initial status of nodes in changing networks. Inactive nodes are not in the network, so cannot hold incoming nor outgoing ties.
'na' should be a logical vector indicating which nodes were non-responsive,
despite being in the network.
Non-responsive nodes are in the network, so can hold incoming ties,
but cannot report outgoing ties.
See as_missinglist().
There are several required names for the columns of the changes component of a stocnet object (if one is included).
'time' can be an integer (e.g. for a wave) or date (e.g. POSIXct or mdate) vector of the times at which changes occur.
'node' must be an index (or names) of the node to which the change applies.
'var' must be a string vector naming the variable to which the change applies, such as 'active' for changing networks.
'value' must be the new value that should be applied at that change (or incremented, as appropriate). Note that the value column can be of any class, such as logical for changes to active status, or numeric for changes to a nodal attribute. These values are held internally as a list within the tibble, so that they can be of any class and length, but printed as a tibble with a 'value' column that shows the first value and a type label for the class of the value.
A change states what a variable becomes from that moment on,
so it is carried forward until another change states otherwise.
A node that does not report at one wave and reports again at the next
therefore holds two changes of the 'na' variable, one each way.
Unlike the ties, then, changes are always recorded at a moment and always
carried forward: an interval over which a nodal variable holds is stated
as two changes, one at each end, and there is no 'update' to declare.
as_changelist() takes a time and returns the changes in force at it.
There is one reserved name for a further column.
'layer' should be a character vector naming the layer a change applies to, where it applies to one layer and not to others. A change that names no layer applies to every layer.
There are several required names for the columns of the ties component of a stocnet object (if one is included).
'from' must be an integer vector of the nodes sending each tie
'to' must be an integer vector of the nodes receiving each tie
There are also several reserved names for the columns of the ties component of a stocnet object.
'layer' should be a character vector of the layer of each tie in a multiplex or multilayer network
'weight' should be a numeric vector of the weights of the ties in a weighted network
If the weight vector includes also negative values, then the network is a signed network,
and the sign of the tie can be determined from the weight.
Missing values, NA, in the weight vector indicate that the tie value is missing,
not the tie itself, which is still present in the network.
For individual missing ties beyond those implied by inactive or non-responsive nodes,
please add them to the missings component as an edgelist.
'time' should be a numeric, character, or date vector of the moment at which each tie was recorded.
'begin' and 'end' should instead give the interval over which each tie lasts, where the network records that rather than a moment.
'increment' and 'replace' should give the change each record makes to a
tie's value, where the network records a stream of such changes.
These are renamed to 'weight' on coercion, and what they said is kept in
info$update.
How a network records time in its ties, and what each of these columns
therefore means, is set out in the Time section of to_time().
There are several required names for the columns of the globals component of a stocnet object (if one is included).
'var' must be a string vector naming the global variable
'value' must be the value the variable takes from that moment on. There may be an additional column:
'time' should be a numeric, character, or date vector of the moment at which each global attribute is updated. Globals are carried forward the way changes are: a value holds from the moment it is recorded at until another value states otherwise.
The missings component lists the ties the network could have observed and did not, one row each, where these are not already implied by an inactive or a non-responsive node. It takes the same columns as the ties component:
'from' and 'to' must be integer vectors of the nodes at each end
'layer' and 'time' should name the layer and moment the tie was missing from, where the network records them.
Since most missing tie data is a node that did not report,
this component is usually NULL.
as_missinglist() returns what it holds together with the ties that the
non-responsive nodes imply, which is nearly always the larger part.
When printed, 'stocnet' objects will print to the console any information stored about the names of the network, its modes, or layers. It will also describe key features of the network, such as whether the network is multiplex, weighted, directed, etc.
It will then print tibbles for the nodes, changes, and ties in the network, as appropriate. That is, if there is no nodal data (e.g. it is an unlabelled network without any other nodal attributes), then this will be skipped. Similarly, if no nodal changes are logged, this information will be skipped too.
out <- make_stocnet(info = list(name = "Example Network",
modes = c("Person", "Organization"),
layers = c("Friendship", "Collaboration")),
nodes = data.frame(label = c("A", "B", "C"),
mode = c("Person", "Person", "Organization"),
active = c(TRUE, FALSE, TRUE)),
ties = data.frame(from = c("A", "B"),
to = c("B", "C"),
weight = c(1, 2),
layer = c("Friendship", "Collaboration")),
changes = data.frame(time = c(1, 2),
node = c("A", "B"),
var = c("active", "active"),
value = c(FALSE, TRUE)))