R igraph筛选互选二元组边表并仅保留单条记录的实现方法
问题说明
现有有向图边表(edgelist),需要筛选存在双向互选关系的二元组(mutual dyads,即同时存在u -> v和v -> u两条边的节点对),要求最终输出的边表中每组互选二元组仅保留1行记录,不同时保留双向两条边。
现有尝试与问题
使用igraph包的which_mutual()函数可以识别所有属于互选二元组的边,但直接筛选会保留每组互选对的双向两条记录,无法满足单组单条的输出要求,示例代码如下:
library(igraph) # 生成示例有向图与边表 g <- sample_gnm(10, 50, directed=TRUE) ff <- as_data_frame(g) # 识别互选边 cd <- which_mutual(g) # 直接筛选会保留双向两条边 ff[which(cd==1),]
实现方案
核心思路:先筛选出所有互选边,再为每个无方向的节点对生成唯一标识,按标识去重即可,每组二元组仅保留1条记录。
方法1:通用去重(按边表顺序保留第一条)
代码可直接运行:
library(igraph) g <- sample_gnm(10, 50, directed=TRUE) ff <- as_data_frame(g) # 步骤1:提取所有互选边 mutual_edges <- ff[which_mutual(g) == 1, ] # 步骤2:为每个无序节点对生成唯一ID(u-v和v-u生成相同ID) mutual_edges$pair_id <- apply( mutual_edges[, c("from", "to")], 1, function(x) paste(sort(x), collapse = "-") ) # 步骤3:按唯一ID去重,每个节点对仅保留第一条边 result <- mutual_edges[!duplicated(mutual_edges$pair_id), c("from", "to")]
方法2:固定规则去重(可控保留边)
如果需要固定保留规则(例如永远保留起点编号小于终点编号的边,避免边表顺序影响输出结果),可以直接按规则筛选:
library(igraph) g <- sample_gnm(10, 50, directed=TRUE) ff <- as_data_frame(g) # 步骤1:提取所有互选边 mutual_edges <- ff[which_mutual(g) == 1, ] # 步骤2:自定义保留规则,此处保留from < to的边,可按需修改 result <- mutual_edges[mutual_edges$from < mutual_edges$to, c("from", "to")]
两种方法输出的结果中,每个互选二元组仅对应1条边记录,符合需求。
内容的提问来源于stack exchange,提问作者cliu
相关产品推荐
相关产品推荐

