R中Sankey Data的数据准备获取流量频率
Data preparation for Sankey Data in R to get flow frequency
我尝试使用 ggalluvial 和 networkd3 包创建 Sankey 图,但迄今为止失败了。理想情况下,我想了解如何在两者中获得我想做的事情。
数据生成如下:
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`)
不确定是 dat 还是 dat_wide 更合适?
我希望输出可视化以下信息(其中括号中的数字是频率,因此是流的宽度)
SA -(2) - SA - (1) - AB
- (1) - SA
AB -(1) - AB
我按照有关 networkd3 link 的说明进行操作 ,但是我最终在图中出现了循环。
我想要的类似图如下图所示:
[![取自 SAS VA 的桑基图][2]][2]
建议和帮助将不胜感激...
谢谢!
[2]: https://i.stack.imgur.com/wTJ1k.png
我发现冲积包对这项任务很有用,但我不知道这是否是您锁定的目的:
library(tidyverse)
library(alluvial)
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_summarized <- dat %>% group_by(holiday_num, holiday_loc, customer) %>%
summarise(n = n()) %>% mutate(color = recode(customer,
`1` = "cadetblue1",
`2` = "cadetblue2",
`3` = "cadetblue3"))
alluvial(dat_summarized[1:3],
freq = dat_summarized$n,
col = dat_summarized$color)
您的数据的核心问题(在 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)
由此,您可以构建一个节点数据框,其中每个不同的节点包含一行,如下所示...
node_names <- factor(sort(unique(c(as.character(links$source),
as.character(links$target)))))
nodes <- data.frame(name = node_names)
然后转换链接数据帧以使用节点数据帧中节点的索引(0 索引,因为它最终被传递给 JavaScript),像这样...
links <- data.frame(source = match(links$source, node_names) - 1,
target = match(links$target, node_names) - 1,
value = 1)
此时,如果您希望节点具有非不同的名称,您现在可以更改它,像这样...
nodes$name <- sub("_[0-9]$", "", nodes$name)
现在你可以绘制它了...
library(networkD3)
sankeyNetwork(links, nodes, "source", "target", "value", "name")
我尝试使用 ggalluvial 和 networkd3 包创建 Sankey 图,但迄今为止失败了。理想情况下,我想了解如何在两者中获得我想做的事情。
数据生成如下:
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`)
不确定是 dat 还是 dat_wide 更合适? 我希望输出可视化以下信息(其中括号中的数字是频率,因此是流的宽度)
SA -(2) - SA - (1) - AB
- (1) - SA
AB -(1) - AB
我按照有关 networkd3 link 的说明进行操作
我想要的类似图如下图所示: [![取自 SAS VA 的桑基图][2]][2]
建议和帮助将不胜感激...
谢谢!
[2]: https://i.stack.imgur.com/wTJ1k.png
我发现冲积包对这项任务很有用,但我不知道这是否是您锁定的目的:
library(tidyverse)
library(alluvial)
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_summarized <- dat %>% group_by(holiday_num, holiday_loc, customer) %>%
summarise(n = n()) %>% mutate(color = recode(customer,
`1` = "cadetblue1",
`2` = "cadetblue2",
`3` = "cadetblue3"))
alluvial(dat_summarized[1:3],
freq = dat_summarized$n,
col = dat_summarized$color)
您的数据的核心问题(在 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)
由此,您可以构建一个节点数据框,其中每个不同的节点包含一行,如下所示...
node_names <- factor(sort(unique(c(as.character(links$source),
as.character(links$target)))))
nodes <- data.frame(name = node_names)
然后转换链接数据帧以使用节点数据帧中节点的索引(0 索引,因为它最终被传递给 JavaScript),像这样...
links <- data.frame(source = match(links$source, node_names) - 1,
target = match(links$target, node_names) - 1,
value = 1)
此时,如果您希望节点具有非不同的名称,您现在可以更改它,像这样...
nodes$name <- sub("_[0-9]$", "", nodes$name)
现在你可以绘制它了...
library(networkD3)
sankeyNetwork(links, nodes, "source", "target", "value", "name")