There are a lot of cases in this world that can be represented as a graph/network. But sometimes that network is not static, which means it changes over time. This kind of network is called ‘dynamic network’ (or ‘temporal network’ sometimes). Since it is usually observed in social network, the analysis through dynamic network is called “(Temporal) Social Network Analysis” sometimes . Some examples of real-life dynamic network are: friendship network, business connection network, the network of biological interaction between organisms, Traffic/Access network,etc. The time intervention here does not allow us to use the algorithm, analysis, and tools the same as the ordinary network-analysis one.

I will introduce some important package in R specifically for Dynamic Network Analysis and Visualization. There are two important packages here: tsna (Temporal Social Network Analysis) and ndtv (Network Dynamic Temporal Visualization). The tsna package consist functionality to analyse temporal network, it is the extension of sna package. The ndtv package was built to render temporal network data as movies, interactive animations, or any other representations of changing relational structures and attributes. In order to work with the network animations in ndtv, we better understand Statnet’s dynamic network format (Statnet is a family packages, including network, sna, ergm, stergm, and others).

Here I use ‘short.stergm.sim’ dataset from ndtv package. This dataset is a simulation data based on a network of business connections among Renaissance Florentine families.

library(ndtv)
## Warning: package 'ndtv' was built under R version 3.6.1
## Loading required package: network
## Warning: package 'network' was built under R version 3.6.1
## network: Classes for Relational Data
## Version 1.15 created on 2019-04-01.
## copyright (c) 2005, Carter T. Butts, University of California-Irvine
##                     Mark S. Handcock, University of California -- Los Angeles
##                     David R. Hunter, Penn State University
##                     Martina Morris, University of Washington
##                     Skye Bender-deMoll, University of Washington
##  For citation information, type citation("network").
##  Type help("network-package") to get started.
## Loading required package: networkDynamic
## Warning: package 'networkDynamic' was built under R version 3.6.1
## 
## networkDynamic: version 0.10.0, created on 2019-04-04
## Copyright (c) 2019, Carter T. Butts, University of California -- Irvine
##                     Ayn Leslie-Cook, University of Washington
##                     Pavel N. Krivitsky, University of Wollongong
##                     Skye Bender-deMoll, University of Washington
##                     with contributions from
##                     Zack Almquist, University of California -- Irvine
##                     David R. Hunter, Penn State University
##                     Li Wang
##                     Kirk Li, University of Washington
##                     Steven M. Goodreau, University of Washington
##                     Jeffrey Horner
##                     Martina Morris, University of Washington
## Based on "statnet" project software (statnet.org).
## For license and citation information see statnet.org/attribution
## or type citation("networkDynamic").
## Loading required package: animation
## Loading required package: sna
## Warning: package 'sna' was built under R version 3.6.1
## Loading required package: statnet.common
## Warning: package 'statnet.common' was built under R version 3.6.1
## 
## Attaching package: 'statnet.common'
## The following object is masked from 'package:base':
## 
##     order
## sna: Tools for Social Network Analysis
## Version 2.4 created on 2016-07-23.
## copyright (c) 2005, Carter T. Butts, University of California-Irvine
##  For citation information, type citation("sna").
##  Type help(package="sna") to get started.
## Registered S3 method overwritten by 'openssl':
##   method      from
##   print.bytes Rcpp
## 
## ndtv: version 0.13.0, created on 2019-05-21
## Copyright (c) 2019, Skye Bender-deMoll, University of Washington
##                     with contributions from
##                     Martina Morris, University of Washington
## Based on "statnet" project software (statnet.org).
## For license and citation information see statnet.org/attribution
## or type citation("ndtv").
data(short.stergm.sim)
head(as.data.frame(short.stergm.sim))
##   onset terminus tail head onset.censored terminus.censored duration
## 1     0        1    3    5          FALSE             FALSE        1
## 2    10       20    3    5          FALSE             FALSE       10
## 3     0       25    3    6          FALSE             FALSE       25
## 4     0        1    3    9          FALSE             FALSE        1
## 5     2       25    3    9          FALSE             FALSE       23
## 6     0        4    3   11          FALSE             FALSE        4
##   edge.id
## 1       1
## 2       1
## 3       2
## 4       3
## 5       3
## 6       4

As you can see, the dataset contain some important variables as follow:
- onset : The beginning time point of the relation,
- terminus : The end time point of the relation,
- tail : the origin vertex,
- head : the terminal vertex,
- duration : the duration of the relation.

First, we want to plot the network (ignoring the time point) as follows.

plot(short.stergm.sim)

We can also plot the network at some time-point. In this case we need network.extract() function.

plot(network.extract(short.stergm.sim,at=5))

We can also plot the network in some duration of time. Here there are two variation of plotting:
(1.) plot any edge/relation that happen at some time-point in given duration of time, or
(2.) plot the edge/relation that happen at the entire given duration of time. Let we see what’s the difference.

# for (1.) 
plot(network.extract(short.stergm.sim,onset=1,terminus=5,rule = "any"))

# for (2.)
plot(network.extract(short.stergm.sim,onset=1,terminus=5,rule = "all"))

Lastly, we can also render a movie about our network to see how it changes over time.

# Change the output.mode to JSON or HTML to see the difference
render.d3movie(short.stergm.sim,displaylabels=TRUE,output.mode = "htmlWidget") 
## No slice.par found, using
## slice parameters:
##   start:0
##   end:25
##   interval:1
##   aggregate.dur:1
##   rule:latest
## Calculating layout for network slice from time  0 to 1
## Calculating layout for network slice from time  1 to 2
## Calculating layout for network slice from time  2 to 3
## Calculating layout for network slice from time  3 to 4
## Calculating layout for network slice from time  4 to 5
## Calculating layout for network slice from time  5 to 6
## Calculating layout for network slice from time  6 to 7
## Calculating layout for network slice from time  7 to 8
## Calculating layout for network slice from time  8 to 9
## Calculating layout for network slice from time  9 to 10
## Calculating layout for network slice from time  10 to 11
## Calculating layout for network slice from time  11 to 12
## Calculating layout for network slice from time  12 to 13
## Calculating layout for network slice from time  13 to 14
## Calculating layout for network slice from time  14 to 15
## Calculating layout for network slice from time  15 to 16
## Calculating layout for network slice from time  16 to 17
## Calculating layout for network slice from time  17 to 18
## Calculating layout for network slice from time  18 to 19
## Calculating layout for network slice from time  19 to 20
## Calculating layout for network slice from time  20 to 21
## Calculating layout for network slice from time  21 to 22
## Calculating layout for network slice from time  22 to 23
## Calculating layout for network slice from time  23 to 24
## Calculating layout for network slice from time  24 to 25
## Calculating layout for network slice from time  25 to 26
## caching 10 properties for slice 0
## caching 10 properties for slice 1
## caching 10 properties for slice 2
## caching 10 properties for slice 3
## caching 10 properties for slice 4
## caching 10 properties for slice 5
## caching 10 properties for slice 6
## caching 10 properties for slice 7
## caching 10 properties for slice 8
## caching 10 properties for slice 9
## caching 10 properties for slice 10
## caching 10 properties for slice 11
## caching 10 properties for slice 12
## caching 10 properties for slice 13
## caching 10 properties for slice 14
## caching 10 properties for slice 15
## caching 10 properties for slice 16
## caching 10 properties for slice 17
## caching 10 properties for slice 18
## caching 10 properties for slice 19
## caching 10 properties for slice 20
## caching 10 properties for slice 21
## caching 10 properties for slice 22
## caching 10 properties for slice 23
## caching 10 properties for slice 24
## caching 10 properties for slice 25
## Loading required namespace: htmlwidgets
## loading ndtv-d3 animation widget...

That’s all the brief introduction of the ndtv package. Now we will explore some of supporting algorithm from tsna package.

library(tsna)
## Warning: package 'tsna' was built under R version 3.6.1
  1. Plot the edge formation over time
plot(tEdgeFormation(short.stergm.sim, time.interval = 1))

Here we can observe that there is a high spike in edge formation at the time-point 13, this implies that the business connections are raised here.

  1. Plot the network’s centrality over time.
dynamicBetweenness <- tSnaStats(
  short.stergm.sim,
  snafun = "centralization",
  start = 1,
  end = 25,
  time.interval = 1,
  aggregate.dur = 0, # The duration that you think 'seasonality' exist.
  FUN = "betweenness"
)
plot(dynamicBetweenness)

Since the centrality measurement here is using ‘betweeness’, we can say that around time-point 3 and around time-point 14 there is a big network component with some family having important role in mantaining connectivity between other family.

The last property that we want to observe are ‘Temporal reachable set’ and ‘Temporal path’.

  1. Forward/backward ‘Temporal reachable’ set and ‘Temporal path’

Sometimes, we also want to know how many vertices can be “reached” by one vertex or how many vertices can “reach” that vertex in the entire period of time. tReach function will give us information about that. The term ‘reach’ here maybe a bit confusing, it will be clearer to understand in the ‘temporal path’ section. There is two variation about direction parameter here:

plot(tReach(short.stergm.sim,direction="bkwd"))

plot(tReach(short.stergm.sim,direction = "fwd"))

In order to see the phenomenon clearly, let we use tPath function to visualize all feasible (forward/backward) temporal path that are started/ended at a desired vertex. Here I visualize the feasible forward temporal path that start from “Ridolfi” (vertex id=13). From the visualization below, we can observe that “Ridolfi” and “Tournabouni” are connected by ‘temporal path’. The temporal path here can be illustrated as follows.

Suppose that Ridolfi family want to send some important business contract to Tornabuoni family. Ridolfi family need to send it between time-point 1 to 25 and since they are not directly connected, Ridolfi family need to send it via one of their business connection and pass it to other business connected family until it arrives at Tournabouni family. The problem is: Can this method be done? The answer is “YES”. Observe that at time-point of 13, Ridolfi is connected to Barbadori and at the exact time, Barbadori is connected to Lamberteschi. Lamberteschi family need to keep the contract with them until the time-point of 21 and pass it to Tournabouni family. Yes, this route is called “Temporal path”. Here we can also observe that Ridolfi family cannot send a contract to Albizzi family using the same method, since there is no temporal path from Ridolfi to Albizzi.

set.seed(100)
RidolfiFwdPath <- tPath(
  short.stergm.sim,
  v = 13,
  direction = "fwd"
)
plotPaths(
  short.stergm.sim,
  RidolfiFwdPath,
  displaylabels = T,
  vertex.col = "white"
)

Reference:
- https://kateto.net/network-visualization
- https://programminghistorian.org/en/lessons/temporal-network-analysis-with-r#fnref:2