My goal is to make a dynamic visualization using three packages in R: ndtv
, network
, and networkDynamic
packages.
I have created a dataset with the information ordered according to this example dataset in a workshop for Network Dynamic Temporal Visualizations (on page 7.)
According to page 49 of the network dynamic manual, one way to upload a dataset and convert it into a networkDynamic object is as follows:
rawEdges<-read.table(paste(path.package("networkDynamic"),"/enron_timebased3.tsv", sep=''),header=TRUE)
However, when I attempt to run
animation.render(rawEdges)
R throws up an error message:
first argument must be a network object.
To fix this, I create a network object:
net<-network(rawEdges)
and try:
animation.render(net, rawEdges)
New error message:
Error in '$<-.data.frame'('tmp', "initial.coords", value = c(0, 0, 0, : replacement has 34 rows, data has 26)
Does anyone know how to fix this?
Think there are couple of issues with your example:
- you will need to create a
networkDynamic
object, not a network
object
- you will have to do some time format conversion for the
table to parse correctly, as well as create numeric ids
- the command is
render.animation()
not animation.render()
First, lets set up some example data we can load. Only need the first 4 columns of your example data:
# text version of the example data
text<-"onset terminus tail head
9/6/2000 9/7/2000 mmmarcantel@equiva.com matthew.lenhart@enron.com
9/6/2000 9/7/2000 stephen.harrington@enron.com matthew.lenhart@enron.com
9/6/2000 9/7/2000 shelliott@dttus.com matthew.lenhart@enron.com
9/6/2000 9/7/2000 jilallen@dttus.com matthew.lenhart@enron.com
5/7/2001 5/8/2001 ken.shulklapper@enron.com matthew.lenhart@enron.com
9/6/2000 9/7/2000 eric.bass@enron.com matthew.lenhart@enron.com
9/6/2000 9/7/2000 shelliott@dttus.com matthew.lenhart@enron.com
9/6/2000 9/7/2000 bryan.hull@enron.com matthew.lenhart@enron.com
9/6/2000 9/7/2000 jilallen@dttus.com matthew.lenhart@enron.com
9/6/2000 9/7/2000 shelliott@dttus.com matthew.lenhart@enron.com
9/6/2000 9/7/2000 brook@pdq.net matthew.lenhart@enron.com
9/5/2000 9/6/2000 tlenhart@corealty.com matthew.lenhart@enron.com
9/5/2000 9/6/2000 patrick.ryder@enron.com matthew.lenhart@enron.com
9/5/2000 9/6/2000 eric.bass@enron.com matthew.lenhart@enron.com
9/5/2000 9/6/2000 mmmarcantel@equiva.com matthew.lenhart@enron.com
5/7/2001 5/8/2001 tlenhart@corealty.com matthew.lenhart@enron.com
9/5/2000 9/6/2000 tlenhart@corealty.com matthew.lenhart@enron.com
9/5/2000 9/6/2000 tlenhart@corealty.com matthew.lenhart@enron.com
9/5/2000 9/6/2000 paul.lucci@enron.com matthew.lenhart@enron.com
9/5/2000 9/6/2000 jilallen@dttus.com matthew.lenhart@enron.com
9/5/2000 9/6/2000 tlenhart@corealty.com matthew.lenhart@enron.com
9/5/2000 9/6/2000 paul.lucci@enron.com matthew.lenhart@enron.com
9/5/2000 9/6/2000 bryan.hull@enron.com matthew.lenhart@enron.com
9/5/2000 9/6/2000 shelliott@dttus.com matthew.lenhart@enron.com
8/31/2000 9/1/2000 bryan.hull@enron.com matthew.lenhart@enron.com
8/31/2000 9/1/2000 tlenhart@corealty.com matthew.lenhart@enron.com"
# write out the example data to an example input file
inputFile<-tempfile()
cat(text,file=inputFile)
Now, load the network dynamic library
library(networkDynamic)
# read in tab-delimited example input file
timeData<-read.csv(inputFile,sep = "\t",stringsAsFactors = FALSE)
# check that it was loaded correctly
timeData
# convert the date formats into a numeric time (milliseconds)
timeData$onset<-as.numeric(as.POSIXct(timeData$onset,format='%m/%d/%Y'))
timeData$terminus<-as.numeric(as.POSIXct(timeData$terminus,format='%m/%d/%Y'))
# create a table of email address to map to numeric ids
emails<-unique(c(timeData$head,timeData$tail))
#covert ids
timeData$head<- match(timeData$head,emails)
timeData$tail<- match(timeData$tail,emails)
# convert to networkDynamic object
enronDyn<-networkDynamic(edge.spells=timeData)
# copy in the network names
network.vertex.names(enronDyn)<-emails
# load ndtv library
library(ndtv)
# compute the animation at 30-day interval
compute.animation(enronDyn,slice.par=list(start=967705200,end=989305200,interval=2592000,aggregate.dur=2592000,rule='latest'))
# render out the animation
render.animation(enronDyn)
ani.replay()
However, your input data looks a little funny to me. I'm pretty sure the original Enron email data has more precise timestamps than the day the email was sent, and it shouldn't take an entire day to send each email? If you can find a version of the data with a more precise timestamp, you will have much more flexibility with how you render and analyse the dynamic events. For example, you will know the order which the emails were sent each day, etc.