修正无向网络数据:确保邻居关系双向对称
修正人员邻居关系数据的方法
问题说明
现有存储人员及邻居信息的data.frame存在两处问题:
- 存在自环(如Josh的邻居包含自身ID)
- 邻居关系不具备双向对称性(如Josh的邻居包含Emma,但Emma的邻居未包含Josh)
原始数据代码
x <- read.table(text = " Name ID Neighbour_ID Josh 1 1,2,3 Emma 2 4 Nick 3 1 Mark 4 5 Claire 5 ", sep = " ", header = TRUE)
原始数据输出
Name ID Neighbour_ID 1 Josh 1 1,2,3 2 Emma 2 4 3 Nick 3 1 4 Mark 4 5 5 Claire 5
期望修正结果
Name ID Neighbour_ID 1 Josh 1 2,3 2 Emma 2 1,4 3 Nick 3 1 4 Mark 4 2,5 5 Claire 5 4
实现步骤与代码
解决思路
- 拆分逗号分隔的邻居ID,构建单边数据集,同时移除自环与空值
- 生成所有边的反向边,确保邻居关系双向对称
- 按ID重新汇总邻居ID,合并回原始数据结构
完整代码
# 安装并加载tidyr包(若未安装) if (!require(tidyr)) install.packages("tidyr") library(tidyr) # 1. 拆分邻居ID为单行边,过滤无效数据 edges <- x %>% separate_rows(Neighbour_ID, sep = ",") %>% mutate(Neighbour_ID = trimws(Neighbour_ID)) %>% filter(Neighbour_ID != "", Neighbour_ID != as.character(ID)) # 2. 构建双向边数据集 bidirectional_edges <- rbind( edges[, c("ID", "Neighbour_ID")], # 生成反向边并重命名列 edges[, c("Neighbour_ID", "ID")] %>% setNames(c("ID", "Neighbour_ID")) ) %>% distinct() # 去重避免重复边 # 3. 按ID汇总邻居ID,排序后用逗号连接 corrected_neighbours <- bidirectional_edges %>% group_by(ID) %>% summarise(Neighbour_ID = paste(sort(Neighbour_ID), collapse = ","), .groups = "drop") # 4. 合并回原始数据,保留姓名信息 result <- x %>% select(Name, ID) %>% left_join(corrected_neighbours, by = "ID") # 输出结果 print(result)
代码说明
separate_rows:将逗号分隔的多邻居ID拆分为每行一个邻居,方便后续处理- 过滤步骤:去除空的邻居条目和ID与邻居ID相同的自环记录
- 双向边构建:通过反转原边的ID与邻居ID,保证所有邻居关系都是双向的
- 汇总步骤:按ID分组后将邻居ID排序并重新拼接为逗号分隔的字符串,与原始数据结构一致
内容的提问来源于stack exchange,提问作者KC15
相关产品推荐
相关产品推荐

