Centrality computed from the time-respecting paths that paths() finds,
taken across the whole observation period (or the start-to-end
window). A path may only continue along a tie that is available after it
arrives, so these values cannot be inflated by ties that occur in the
wrong order, as a flattened network is. The result is one value per
vertex, not a series: for centrality that changes from window to window,
use centrality_series(); for the number of vertices a vertex can reach,
use reachability().
Usage
path_centrality(
dn,
measure = "closeness",
sessions = c("bounded", "collapse", "separate"),
start = NULL,
end = NULL,
traversal_time = 0,
plot = FALSE
)Arguments
- dn
A temporal network from
dynet().- measure
One or both of
"closeness"(the default) and"betweenness". Any other name raisesdynet_unknown_measure.- sessions
How to treat sessions:
"bounded"(the default) keeps paths inside a session,"collapse"ignores sessions,"separate"reports each session on its own rows."separate"on a network built without a session column raisesdynet_no_sessions.- start, end
Inclusive path-traversal bounds. Default to the observed range. A network built from dates may be addressed with dates.
- traversal_time
Nonnegative duration charged for every hop, in the network's time unit;
0by default. A calendar network also accepts a scalardifftime.- plot
Whether to draw the result as well as return it. Drawing is a side effect in the manner of
graphics::hist(): the verb still returns its tidy table, invisibly when it has drawn.
Value
A node-level dynet_metric: a tidy data frame with one row per
vertex and measure, columns node, measure and value, preceded by
session under sessions = "separate". There is no time column. A
single-measure result stores its mathematical choices as direct
attributes; a two-measure result stores named records under
measure_metadata.
Details
Betweenness is the raw dependency sum over reachable forward
ordered pairs. For each source-target pair, its unit dependency is divided
equally over every canonical shortest-foremost journey, and an internal
vertex receives the fraction of those journeys that contain it. Sources and
targets receive no endpoint credit. This ordered-pair convention also
applies to undirected contacts because temporal reach is generally
asymmetric. The result is not normalised; its fixed range is
[0, (n - 1) * (n - 2)].
Closeness is inverse mean forward latency over reachable vertices:
if \(R_s\) is the set of reachable vertices other than source \(s\),
$$C(s) = |R_s| / \sum_{z \in R_s} (a_z - o_s),$$
where \(a_z\) is the foremost arrival time and \(o_s\) is the source's
resolved origin: the traversal window's lower bound, or – when vertex
activity was declared – the source's first presence inside that window.
Every reachable endpoint is included once, regardless
of how many optimal paths reach it. A source with no reachable nonself
endpoints has value zero. If all reachable endpoints have zero latency, the
value is Inf; zero-latency endpoints remain in the numerator when mixed
with positive latencies. The measure therefore has inverse-time units, is
invariant to translating the time axis, and scales inversely when time is
rescaled.
Both measures use paths() traversal semantics: nondecreasing
times, unlimited waiting, half-open interval spells, and a separate exact
timestamp rule for point events. Positive traversal_time requires an
interval traversal to finish within continuous pair activity; a point event
triggers at its timestamp and reaches its endpoint after that duration.
start and end bound every measure. In separate-session output, a
session outside a one-sided bound contributes zero rows.
Declared vertex activity gates the exact source anchor and every hop. Waiting after a valid anchor may cross inactivity; interval traversal requires both endpoints through completion, while a point trigger requires the receiver again after any traversal delay. Fixed node rows and full-network denominators are retained.
Conditions
Errors: dynet_unknown_measure (a measure other than "closeness" or
"betweenness"), dynet_no_sessions (sessions = "separate" without a
session column), dynet_outside_observation (the requested range misses
observed support; it also carries dynet_bad_input), and
dynet_bad_input for every other broken contract – dn not a dynet, a
malformed measure, an out-of-range start, end or traversal_time.
References
Pan, R. K., & Saramaki, J. (2011). Path lengths, correlations, and centrality in temporal networks. Physical Review E, 84(1), 016105.
Tang, J., Musolesi, M., Mascolo, C., Latora, V., & Nicosia, V. (2010). Analysing information flows and key mediators through temporal centrality metrics. Proceedings of SNS '10.
Buss, S., Molter, H., Niedermeier, R., & Rymar, M. (2024). Algorithmic aspects of temporal betweenness. Network Science, 12(2), 160-188.
Nicosia, V., Tang, J., Mascolo, C., Musolesi, M., Russo, G., & Latora, V. (2013). Graph metrics for temporal networks. In Temporal Networks (pp. 15-40). Springer.
Examples
# Every ordered pair is searched, so the cost grows steeply with the
# vertex count; a subgraph keeps the example quick.
dn <- dynet(school_contacts)
few <- induce_subgraph(dn, nodes = c("Ana", "Ben", "Cara", "Dan", "Eve",
"Finn", "Gita", "Hugo"))
path_centrality(few)
#> # Closeness (node-level)
#> # 8 vertices | time in step
#> # computed on time-respecting paths across the whole window
#> node measure value
#> Ana closeness 0.09987159
#> Ben closeness 0.13180192
#> Cara closeness 0.07404273
#> Dan closeness 0.14198783
#> Eve closeness 0.13908206
#> Finn closeness 0.07579859
#> Gita closeness 0.10995916
#> Hugo closeness 0.12297962
path_centrality(few, measure = c("closeness", "betweenness"),
start = 0, end = 10)
#> # Temporal centrality (node-level)
#> # 8 vertices | time in step
#> # measures: closeness, betweenness
#> # computed on time-respecting paths within the requested traversal window
#> node measure value
#> Ana closeness 0.1380262
#> Ben closeness 0.1731902
#> Cara closeness 0.1270648
#> Dan closeness 0.1794258
#> Eve closeness 0.1740644
#> Finn closeness 0.1476015
#> Gita closeness 0.1773836
#> Hugo closeness 0.1461276
#> Ana betweenness 8.0000000
#> Ben betweenness 0.0000000
#> Cara betweenness 7.0000000
#> Dan betweenness 0.0000000
#> # 4 more rows. summary() aggregates them; plot() draws them.