R Highcharter Sankey узловой столбец

Я хочу построить диаграмму Санки в R, используя пакет highcharter. У меня проблема с форматированием. Вот пример.

# devtools::install_github("jbkunst/highcharter")
library(highcharter)

hc_dat <- data.frame(from = c("A", "A", "B"), 
                     to = c("C", "B", "C"), N = c(7, 5, 5))
highchart() %>%
  hc_add_series(data = hc_dat, type = "sankey", 
                hcaes(from = from, to = to, weight = N))

Это приводит к следующему изображению: Out-of-box

Я хочу, чтобы узел B был посередине для лучшего обзора сюжета. Поэтому я пытаюсь добиться этого, манипулируя свойством column nodes в серии Highcharts:

nodes_mapping <- list(list(id = "A", column = 0),
                      list(id = "B", column = 1),
                      list(id = "C", column = 2))

highchart() %>%
  hc_add_series(data = hc_dat, type = "sankey", 
                nodes = nodes_mapping,
                hcaes(from = from, to = to, weight = N))

Это не меняет изображение. Я нашел, причина следующая: highcharter использует jsonlite::toJSON для преобразования R объектов, и он предоставляет ненужные [] в JSON, что приводит к нарушению поведения Highcharts.

jsonlite::toJSON(nodes_mapping)
# [{"id":["A"],"column":[0]},{"id":["B"],"column":[1]},{"id":["C"],"column":[2]}]

То же самое, но с "A" вместо ["A"] и т.д., Будет работать. Доказательство в JS находится в этом jsfiddle.

Я попытался встроить JavaScript в сюжет с htmlwidgets::JS, но он не работает:

highchart() %>%
  hc_add_series(data = hc_dat, type = "sankey", 
                nodes = JS('[{"id":"A","column":[0]},{"id":"B","column":[1]},{"id":"C","column":[2]}]'),
                hcaes(from = from, to = to, weight = N))
# empty chart

highchart() %>%
  hc_add_series(data = hc_dat, type = "sankey", 
                JS('nodes: [{"id":"A","column":[0]},{"id":"B","column":[1]},{"id":"C","column":[2]}]'),
                hcaes(from = from, to = to, weight = N))
# Error: inherits(mapping, "hcaes") is not TRUE

highchart() %>%
  hc_add_series(data = hc_dat, type = "sankey", 
                hcaes(from = from, to = to, weight = N),
                JS('nodes: [{"id":"A","column":[0]},{"id":"B","column":[1]},{"id":"C","column":[2]}]'))
# Error: Column 4 must be named

Итак, здесь я застрял. Кто-нибудь знает, как сделать hc_add_series рассмотрением свойств сериала по мере необходимости в этом случае?

Ответ 1

Санки из A-> B и из B-> C может быть сделано путем переопределения ваших базовых данных:

 hc_dat <- data.frame(from = c("A", "B"), 
                 to = c("B", "C"), N = c(7, 5))

Аналогично, вы можете определить узел из A-> C

 hc_dat <- data.frame(from = c("A", "B", "A"), 
                 to = c("B", "C", "C"), N = c(5, 5, 7))

Однако это не делает хороший сюжет.

Ответ 2

Как уже упоминалось в комментариях, вы можете сделать networkD3.

Вот пример, основанный на данных примера, которые вы предоставляете.

# Create nodes and links data.frames
nodes <- data.frame(name = unique(unlist(hc_dat[, 1:2])))
links <- data.frame(
    source = match(hc_dat$from, nodes$name) - 1,
    target = match(hc_dat$to, nodes$name) - 1,
    value = hc_dat$N)

# Draw a Sankey diagram
library(networkD3)
sankeyNetwork(
    Links = links, Nodes = nodes,
    Source = "source", Target = "target", Value = "value", NodeID = "name",
    fontSize = 16, fontFamily = "sans-serif", nodeWidth = 30, nodePadding = 30)

enter image description here