在R中创建网络变量以识别通过任职学校直接/间接关联的校长群体
嘿,这个需求本质上是要找出图的连通分量——把通过学校直接或间接关联的校长归为同一个群体,用R的igraph包就能完美解决,步骤清晰又高效,我给你一步步拆解:
核心思路
我们可以把校长和学校看作一个二分图的两类节点:
- 如果两个校长共享过同一所学校(或者通过转校链间接关联),他们就属于同一个连通分量(也就是你要的network)
- 利用图论工具自动识别这些连通分量,再映射回原数据即可
具体实现步骤
1. 安装并加载必要的包
install.packages("igraph") library(tidyverse) library(igraph)
2. 预处理数据
首先过滤掉school为NA的记录(这些无法参与关联),同时去重校长-学校的配对(避免同一校长同一学校重复计算):
# 清理原数据:去掉school为NA的行 ps_clean <- ps %>% filter(!is.na(school)) # 获取每个校长任职的唯一学校(去重,减少冗余) principal_school_links <- ps_clean %>% distinct(principal, school)
3. 构建二分图并提取连通分量
我们先构建校长-学校的二分图,再投影到校长节点(共享学校的校长会被连接),最后识别连通分量:
# 构建无向二分图:节点包含校长和学校 bipartite_graph <- graph_from_data_frame(principal_school_links, directed = FALSE) # 投影到校长节点:只保留校长之间的连接(共享学校则相连) principal_graph <- bipartite_projection( bipartite_graph, types = V(bipartite_graph)$name %in% principal_school_links$principal )[[1]] # 提取每个校长所属的连通分量(即network ID) network_membership <- components(principal_graph)$membership
4. 将network变量映射回原数据
把连通分量ID合并到原数据中,同时处理school为NA的记录(标记为NA):
ps_with_network <- ps %>% mutate( network = case_when( is.na(school) ~ NA_integer_, TRUE ~ network_membership[as.character(principal)] ) )
验证结果
看一下示例数据的输出:
- 校长
a仅任职于fhs,无关联校长,属于独立网络(network=1) - 校长
b和c通过lms关联,属于同一网络(network=2) - 校长
d和e通过ehs关联,属于同一网络(network=3) - 校长
e在year≥4的记录因school为NA,network标记为NA
完全符合你的预期!
可选优化:给network更友好的命名
如果不想用数字作为network标识,可以换成分量中第一个校长的名字(或者学校名):
# 生成network名称映射表 network_labels <- tibble( network_id = unique(network_membership), network_name = names(network_membership)[match(network_id, network_membership)] ) # 替换原数据的network ID为名称 ps_with_network_named <- ps_with_network %>% left_join(network_labels, by = c("network" = "network_id")) %>% rename(network_id = network, network = network_name)
这样network列会显示为a、b、d,更直观易懂。
内容的提问来源于stack exchange,提问作者lrna
相关产品推荐
相关产品推荐

