You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将航运航次数据转换为visNetwork/igraph可用的From-To格式?

拆分航运数据港口字段并构建网络图数据的R实现思路

Hey Dhiraj, 我懂你现在的痛点——要把带航次ID的航运数据拆成From/To港口对,还要保留Commencing、Loading这些功能属性,最后用visNetwork或者igraph做网络图可视化,之前试了for循环没搞定对吧?别慌,咱们用更简洁高效的方法来解决这个问题。

首先,先模拟一下你的数据集结构(方便后续演示):

# 模拟你的航运数据集
shipping_data <- data.frame(
  VoyageID = c(1,1,1,2,2,2,2,3,3,3),
  PortName = c("Shanghai", "Shanghai", "Singapore", "Rotterdam", "Antwerp", "Hamburg", "Rotterdam", "Los Angeles", "Long Beach", "Oakland"),
  PortFunction = c("Commencing", "Loading", "Discharging", "Commencing", "Waiting", "Loading", "Discharging", "Commencing", "Waiting", "Discharging")
)

核心思路:按航次分组配对港口

每个航次是一个连续的港口序列,我们需要按航次ID分组,把每个港口和它的下一个港口自动配对成From/To,同时保留对应的功能属性。用dplyr的分组函数比手动写for循环靠谱得多,能避免索引错误、分组遗漏这些坑。

1. 生成From/To字段与功能属性

library(dplyr)

# 按航次分组,生成港口流转对
network_data <- shipping_data %>%
  group_by(VoyageID) %>%
  mutate(
    From = PortName,
    To = lead(PortName),  # 取当前航次下一个港口作为To
    From_Function = PortFunction,  # 保留出发港口的功能
    To_Function = lead(PortFunction)  # 保留到达港口的功能
  ) %>%
  ungroup() %>%
  filter(!is.na(To))  # 过滤每个航次的最后一行(无后续港口,无需作为起点)

这里的lead()函数是关键——它会在每个航次分组内,把下一行的PortName和PortFunction移到当前行,自动完成港口配对,完美适配多卸载港口的场景(比如一个航次有A→B→C→D多个港口,会生成A→B、B→C、C→D三行数据)。

2. 为可视化准备节点和边数据

visNetwork和igraph都需要独立的节点数据集和边数据集,咱们来整理一下:

节点数据(所有唯一港口)

nodes <- network_data %>%
  # 合并From和To的港口,保留功能属性
  select(PortName = From, Function = From_Function) %>%
  bind_rows(network_data %>% select(PortName = To, Function = To_Function)) %>%
  distinct(PortName, .keep_all = TRUE) %>%
  mutate(id = PortName)  # visNetwork要求节点有唯一id,这里直接用港口名

边数据(港口流转关系)

edges <- network_data %>%
  select(
    from = From,
    to = To,
    label = paste(From_Function, "→", To_Function),  # 边的标签显示功能流转
    voyage_id = VoyageID  # 保留航次ID,方便后续筛选
  )

3. 用visNetwork快速生成网络图

library(visNetwork)

visNetwork(nodes, edges) %>%
  visEdges(arrows = "to") %>%  # 添加箭头明确流转方向
  visOptions(highlightNearest = TRUE) %>%  # 点击节点时高亮相邻节点
  visLayout(randomSeed = 123)  # 固定布局种子,避免每次刷新布局变化

为什么之前的for循环没成功?

大概率是手动循环时没处理好分组逻辑——比如没有正确按航次ID隔离数据,或者遗漏了每个航次最后一个节点的过滤。用dplyr的分组函数可以自动处理这些细节,比手动循环更稳定高效。

内容的提问来源于stack exchange,提问作者Dhiraj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:45:22