statnet / ndtv

ndtv: Network Dynamic Temporal Visualizations in R

Home Page:https://cran.r-project.org/web/packages/ndtv/index.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

render.d3movie errors on inactive weight attribute

nextensible opened this issue · comments

Please find below a reproducible example:

if (!require("pacman")) install.packages("pacman"); library("pacman")
pacman::p_load(network, networkDynamic, ndtv, lubridate)

stTransac <- "
'person', 'document', 'weight', 'instantId'
'A',      'a1',       '10',     '100'
'B',      'a1',       '20',     '200'
'C',      'a1',       '30',     '300'
"
dfTransac <- read.csv(text = stTransac, sep = "," , quote = '\'' , strip.white = TRUE, stringsAsFactors = FALSE)

net <- network.initialize(0, directed = TRUE, bipartite = 3)

add.vertices.networkDynamic(net, 3, vertex.pid = c("A","B","C"))
add.vertices.networkDynamic(net, 1, vertex.pid = "a1")

net %v% "vertex.names" <- c(c("A","B","C"), "a1")
set.network.attribute(net,'vertex.pid','vertex.names')
set.network.attribute(net,'edge.pid','edge.names')

add.edges.networkDynamic(net,
                         tail = get.vertex.id(net, c("A","B","C")),
                         head = get.vertex.id(net, "a1"),
                         edge.pid = paste0(c("A","B","C"), "->a1"))

activate.edges(net,
               e = get.edge.id(net, paste0(dfTransac[["person"]], "->a1")),
               at = dfTransac$instantId)

activate.edge.attribute(net,
                        prefix = "weight",
                        value = dfTransac$weight,
                        e = get.edge.id(net, paste0(dfTransac[["person"]], "->a1")),
                        at = dfTransac$instantId)

reconcile.vertex.activity(net = net, mode = "encompass.edges", edge.active.default = FALSE)

compute.animation(net, slice.par = list(start = 100, end = 101, interval = 1, aggregate.dur = 1, rule = "any"))
render.d3movie(net, edge.lwd = 'weight')

Code above gives the error :
" Attribute 'weight' had illegal missing values for edge.lwd or was not present in plot.network.default."
because there are no values defined for the edges at many of the time points that it tries to plot. For example

get.edge.attribute.active(net,'weight',at=100)
[1] 10 NA NA

As the tutorials demonstrate, it is often a good idea to activate a default value for all elements for the entire time period before activating the specific values for the defined spells. In this case, you could first call

activate.edge.attribute(net,
                        prefix = "weight",
                        value =0,
                        onset = -Inf,
                        terminus = Inf)

Hi, to me, it seems a bit odd that one has to initialize the attribute with "made up" values. AFAIU the result of your get.edge.attribute.active(net,'weight',at=101) call means that 1 out of 3 edges has a value at time 100. But, the code above does not fail at time 100, but only at times where all are NA, e.g. at 101.

Maybe this can be regarded as inconvenience, however: render.animation does not fail with the code above, render.d3movie does. IMHO, these two should behave in sync somehow?

you are right. Here is a minimal test example

test<-network.initialize(2)
add.edges.active(test,1,2,onset=0,terminus=2)
activate.edge.attribute(test,'weight',1, at=1)
render.d3movie(test,edge.lwd='weight')
Error in plotArgs.network(x = slice, argName = arg, argValue = dataVals) : 
  Attribute 'weight' had illegal missing values for edge.lwd or was not present in plot.network.default.

need to prevent it from looking up attributes when there are no edges active. Activating a default attribute would only work for the case where the edge is active but the attribute is not.