I want to construct a networkDynamic
object in R from transaction data where each line represents a contribution by a person to a document. Multiple contributions should be represented as an increase in edge weight instead of creating multiple edges.
The following code snippets should be reproducible in RStudio easily to see the problem.
if (!require("pacman")) install.packages("pacman"); library("pacman")
pacman::p_load(network, networkDynamic, ndtv, lubridate)
stTransac <- "
'person', 'document', 'weight', 'instantId'
'A', 'a1', '3', '1'
'A', 'a1', '15', '2'
'A', 'a1', '100', '3'
'B', 'a1', '20', '10'
'C', 'a1', '30', '12'
"
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)
Up to now, everything works as expected (if you skip the activate.edge.attribute
block below and jump directly to the last block, you will see in the animation that edges are activated at times 1,2,3,10,12.) However, when using the activate.edge.attribute
function intuitively in the same way as the activate.edges
function, for the first edge the weight attribute is only initialized at 3
with a value of 100
. The earlier two weight values are dropped.
activate.edge.attribute(net,
prefix = "weight",
value = dfTransac$weight,
e = get.edge.id(net, paste0(dfTransac[["person"]], "->a1")),
at = dfTransac$instantId)
I could iterate over the transaction data frame, but I suppose this will not scale too well:
by(dfTransac, 1:nrow(dfTransac), function(row) {
net <<- activate.edge.attribute(net,
prefix = "weight",
value = row[["weight"]],
e = get.edge.id(net, paste0(row[["person"]], "->", row[["document"]])),
at = row[["instantId"]])
})
This last block renders the animation...
reconcile.vertex.activity(net = net, mode = "encompass.edges", edge.active.default = FALSE)
compute.animation(net, slice.par = list(start = 1, end = 13, interval = 1, aggregate.dur = 1, rule = "any"))
render.animation(net)
ani.replay()
What is the correct and efficient way to set the weight attribute at
multiple different timestamps?