基于职业轨迹的组织间网络生成与可视化问题求助
基于职业轨迹构建组织间网络的R语言实现方案
原代码核心问题
- 数据过滤逻辑错误:原代码未正确提取各时段内的职业记录,索引操作
-(1:45)不符合数据结构,且未保留个体的时间序职业轨迹。 - 网络构建逻辑偏差:原代码通过比较个体姓名重叠构建节点连接,完全违背“个体从A公司转至B公司则A-B连边”的需求。
- 节点属性赋值错误:图节点应为公司名称,但原代码试图调用不存在的
carriers1节点属性,导致聚类与着色失败。
修正后的完整实现步骤
1. 加载依赖包与数据预处理
将宽格式数据转为长格式,便于按个体处理职业时间线:
# 加载所需包 library(tidyverse) library(igraph) library(ggraph) # 读取数据集(假设org已加载) org_long <- org %>% pivot_longer( cols = starts_with(c("Carrier.", "Year.")), names_to = c(".value", "seq"), names_pattern = "(Carrier|Year)\\.(\\d+)" ) %>% filter(!is.na(Carrier) & !is.na(Year)) %>% # 去除缺失值 arrange(Name, Year) # 按个体和年份排序
2. 分时间段提取有效职业轨迹
定义三个时间段,过滤出每个时段内的任职记录,仅保留能形成跳槽轨迹的个体(至少两次任职):
# 定义时间段 periods <- list( period1 = c(1958, 1978), period2 = c(1979, 1988), period3 = c(1989, 2010) ) # 按时间段过滤数据 period_data <- map(periods, function(p) { org_long %>% filter(Year >= p[1] & Year <= p[2]) %>% group_by(Name) %>% filter(n() >= 2) %>% # 保留至少有两次任职的个体 arrange(Year) %>% ungroup() })
3. 构建组织间边列表与网络
对每个时间段,生成公司间的跳槽边(A→B表示个体从A到B任职),支持加权边(统计跳槽人数):
build_org_network <- function(data) { # 生成每个个体的连续任职公司对 edges <- data %>% group_by(Name) %>% mutate(prev_carrier = lag(Carrier)) %>% filter(!is.na(prev_carrier)) %>% ungroup() %>% select(from = prev_carrier, to = Carrier) # 统计边的权重(跳槽人数) edge_weights <- edges %>% count(from, to, name = "weight") # 构建有向图(若需无向图,将mode设为"undirected") graph <- graph_from_data_frame(edge_weights, directed = TRUE) return(graph) } # 生成三个时间段的网络 period_graphs <- map(period_data, build_org_network)
4. 节点聚类与可视化
为节点添加聚类属性并绘制网络图:
# 定义聚类分组 cluster_groups <- list( Banks = c("Natixis", "CIC","HSBC France", "BPCE group", "Banque Hervet", "Credit Lyonnais", "BNP Paribas", "Societe General", "Investment banks", "Other banks"), Private_sector = c("Retail", "Media", "Technology", "Heavy industry", "energy sector", "real estate sector", "consulting", "pharmaceutical industry", "other sectors") ) # 为节点添加聚类属性与颜色 add_cluster_attr <- function(graph) { V(graph)$cluster <- case_when( V(graph)$name %in% cluster_groups$Banks ~ "Banks", V(graph)$name %in% cluster_groups$Private_sector ~ "Private sector", TRUE ~ "Public administration" ) color_palette <- c( "Banks" = "red", "Private sector" = "blue", "Public administration" = "gold" ) V(graph)$color <- color_palette[V(graph)$cluster] # 节点大小基于总连接数(度数) V(graph)$size <- degree(graph) * 0.8 return(graph) } # 处理所有时段的图 period_graphs <- map(period_graphs, add_cluster_attr) # 可视化函数 plot_network <- function(graph, title) { ggraph(graph, layout = "fr") + geom_edge_link(aes(width = weight), alpha = 0.3, color = "gray50") + geom_node_point(aes(color = cluster, size = size)) + geom_node_text(aes(label = name), size = 3, vjust = 1.2) + scale_edge_width(range = c(0.5, 3)) + scale_color_manual(values = c("red", "blue", "gold")) + theme_void() + labs(title = title) + theme(plot.title = element_text(hjust = 0.5)) } # 绘制三个时段的网络 p1 <- plot_network(period_graphs$period1, "1958-1978 组织间职业流动网络") p2 <- plot_network(period_graphs$period2, "1979-1988 组织间职业流动网络") p3 <- plot_network(period_graphs$period3, "1989-2010 组织间职业流动网络") # 查看图形 p1 p2 p3
关键说明
- 采用长格式数据处理职业轨迹,更便于按个体提取连续任职关系;
- 网络为有向图,准确反映“从A到B”的职业流动方向,若需无向图可修改
graph_from_data_frame的directed参数; - 边权重代表从A到B的跳槽人数,可根据需求改为二值边(仅保留存在性);
- 节点大小基于节点的度数(总连接数),也可替换为入度/出度或其他指标。
内容的提问来源于stack exchange,提问作者Thibaud Deguilhem
相关产品推荐
相关产品推荐

