Управление атрибутами динамических вершин с помощью networkDynamic и/или ndtv

Я смотрю, как со временем меняются государственные органы. Планируется использовать пакет ndtv для визуализации изменений. У меня есть список узлов, в котором перечислены идентификаторы вершин, имя агентства, начало узла и конец узла:

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)

Я могу довольно легко создать сетевой объект:

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 агентств. У каждого будет годовой бюджет (если они существуют в начале, конце в списке узлов). Любые советы или советы будут оценены.

похоже, что список узлов в вашем примере на самом деле загружает файл списка краев?

skyebend 29.05.2019 06:17
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
572
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

чтобы настроить динамические атрибуты вершин, вы можете использовать функцию activate.vertex.attribute(), чтобы определить, какие вершины должны иметь какие значения для какой продолжительности. Например, чтобы создать динамический атрибут в вершине 1 с именем «бюджет» со значением 10 000 за период с 2014 по 2015 год:

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

Скорее всего, вы захотите сделать это сразу при создании объекта. Если вы настроите свой nodelist так, чтобы он имел одну строку на вершину в год, вы должны иметь возможность использовать параметр create.TEAs конструктора networkDynamic() для инициализации объекта с помощью заклинаний активности атрибутов, которые вам нужны. Итак, если ваш 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

Кстати, заклинания активности - это "право открытые" интервалы, поэтому я изменил дату окончания на 07-01, чтобы не оставить организации без финансирования на один день.

skyebend 29.05.2019 06:55

Спасибо. У меня возникают проблемы с согласованием бюджетов с агентствами, поэтому я пока не могу протестировать ваше решение. Легче сказать, чем сделать увязку бюджетных документов с административными мероприятиями.

aterhorst 31.05.2019 08:23

nodelist_expanded <- read.csv("github.com/aterhorst/data/raw/master/nodelist_expa‌​nded.csv", header=T, stringsAsFactors = F)

aterhorst 12.06.2019 08:47

nodelist_expanded требует, чтобы даты были выровнены, чтобы не было пробелов в один день. Однако я не слишком хорошо разбираюсь в TEA. Я получаю эту ошибку при попытке использовать nodelist_expanded: Ошибка в networkDynamic(edge.spells = edgelist[, c(4, 5, 3, 2)], vertex.spells = nodelist_expanded[,: вектор vertex.TEA.names должен соответствовать количеству оставшихся столбцов в vertex.spells

aterhorst 12.06.2019 08:50

Фиксированные даты, чтобы они совпадали, сейчас.

aterhorst 12.06.2019 09:07
Ответ принят как подходящий

Мне удалось заставить что-то работать.

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"))})

Другие вопросы по теме