我想在事务数据中在R中构造一个networkDynamic
对象,其中每一行代表一个人对文档的贡献。多个贡献应表示为边缘权重的增加,而不是创建多个边缘。
以下代码片段应该可以在RStudio中轻松重现以查看问题。
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)
到目前为止,一切都按预期工作(如果您跳过下面的activate.edge.attribute
块并直接跳到最后一个块,您将在动画中看到边缘在1,2,3,10时被激活但是,当以与activate.edge.attribute
函数相同的方式直观地使用activate.edges
函数时,对于第一个边,权重属性仅在3
初始化,值为{ {1}}。之前的两个权重值被删除。
100
我可以遍历事务数据框,但我想这不会扩展得太好:
activate.edge.attribute(net,
prefix = "weight",
value = dfTransac$weight,
e = get.edge.id(net, paste0(dfTransac[["person"]], "->a1")),
at = dfTransac$instantId)
最后一个块渲染动画......
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"]])
})
设置权重属性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()
多个不同时间戳的正确有效方法是什么?
答案 0 :(得分:3)
部分由于效率原因,属性激活码不能激活每个顶点/边缘的多个法术。正如文档所说:
...可以使用一个函数调用来激活多个 多个顶点上的值,每个顶点上的活动时间不同 顶点,但不能在多个位置激活多个值 一次调用的单个顶点上的时间。
我建议使用以下语法创建具有networkDynamic()
构造函数的网络,该函数可以同时导入属性。
# re-arrange the data.frame column order to an edge.spell format,
# duplicating the time to use for onset and terminus
input<-dfTransac[,c(4,4,1,2,3)]
# convert the ids to numeric
ids<-unique(c(dfTransac$person,dfTransac$document))
input[,3]<-match(input[,3],ids)
input[,4]<-match(input[,4],ids)
input
instantId instantId.1 person document weight
1 1 1 1 4 3
2 2 2 1 4 15
3 3 3 1 4 100
4 10 10 2 4 20
5 12 12 3 4 30
# initialize a base network with the appropriate characteristics
net<-network.initialize(length(ids),bipartite=3)
# copy in the vertex names
network.vertex.names(net)<-ids
# use the networkDynamic constructor, telling it to create dynamic attributes
netDyn <- networkDynamic(net,edge.spells = input,
+ create.TEAs = TRUE,edge.TEA.names = 'weight')
Activated TEA edge attributes: weightCreated net.obs.period to describe network
Network observation period info:
Number of observation spells: 1
Maximal time range observed: 1 until 12
Temporal mode: continuous
Time unit: unknown
Suggested time increment: NA
# print out the attributes structure for edge 1 to double check
get.edge.attribute(netDyn,'weight.active',unlist=FALSE)[[1]]
[[1]]
[[1]][[1]]
[1] 3
[[1]][[2]]
[1] 15
[[1]][[3]]
[1] 100
[[2]]
[,1] [,2]
[1,] 1 1
[2,] 2 2
[3,] 3 3
因此,我们可以看到第一个边缘现在具有“重量”的预期值3。请注意networkDynamic()
必须执行类似的循环以适当地附加动态属性,但至少它们都在幕后。