使用networkDynamic和/或ndtv控制动态顶点属性

时间:2019-05-29 02:21:48

标签: r sna temporal statnet

我正在研究政府机构如何随着时间而变化。计划是使用ndtv软件包可视化更改。我有一个节点列表,其中列出了顶点ID,代理名称,节点起点和节点终点:

nodelist <- read.csv("https://github.com/aterhorst/data/raw/master/edgelist.csv", header=T, stringsAsFactors = F)

和显示边缘起点的边缘列表:

edgelist <- read.csv("https://github.com/aterhorst/data/raw/master/edgelist.csv", header=T, stringsAsFactors = F)

我可以很容易地创建一个网络对象:

nw <- network(edgelist,
              vertex.attr = nodelist[,c(1,2)],
              vertex.attrnames = c("vertex.id", "agency"), 
              directed = F)

nd <-networkDynamic(nw, 
                    edge.spells = edgelist[,c(3,4,2,1)],
                    vertex.spells=nodelist[,c(3,4,1)])

我可以为网络设置边线,顶点动画:

reconcile.vertex.activity(nd, mode = "match.to.edges")

filmstrip(nd, 
          displaylabels = FALSE, 
          frames = 5, 
          slice.par = list(start = 2014, end = 2019, interval = 1, aggregate.dur = 1, rule = 'any'))

render.d3movie(nd,
               filename = "~/owncloud/longspine/data/animation.html",
               displaylabels = FALSE,
               # This slice function makes the labels work
               vertex.tooltip = function(slice) {paste("<b>Agency:</b>", (slice %v% "agency"))})

从本质上讲,这表明边缘和顶点是如何随时间变化的。接下来,我要按代理商预算调整顶点的大小。每年都在变化。我应该怎么做?在线教程有点难以理解。在我的示例中,我们总共有217个代理商。每个都将有一个年度预算(如果按预算存在,则在节点列表中为总站)。任何提示或建议,将不胜感激。

2 个答案:

答案 0 :(得分:0)

要设置动态顶点属性,可以使用activate.vertex.attribute()函数来定义哪些顶点在持续时间内应具有哪些值。例如,要在2014-2015年间在值为1的名为“预算”的顶点1上创建动态属性:

    nd <-activate.vertex.attribute(nd,'budget',
                                  value=10000,
                                  onset=2014,
                                  terminus=2015,
                                  v=1)

很可能您在创建对象时希望一次完成所有操作。如果您将nodelist设置为每年每个顶点有一行,则应该可以使用create.TEAs构造函数的networkDynamic()选项使用属性activity初始化对象您需要的咒语。因此,如果您的nodelist如下所示:


      vertex.id        agency portfolio      onset   terminus  budget
    1         1   AAF Company     FALSE 2014-07-01 2015-07-01   10000
    2         1   AAF Company     FALSE 2015-07-01 2016-07-01   10500
    ...

然后

    nd <-networkDynamic(nw, 
                    edge.spells = edgelist[,c(3,4,2,1)],
                    vertex.spells=nodelist[,c(3,4,1)],
                    create.TEAs=TRUE,
                    vertex.TEA.names='budget')

networkDynamic软件包插图中“激活TEA属性”部分应提供更多有用的信息https://cran.r-project.org/web/packages/networkDynamic/vignettes/networkDynamic.pdf

然后,您应该能够将动态顶点属性映射到ndtv中的动画绘图属性(ndtv将在每个时间点管理从动态到静态属性的转换)

render.d3movie(nd,vertex.cex='budget')

除非这些组织的预算很少,否则我猜您想使用预算的log()或其他方式来转换原始预算数或节点会很大。

还有一个教程对此进行了更深入的介绍,因为时间窗口中的值聚合如何工作需要一些细微之处:http://statnet.csde.washington.edu/workshops/SUNBELT/current/ndtv/ndtv_workshop.html#controlling-plot-properties-using-dynamic-attributes-teas

答案 1 :(得分:0)

我设法找到了一些工作。

require(sna)
require(tsna)
require(ndtv)
require(networkDynamic)
require(lubridate)

nodelist <- read.csv("https://github.com/aterhorst/data/raw/master/nodelist.csv", header=T, stringsAsFactors = F)
edgelist <- read.csv("https://github.com/aterhorst/data/raw/master/edgelist.csv", header=T, stringsAsFactors = F)
nodelist_expanded <- read.csv("https://github.com/aterhorst/data/raw/master/nodelist_expanded.csv", header=T, stringsAsFactors = F)

# onset date must be numeric (does not like date?)
nodelist$onset <- year(nodelist$onset)
nodelist$terminus <- year(nodelist$terminus)

# colour nodes by portfolio type
nodelist$col <- ifelse(nodelist$portfolio == T, "red", "blue")

nodelist_expanded$onset <- year(nodelist_expanded$onset)
nodelist_expanded$terminus <- year(nodelist_expanded$terminus)

# scale attributes
nodelist_expanded$log_appropriation <- log(nodelist_expanded$appropriation + 10) / 10
nodelist_expanded$log_ext_revenue <- log(nodelist_expanded$ext_revenue + 10) / 10

edgelist$onset <- year(edgelist$onset)
edgelist$terminus <- year(edgelist$terminus)

# create basic network object
nw <- network(edgelist[,c(2,3)],
          vertex.attr = nodelist[,c(1:3,6)],
          vertex.attrnames = c("vertex.id", "agency", "portfolio", "col"),
          directed = F)

# plot basic network object
plot(nw, vertex.col = "col")

# make dynamic network object
nd <-networkDynamic(nw,
                    edge.spells = edgelist[,c(4,5,3,2)],
                    vertex.spells = nodelist_expanded[,c(6,7,1,8,9)],
                    create.TEAs = TRUE,
                    vertex.TEA.names = c("log_appropriation", "log_ext_revenue"))

# reconcile things
reconcile.vertex.activity(nd, mode = "match.to.edges")

# make movie!
render.d3movie(nd,
               displaylabels = FALSE,
               vertex.col = "col",
               vertex.tooltip = function(slice) {
             paste("<b>Agency:</b>", (slice %v% "agency"))})