如何基于时间维度的区域合并/拆分对数据集R中的区域进行分组?
区域变更分组解决方案
原始数据
data <- data.frame( id_territory = c("id_1", "id_2", "id_3","id_3","id_4","id_5","id_6","id_7", "id_8", "id_9"), type_mutation = c("absorbed territory","absorbed territory", "absorbing territory", "absorbed territory", "absorbing territory", "absorbing territory","creation","part of territory transferred", "absorbed territory", "absorbing territory"), id_reform = c("A","A","A","B","B","B","C","C","D","D") )
变更说明
- 改革A:id_1、id_2被id_3合并
- 改革B:id_3拆分为id_4、id_5
- 改革C:id_6由id_7的部分区域新建
- 改革D:id_8被id_9合并
期望输出
df <- data.frame( id_territory = c("id_1", "id_2", "id_3","id_3","id_4","id_5","id_6","id_7", "id_8", "id_9"), type_mutation = c("absorbed territory","absorbed territory", "absorbing territory", "absorbed territory", "absorbing territory", "absorbing territory","creation","part of territory transferred", "absorbed territory", "absorbing territory"), id_reform = c("A","A","A","B","B","B","C","C","D","D"), group_id = c("group_1","group_1", "group_1", "group_1","group_1","group_1","group_2","group_2", "group_3", "group_3") )
实现代码
核心思路是用连通分量识别关联区域:把每个改革中存在变更关系的区域连边,同一连通分量的区域归为同一组。
# 安装加载igraph包 if (!require(igraph)) { install.packages("igraph") library(igraph) } # 构建关联边列表 edges <- data.frame(from = character(), to = character()) # 遍历每个改革批次,生成关联边 for (reform in unique(data$id_reform)) { sub_data <- subset(data, id_reform == reform) # 处理吸收/合并场景:被吸收区域关联到吸收区域 absorbing <- sub_data$id_territory[sub_data$type_mutation == "absorbing territory"] absorbed <- sub_data$id_territory[sub_data$type_mutation == "absorbed territory"] if (length(absorbing) > 0 && length(absorbed) > 0) { edges <- rbind(edges, data.frame(from = absorbed, to = rep(absorbing[1], length(absorbed)))) } # 处理新建/部分转移场景:新建区域关联到转出区域 creation <- sub_data$id_territory[sub_data$type_mutation == "creation"] transferred <- sub_data$id_territory[sub_data$type_mutation == "part of territory transferred"] if (length(creation) > 0 && length(transferred) > 0) { edges <- rbind(edges, data.frame(from = creation, to = transferred)) } } # 构建无向图并提取连通分量 g <- graph_from_data_frame(edges, directed = FALSE) comp <- components(g) # 为每个区域分配分组ID data$group_id <- paste0("group_", comp$membership[match(data$id_territory, names(comp$membership))]) # 处理无关联的独立区域(示例中无此情况,保留鲁棒性) unlinked <- setdiff(unique(data$id_territory), names(comp$membership)) if (length(unlinked) > 0) { next_group <- max(comp$membership) + 1 for (terr in unlinked) { data$group_id[data$id_territory == terr] <- paste0("group_", next_group) next_group <- next_group + 1 } } # 输出结果 print(data)
运行后即可得到期望的分组结果:id_1-id_5因多次拆分合并属于同一连通分量(group_1),id_6-id_7因新建关联属于group_2,id_8-id_9因合并属于group_3。
内容的提问来源于stack exchange,提问作者Coralie
相关产品推荐
相关产品推荐

