如何用R的plotly/networkD3包生成桑基图?数据格式处理咨询
桑基图数据格式解析与转换({plotly}/{networkD3}适用)
三个核心字段的含义
- source:桑基图里流的起点节点(比如
2005_0代表2005年响应类别为0的群体) - target:桑基图里流的终点节点(比如
2010_1代表2010年响应类别为1的群体) - value:从起点节点流向终点节点的样本数量
现有数据转换步骤
你的数据是每个样本(UniqID)在各年份的响应记录,要做年份间的流转分析,需要先把相邻年份的响应配对,再统计每种配对的次数。以下是完整实现代码:
第一步:处理原始数据,生成流转统计
library(dplyr) library(tidyr) # 原始数据 df <- data.frame( UniqID = rep(c(1:10), times=4), Year = c(rep("2005", times=10), rep("2010", times=10), rep("2015", times=10), rep("2020", times=10)), Response_Variable = round(runif(n = 40, min = 0, max = 2), digits = 0) ) # 转成宽格式:每个ID一行,列对应各年份的响应值 wide_df <- df %>% pivot_wider(names_from = Year, values_from = Response_Variable) # 生成相邻年份的流转配对,并统计数量 flow_data <- bind_rows( # 2005 → 2010的流转 wide_df %>% select(UniqID, source_year = `2005`, target_year = `2010`) %>% mutate(source = paste0("2005_", source_year), target = paste0("2010_", target_year)), # 2010 → 2015的流转 wide_df %>% select(UniqID, source_year = `2010`, target_year = `2015`) %>% mutate(source = paste0("2010_", source_year), target = paste0("2015_", target_year)), # 2015 → 2020的流转 wide_df %>% select(UniqID, source_year = `2015`, target_year = `2020`) %>% mutate(source = paste0("2015_", source_year), target = paste0("2020_", target_year)) ) %>% count(source, target, name = "value")
第二步:用{networkD3}绘制桑基图
networkD3要求节点用数字ID(0起始),需要先做名称映射:
library(networkD3) # 提取所有唯一节点 nodes <- data.frame(name = unique(c(flow_data$source, flow_data$target))) # 给流转数据匹配数字ID flow_data <- flow_data %>% mutate( source_id = match(source, nodes$name) - 1, target_id = match(target, nodes$name) - 1 ) # 生成桑基图 sankeyNetwork( Links = flow_data, Nodes = nodes, Source = "source_id", Target = "target_id", Value = "value", NodeID = "name", fontSize = 12, nodeWidth = 30 )
第三步:用{plotly}绘制桑基图
plotly支持直接用节点名称,无需转数字ID:
library(plotly) plot_ly( type = "sankey", node = list( label = unique(c(flow_data$source, flow_data$target)), pad = 15, thickness = 20 ), link = list( source = match(flow_data$source, unique(c(flow_data$source, flow_data$target))) - 1, target = match(flow_data$target, unique(c(flow_data$source, flow_data$target))) - 1, value = flow_data$value ) ) %>% layout(title = "响应类别年份流转桑基图")
内容的提问来源于stack exchange,提问作者wisamb
相关产品推荐
相关产品推荐

