12

我想使用highcharter包在 R 中绘制一个桑基图。我在格式化它时遇到问题。这是示例。

# 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))

这将产生以下图片: 开箱即用

我希望B节点位于中间以获得更好的情节前景。因此,我尝试通过操纵Highcharts 系列的column属性来实现这一点:nodes

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]}]

相同但 with"A"而不是["A"]etc. 将起作用。JS 中的证明在这个jsfiddle中。

我尝试将 JavaScript 嵌入 plot with 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考虑在这种情况下需要的系列属性?

4

2 回答 2

3

可以通过重新定义基础数据来完成 A->B 和 B->C 的 Sankey:

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

但是,这并没有呈现出很好的情节。

于 2018-06-26T16:18:48.287 回答
0

正如评论中已经提到的,您可能想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)

在此处输入图像描述

于 2018-06-29T01:23:45.700 回答