I want to plot a Sankey diagram in R using highcharter
package. I face a problem with formatting it. Here is the example.
# 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))
This produces the following picture:
I want the B
node to be in the middle for better outlook of the plot. So I try to achieve this manipulating the column
property of the nodes
in Highcharts series:
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))
This doesn't change the picture. I've found, the reason is following: highcharter
uses jsonlite::toJSON
to convert R
objects, and it provides unnecessary []
in JSON, which corrupts Highcharts behaviour.
jsonlite::toJSON(nodes_mapping)
# [{"id":["A"],"column":[0]},{"id":["B"],"column":[1]},{"id":["C"],"column":[2]}]
The same but with "A"
instead of ["A"]
etc. will work. The proof in JS is in this jsfiddle.
I've tried to embed JavaScript in plot with htmlwidgets::JS
, but it doesn't work:
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
So, here I'm stuck. Does anyone know how to make hc_add_series
consider properties of series as it's needed in this case?
Sankey from A->B and from B->C can be done by re-defining your underlying data:
hc_dat <- data.frame(from = c("A", "B"),
to = c("B", "C"), N = c(7, 5))
Similarly, you can define node from A->C
hc_dat <- data.frame(from = c("A", "B", "A"),
to = c("B", "C", "C"), N = c(5, 5, 7))
This does not render a nice plot, though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With