My aim is to make a dynamic network visualization using the ndtv and networkDynamic packages in R. I constuct the networkDynamic object using edge spells and vertex spells as described in section 7.3 here. The data frames also contain temporal edge and vertex attributes (TEAs).
library(networkDynamic)
edges <- read.csv("https://raw.githubusercontent.com/SoranHD/Rstuff/main/edges.csv")
edges$X<- NULL
nodes <- read.csv("https://raw.githubusercontent.com/SoranHD/Rstuff/main/nodes.csv")
nodes$X <- NULL
net <- networkDynamic(edge.spells = edges, vertex.spells = nodes, create.TEAs = TRUE)
I want all edges and vertices to remain active throughout, but to vary based on their TEAs. I want "weight" to determine the width of the edges and "size" to determine the size of the nodes.
However, when I render the animation, it is clear that neither map onto their object properly.
compute.animation(net,
slice.par = list(start = 1, end = 8, interval = 1, aggregate.dur = 1, rule = "any"))
render.d3movie(net, usearrows = T,
edge.lwd = (net %e% "weight.active")/100,
vertex.cex = (net %v% "size.active"),
output.mode = "HTML",
launchBrowser = FALSE)
For some reason, only the edges directed from "node 1" have different widths, and even these do not appear as expected. The node sizes are also wrong, and remain static throughout.
Clearly I am doing something wrong. I have tried to construct the data set in several different ways, including as a list of network objects representing each wave, but I keep running into the same issue. Any help would be greatly appreciated.
Edit
I have had the same issue when constructing the dynamicNetwork object using the network.list option, and it persists when running the same code on the newcomb data, as suggested in the comments. The documentation linked above mentions that the data set contains the edge attribute "weights" it doesn't seem to, so I use the "rank" attribute from the newcom.rank data set instead.
library(networkDynamic)
library(networkDynamic)
data(newcomb)
newcombDyn <- networkDynamic(network.list = newcomb.rank, create.TEAs = TRUE)
When comparing the "rank" attribute in the first network in the newcomb.rank network list with the "rank.active" attribute at time 1, we see that they do not correspond. Moreover, the "rank.active" attribute is much larger than the number of active edges.
get.edge.attribute(newcomb.rank[[1]], "rank")
get.edge.attribute.active(newcombDyn, "rank.active", at = 1)
Moreover, "rank.active" looks the same at t = 2 as t = 1.
get.edge.attribute.active(newcombDyn, "rank.active", at = 2)
Finally, when rendering the animation with edge width based on the "rank.active" attribute, the edge width is not dynamic but remains static throughout.
compute.animation(newcombDyn, slice.par = list(start = 1, end = 14, interval = 1, aggregate.dur = 1, rule = "any"))
render.d3movie(newcombDyn, usearrows = T, edge.lwd = (newcombDyn %e% "rank.active")/2, output.mode = "HTML", launchBrowser = TRUE)
I think it is just a matter of changing from
rank.active
torank
, but the results may not be what you desire as all relationships through time are present as there are no ties allowed. But,Looking at the difference between
and
we see the values are changing so should map as expected (perhaps)
makes a movie of sorts. Alternatively,using your data from above (now that it has been certified as safe by the author), changing your
to
And it seems to be working(ish), for a remarkably tricky data structure. HTH