为 R 中的 Sankey Data 准备数据以获取流频率

use*_*372 4 r sankey-diagram networkd3

我曾尝试使用 ggalluvial 和 networkd3 包创建桑基图,但未能成功。理想情况下,我想了解如何在两者中获得我想做的事情。

数据生成如下:

dat <- data.frame(customer = c(rep(c(1, 2), each=3), 3, 3),
              holiday_loc = c("SA", "SA", "AB", "SA", "SA", "SA", "AB", "AB"),
              holiday_num = c(1, 2, 3, 1, 2, 3, 1, 2))

dat_wide <- dat %>%
        spread(key=holiday_num, value=holiday_loc`)
Run Code Online (Sandbox Code Playgroud)

不确定 dat 还是 dat_wide 更合适?我希望输出可视化以下信息(括号中的数字是频率,因此是流量的宽度)

SA -(2) - SA - (1) - AB

           - (1) - SA
Run Code Online (Sandbox Code Playgroud)

AB -(1) - AB

我按照这个链接上的说明使用 networkd3 为 R 中的离散状态序列networkd3 Sankey 图,但是我最终在图中找到了循环。

下图显示了我想要的类似图表:[![Sankey 图表取自 SAS VA][2]][2]

建议和帮助将不胜感激...

谢谢!

[2]:https : //i.stack.imgur.com/wTJ1k.png在此处输入图片说明

CJ *_*man 5

您的数据的核心问题(networkD3就术语而言)是您具有相同名称的节点,因此您需要区分它们,至少在处理数据时是这样。

结合位置和数量信息来制作可区分的节点,然后将您的数据转换为链接数据框,就像这样......

links <- 
  dat %>% 
  mutate("source" = paste(holiday_loc, holiday_num, sep = "_")) %>% 
  group_by(customer) %>% 
  arrange(holiday_num) %>% 
  mutate("target" =  lead(source)) %>% 
  ungroup() %>% 
  arrange(customer) %>% 
  filter(!is.na(target)) %>% 
  select(source, target)
Run Code Online (Sandbox Code Playgroud)

从中,您可以构建一个节点数据框,其中包含每个不同节点的一行,就像这样......

node_names <- factor(sort(unique(c(as.character(links$source), 
                                   as.character(links$target)))))
nodes <- data.frame(name = node_names)
Run Code Online (Sandbox Code Playgroud)

然后将链接数据帧转换为使用节点数据帧中节点的索引(0 索引,因为它最终被传递给 JavaScript),就像这样......

links <- data.frame(source = match(links$source, node_names) - 1, 
                    target = match(links$target, node_names) - 1,
                    value = 1)
Run Code Online (Sandbox Code Playgroud)

此时,如果您希望节点具有非不同的名称,您现在可以更改它,就像这样......

nodes$name <- sub("_[0-9]$", "", nodes$name)
Run Code Online (Sandbox Code Playgroud)

现在你可以绘制它...

library(networkD3)
sankeyNetwork(links, nodes, "source", "target", "value", "name")
Run Code Online (Sandbox Code Playgroud)

桑基情节