求助:基于dplyr按路线分组生成所有起讫点组合的方法
当然可以用dplyr搭配purrr、tidyr这类工具轻松实现!我给你两种可行的方案,都能完美生成你需要的所有起讫点组合:
先准备好原始数据
df <- read.table(text = "route origin dest seq 1 a b 1 1 b c 2 1 c d 3 1 d e 4 2 f g 1 2 g h 2 2 h i 3", header = TRUE)
方案一:用expand.grid筛选有序对
这种方法逻辑清晰,适合理解整个过程:
library(dplyr) library(purrr) library(tidyr) all_origin_dest <- df %>% group_by(route) %>% # 把每个路线的站点按行驶顺序拼接成完整序列 mutate(full_stations = list(c(origin, dest))) %>% # 每个路线只保留一行,避免重复处理 slice(1) %>% # 生成所有站点对,只保留起点在序列中位置早于终点的组合 mutate(station_pairs = map(full_stations, ~ expand.grid( origin = .x, dest = .x, stringsAsFactors = FALSE ) %>% filter(match(origin, .x) < match(dest, .x)))) %>% # 展开成表格形式 unnest(station_pairs) %>% # 只保留需要的列 select(origin, dest) %>% ungroup() print(all_origin_dest)
方案二:用combn简化代码
如果追求更简洁的写法,combn函数可以直接生成所有符合顺序的2站点组合:
all_origin_dest <- df %>% group_by(route) %>% # 拼接每个路线的完整站点序列 summarize(full_stations = c(first(origin), dest)) %>% # 用combn生成所有有序站点对,转置后转为数据框 mutate(station_pairs = map(full_stations, ~ as.data.frame( t(combn(.x, 2)), stringsAsFactors = FALSE ) %>% rename(origin = V1, dest = V2))) %>% unnest(station_pairs) %>% ungroup()
结果说明
两种方案都会生成你预期的输出:比如路线1会包含a-b、a-c、a-d、a-e、b-c、b-d、b-e、c-d、c-e、d-e这些组合,路线2则会生成f-g、f-h、f-i、g-h、g-i、h-i,完全符合列车行驶路线的所有可能起讫点需求。
内容的提问来源于stack exchange,提问作者FilipeTeixeira
相关产品推荐
相关产品推荐

