在Tidygraph中对节点邻域的所有属性批量应用函数
批量计算igraph节点多属性的邻居平均值
问题描述
我有一个包含W1、W2、B1、B2等多个属性的igraph图,目前已能实现单个属性的邻居平均值计算,但希望通过一次操作批量处理所有目标属性,自动为每个属性生成对应的[属性名]_neighs变量(比如W1对应W1_neighs)。
原单个属性实现代码:
library(igraph) library(dplyr) # 创建环形图并添加属性 create_ring(40) %>% mutate(id = row_number()) %>% mutate(W1 = rnorm(40,75,15), W2 = rnorm(40,20,11), B1 = rnorm(40,2,11), B2 = rnorm(40,1,1)) %>% mutate(Neighs = local_members(order = 1, mindist = 1), k = local_size(order = 1, mindist = 1)) -> ring # 单个属性计算邻居均值 ring <- ring %>% mutate(W1_neighs = as.igraph(.) %>% ego(order = 1, mindist = 1) %>% sapply(function(v) mean(v$W1, na.rm=T)))
批量处理方案
方法1:使用purrr循环处理目标属性
提取需要计算的属性名列表,用purrr::map逐个计算邻居均值,再将结果合并到原数据框:
library(purrr) # 定义需要计算的目标属性 target_attrs <- c("W1", "W2", "B1", "B2") # 批量计算每个属性的邻居均值 neigh_means <- map_dfc(target_attrs, function(attr) { vals <- as.igraph(ring) %>% ego(order = 1, mindist = 1) %>% sapply(function(v) mean(v[[attr]], na.rm = TRUE)) tibble(!!paste0(attr, "_neighs") := vals) }) # 合并到原数据框 ring <- bind_cols(ring, neigh_means)
方法2:结合igraph的neighborhood与dplyr批量处理
利用neighborhood获取邻居节点索引,再通过聚合计算均值,代码更简洁:
# 获取每个节点的邻居索引列表 neigh_indices <- neighborhood(ring, order = 1, mindist = 1) # 批量计算每个属性的邻居均值 ring <- ring %>% mutate(across(all_of(target_attrs), ~map_dbl(neigh_indices, function(idx) mean(ring[[cur_column()]][idx], na.rm = TRUE)), .names = "{col}_neighs"))
说明
- 两种方法都能自动为目标属性生成对应的
[属性名]_neighs变量,避免重复编写单属性计算代码 target_attrs可根据实际需求调整,新增或删除属性只需修改该列表na.rm = TRUE用于计算时忽略缺失值,可根据场景选择是否保留
内容的提问来源于stack exchange,提问作者David Eagle
相关产品推荐
相关产品推荐

