多层 SankeyNetwork (NetworkD3) 不在 R 中绘制
Multi-layer SankeyNetwork (NetworkD3) does not plot in R
我已经成功地使用 NetworkD3 包绘制了 2 层 Sankey 网络。我创建了一个函数,它采用包含列源、目标和值的数据框,并输出桑基图。我使用此功能来帮助快速生成类似的图。我的问题不是关于函数的效率 - 尽管我的问题的根源可能在于它。
下面我提供了一个可重现的例子。我演示了我的函数如何为两个数据集(z1 和 z2)生成 SankeyNetwork。然而,当我将这些数据集与创建 3 层 SankeyNetwork 的想法结合起来时 - 查看器中没有任何图(我也尝试增加宽度和高度)。我猜这可能与索引有关,尽管在过去我会收到关于需要零索引的错误输出。我没有收到任何错误,只是一个空白图。
library(networkD3)
library(dplyr)
# The function used to create the plots
sanktify <- function(x) {
# Create nodes DF with the unique sources & targets from input
nodes <- unique(data.frame(c(unique(x$source), unique(x$target))))
nodes$ID <- as.numeric(rownames(nodes)) - 1 # sankeyNetwork requires IDs to be zero-indexed
names(nodes) <- c("name", "ID")
# Create two versions of nodes for merging
nodes_source <- nodes
nodes_target <- nodes
names(nodes_source) <- c("source", "source_ID")
names(nodes_target) <- c("target", "target_ID")
# Replace source & target in links DF with IDs
links <- merge(x, nodes_source, by="source", all.x=TRUE) %>%
merge(nodes_target, by="target", all.x=TRUE) %>%
select(source_ID, target_ID, value) %>%
arrange(source_ID)
# Create Sankey Plot
sank <- sankeyNetwork(
Links = links,
Nodes = nodes,
Source = "source_ID",
Target = "target_ID",
Value = "value",
NodeID = "name",
units = "USD",
fontSize = 12,
nodeWidth = 30
)
return(sank)
}
# Creating & plotting first data frame.
z1 <- tbl_df(data.frame(source = c("A", "A", "B", "B"),
target = c("Cardiovascular", "Neurological", "Cardiovascular", "Neurological"),
value = c(5, 8, 2, 10)))
z1$source <- as.character(z1$source)
z1$target <- as.character(z1$target)
sanktify(z1) # Correctly produces plot
# Creating & plotting 2nd data frame
z2 <- tbl_df(data.frame( source = c("Cardiovascular", "Cardiovascular", "Neurological", "Neurological"),
target = c("IP Surg", "IP Med", "IP Surg", "IP Med"),
value = c(3, 7, 6, 1)))
z2$source <- as.character(z2$source)
z2$target <- as.character(z2$target)
sanktify(z2) # Correctly produces plot
# Combining the two dataframes into a new DF with the goal of creating a '3-layer' plot.
z3 <- rbind(z1, z2)
sanktify(z3) # Blank output. No errors in the R console
尽管做了很多繁琐的逐步工作来根除问题,但令人尴尬的是,我从未尝试颠倒我将两个数据帧绑定在一起的顺序。
z3 <- rbind(z2,z1) 使用 Sanktify 函数,而 z3 <- rbind(z1,z2) 生成空白图。
不确定为什么 - 因为我的函数旨在提供零索引 ID #。所以如果有比较了解JS/D3的人知道,我很好奇
我相信答案应该在交叉发布的 Github 问题 https://github.com/christophergandrud/networkD3/issues/134 中。我也会在这里复制并粘贴代码。 unique
位置错误,需要在源和目标连接后 运行。
library(networkD3)
library(dplyr)
# The function used to create the plots
sanktify <- function(x) {
# Create nodes DF with the unique sources & targets from input
# ***** changing this is the key***********************************************************
nodes <- data.frame(unique(c(x$source,x$target)),stringsAsFactors=FALSE)
# ************************************************************************************************
nodes$ID <- as.numeric(rownames(nodes)) - 1 # sankeyNetwork requires IDs to be zero-indexed
names(nodes) <- c("name", "ID")
# use dplyr join over merge since much better; in this case not big enough to matter
# Replace source & target in links DF with IDs
links <- inner_join(x, nodes, by = c("source"="name")) %>%
rename(source_ID = ID) %>%
inner_join(nodes, by = c("target"="name")) %>%
rename(target_ID = ID)
# Create Sankey Plot
sank <- sankeyNetwork(
Links = links,
Nodes = nodes,
Source = "source_ID",
Target = "target_ID",
Value = "value",
NodeID = "name",
units = "USD",
fontSize = 12,
nodeWidth = 30
)
return(sank)
}
# use data_frame to avoid tbl_df(data.frame(
z1 <- data_frame(
source = c("A", "A", "B", "B"),
target = c("Cardiovascular", "Neurological", "Cardiovascular", "Neurological"),
value = c(5, 8, 2, 10)
)
z2 <- data_frame(
source = c("Cardiovascular", "Cardiovascular", "Neurological", "Neurological"),
target = c("IP Surg", "IP Med", "IP Surg", "IP Med"),
value = c(3, 7, 6, 1)
)
z3 <- bind_rows(z1,z2)
sanktify(z3)
我已经成功地使用 NetworkD3 包绘制了 2 层 Sankey 网络。我创建了一个函数,它采用包含列源、目标和值的数据框,并输出桑基图。我使用此功能来帮助快速生成类似的图。我的问题不是关于函数的效率 - 尽管我的问题的根源可能在于它。
下面我提供了一个可重现的例子。我演示了我的函数如何为两个数据集(z1 和 z2)生成 SankeyNetwork。然而,当我将这些数据集与创建 3 层 SankeyNetwork 的想法结合起来时 - 查看器中没有任何图(我也尝试增加宽度和高度)。我猜这可能与索引有关,尽管在过去我会收到关于需要零索引的错误输出。我没有收到任何错误,只是一个空白图。
library(networkD3)
library(dplyr)
# The function used to create the plots
sanktify <- function(x) {
# Create nodes DF with the unique sources & targets from input
nodes <- unique(data.frame(c(unique(x$source), unique(x$target))))
nodes$ID <- as.numeric(rownames(nodes)) - 1 # sankeyNetwork requires IDs to be zero-indexed
names(nodes) <- c("name", "ID")
# Create two versions of nodes for merging
nodes_source <- nodes
nodes_target <- nodes
names(nodes_source) <- c("source", "source_ID")
names(nodes_target) <- c("target", "target_ID")
# Replace source & target in links DF with IDs
links <- merge(x, nodes_source, by="source", all.x=TRUE) %>%
merge(nodes_target, by="target", all.x=TRUE) %>%
select(source_ID, target_ID, value) %>%
arrange(source_ID)
# Create Sankey Plot
sank <- sankeyNetwork(
Links = links,
Nodes = nodes,
Source = "source_ID",
Target = "target_ID",
Value = "value",
NodeID = "name",
units = "USD",
fontSize = 12,
nodeWidth = 30
)
return(sank)
}
# Creating & plotting first data frame.
z1 <- tbl_df(data.frame(source = c("A", "A", "B", "B"),
target = c("Cardiovascular", "Neurological", "Cardiovascular", "Neurological"),
value = c(5, 8, 2, 10)))
z1$source <- as.character(z1$source)
z1$target <- as.character(z1$target)
sanktify(z1) # Correctly produces plot
# Creating & plotting 2nd data frame
z2 <- tbl_df(data.frame( source = c("Cardiovascular", "Cardiovascular", "Neurological", "Neurological"),
target = c("IP Surg", "IP Med", "IP Surg", "IP Med"),
value = c(3, 7, 6, 1)))
z2$source <- as.character(z2$source)
z2$target <- as.character(z2$target)
sanktify(z2) # Correctly produces plot
# Combining the two dataframes into a new DF with the goal of creating a '3-layer' plot.
z3 <- rbind(z1, z2)
sanktify(z3) # Blank output. No errors in the R console
尽管做了很多繁琐的逐步工作来根除问题,但令人尴尬的是,我从未尝试颠倒我将两个数据帧绑定在一起的顺序。
z3 <- rbind(z2,z1) 使用 Sanktify 函数,而 z3 <- rbind(z1,z2) 生成空白图。
不确定为什么 - 因为我的函数旨在提供零索引 ID #。所以如果有比较了解JS/D3的人知道,我很好奇
我相信答案应该在交叉发布的 Github 问题 https://github.com/christophergandrud/networkD3/issues/134 中。我也会在这里复制并粘贴代码。 unique
位置错误,需要在源和目标连接后 运行。
library(networkD3)
library(dplyr)
# The function used to create the plots
sanktify <- function(x) {
# Create nodes DF with the unique sources & targets from input
# ***** changing this is the key***********************************************************
nodes <- data.frame(unique(c(x$source,x$target)),stringsAsFactors=FALSE)
# ************************************************************************************************
nodes$ID <- as.numeric(rownames(nodes)) - 1 # sankeyNetwork requires IDs to be zero-indexed
names(nodes) <- c("name", "ID")
# use dplyr join over merge since much better; in this case not big enough to matter
# Replace source & target in links DF with IDs
links <- inner_join(x, nodes, by = c("source"="name")) %>%
rename(source_ID = ID) %>%
inner_join(nodes, by = c("target"="name")) %>%
rename(target_ID = ID)
# Create Sankey Plot
sank <- sankeyNetwork(
Links = links,
Nodes = nodes,
Source = "source_ID",
Target = "target_ID",
Value = "value",
NodeID = "name",
units = "USD",
fontSize = 12,
nodeWidth = 30
)
return(sank)
}
# use data_frame to avoid tbl_df(data.frame(
z1 <- data_frame(
source = c("A", "A", "B", "B"),
target = c("Cardiovascular", "Neurological", "Cardiovascular", "Neurological"),
value = c(5, 8, 2, 10)
)
z2 <- data_frame(
source = c("Cardiovascular", "Cardiovascular", "Neurological", "Neurological"),
target = c("IP Surg", "IP Med", "IP Surg", "IP Med"),
value = c(3, 7, 6, 1)
)
z3 <- bind_rows(z1,z2)
sanktify(z3)