Search code examples
ranimationsnastatnet

Formatting onset terminus data for dynamic network visualisation


I am looking at how government agencies change over time. The plan is to use the ndtv package to visualise changes. However, I am running into problems and have no idea what I am doing wrong! I suspect my data is not formatted correctly.

I have an nodelist that lists vertex ids, agency name, node onset and node terminus:

nodelist <- read.csv("https://github.com/aterhorst/data/raw/master/edgelist.csv", header=T, stringsAsFactors = F)

and an edgelist showing onset, terminus of edges:

edgelist <- read.csv("https://github.com/aterhorst/data/raw/master/edgelist.csv", header=T, stringsAsFactors = F)

I can create a network object pretty easily:

library(tidyverse)
library(sna)
nw <- network(edgelist %>% select(head, tail),
              vertex_attr = nodelist %>% select(vertex.id, agency),
              vertex.attrnames = c("vertex.id", "agency"),
              directed = F)
print(nw)
plot(nw)

Now I want to make a dynamic network object:

library(tsna)
library(ndtv)
dn <- networkDynamic(nw, 
                     edge.spells = edgelist,
                     vertex.spells = nodelist)

Then the wheels fall off:

Error in networkDynamic(nw, edge.spells = edgelist, vertex.spells = nodelist) : 
  vertex.spells requires the vertex.id column to be numeric

I tried changing onset, terminus from integer to numeric - makes no difference. I have tried different ways to create the dynamic network object e.g.

dn <- networkDynamic(edge.spells = edgelist)

This produces this error:

Initializing base.net of size 2020 imputed from maximum vertex id in edge records
Error in activate.edges(base.net, onset = edge.data[, 1], terminus = edge.data[,  : 
  Onset times must precede terminus times in activate.edges.

and:

dn <- networkDynamic(edge.spells = edgelist, vertex.spells = nodelist)

gives me this error:

Error in networkDynamic(edge.spells = edgelist, vertex.spells = nodelist) : 
  vertex.spells requires the vertex.id column to be numeric 

I played around with the order of the edge.spell and this yielded a positive result:

 dn <- networkDynamic(net, 
                      edge.spells = edgelist %>% select(onset, terminus, tail, head))

Edge activity in base.net was ignored
Created net.obs.period to describe network
 Network observation period info:
  Number of observation spells: 1 
  Maximal time range observed: 2014 until 2020 
  Temporal mode: continuous 
  Time unit: unknown 
  Suggested time increment: NA 

All good. Now when I add vertex.spell I get this error:

dynamicNet <- networkDynamic(net, 
                         edge.spells = edgelist %>% select(onset, terminus, tail, head), 
                         vertex.spells = nodelist %>% select(onset, terminus, vertex.id) %>% 
                         mutate(vertex.id = as.numeric(vertex.id)))

Error in networkDynamic(net, edge.spells = edgelist %>% select(onset,  : 
  vertex.spells requires the vertex.id column to be numeric

Which is bizarre as I have explicitly stated vertex.id to be numeric! Obviously, I am stuffing up with formatting somewhere but its not obvious where. Any help would be appreciated.


Solution

  • In this case, I don't think you need to first create the static network (tho that should work). The main problem seems to just be the column ordering in the lists. The help file ?networkDynamic indicates that it requires a specific order for the edge.spells and vertex.spells:

    edge.spells "... Assumed to be [onset,terminus,tail vertex.id, head vertex.id]. ..."

    vertex.spells "...Assumed to be [onset,terminus,vertex.id]"

    Your data looks like:

    > head(nodelist)
      vertex.id                                  agency onset terminus
    1         1                             AAF Company  2014     2020
    2         2              Aboriginal Hostels Limited  2014     2020
    3         3         Administrative Appeals Tribunal  2014     2020
    4         4 Aged Care Quality and Safety Commission  2014     2020
    5         5                   Airservices Australia  2014     2020
    6         6  Albury-Wodonga Development Corporation  2014     2020
    > head(edgelist)
      head tail onset terminus
    1   10    3  2014     2020
    2   10   11  2014     2020
    3   10   12  2014     2020
    4   10   18  2014     2020
    5   10   22  2014     2020
    6   10   23  2014     2020
    

    So if the cols of your data are re-orderd..

    nd <-networkDynamic(edge.spells = edgelist[,c(3,4,2,1)],
      vertex.spells=nodelist[,c(3,4,1)])
    
    Initializing base.net of size 217 imputed from maximum vertex id in edge records
    Created net.obs.period to describe network
     Network observation period info:
      Number of observation spells: 1 
      Maximal time range observed: 2014 until 2020 
      Temporal mode: continuous 
      Time unit: unknown 
      Suggested time increment: NA 
    

    This creates network object and dynamics. Since it looks like your nodelist has only one row per vertex, labels can be brought in with

    network.vertex.names(nd)<-nodelist$agency