社交网络分析:如何在R中从人口统计数据生成带权重边列表
问题描述
现有包含n个个体、k个社会特征变量的人口统计数据集,拟基于此开展社交网络分析:以个体为网络顶点,共享社会特征为边,边权重为共享特征的数量(一致项数)。需实现通过比对数据行的一致项来计算边的权重。
可复现示例数据集代码
# 可复现示例 id <- c(1:4) sex <- c("male", "male", "female", "female") age <- c("young", "young", "young", "old") df <- data.frame(id, sex, age)
生成的数据集:
id sex age 1 1 male young 2 2 male young 3 3 female young 4 4 female old
已生成的边列表
通过以下代码生成所有顶点的唯一组合边列表:
# 生成所有id的唯一组合 edge_list <- as.data.frame(t(combn(df$id, 2))) colnames(edge_list) <- c("V1", "V2")
边列表结果:
V1 V2 1 1 2 2 1 3 3 1 4 4 2 3 5 2 4 6 3 4
预期输出
需计算每条边的权重,得到如下格式的数据集:
V1 V2 weights 1 1 2 2 # 个体1与2共享性别和年龄,权重=2 2 1 3 1 # 个体1与3仅共享年龄,权重=1 3 1 4 0 # 个体1与4无共享特征,权重=0 4 2 3 1 # ... 5 2 4 0 6 3 4 1
解决方案
方法1:使用dplyr关联计算
通过将边列表与原始数据集两次关联,获取两个个体的特征后,逐列比对统计一致项数量:
library(dplyr) # 保留原始数据集避免覆盖 original_df <- df # 关联V1对应的特征并重命名 edge_list <- edge_list %>% left_join(original_df, by = c("V1" = "id")) %>% rename_with(~ paste0(., "_v1"), -c(V1, V2)) # 关联V2对应的特征并重命名 edge_list <- edge_list %>% left_join(original_df, by = c("V2" = "id")) %>% rename_with(~ paste0(., "_v2"), -c(V1, V2, ends_with("_v1"))) # 按行统计特征一致的数量 edge_list <- edge_list %>% rowwise() %>% mutate(weights = sum(c_across(ends_with("_v1")) == c_across(ends_with("_v2")))) %>% ungroup() %>% select(V1, V2, weights) print(edge_list)
方法2:使用base R循环实现
遍历边列表的每一行,提取两个个体的特征向量,计算相等元素的数量:
original_df <- df edge_list <- as.data.frame(t(combn(df$id, 2))) colnames(edge_list) <- c("V1", "V2") # 初始化权重列 edge_list$weights <- 0 # 遍历每条边计算权重 for(i in 1:nrow(edge_list)){ # 获取两个个体的特征(排除id列) row1 <- original_df[original_df$id == edge_list$V1[i], -1] row2 <- original_df[original_df$id == edge_list$V2[i], -1] # 统计特征一致的数量 edge_list$weights[i] <- sum(row1 == row2) } print(edge_list)
内容的提问来源于stack exchange,提问作者Max_BY
相关产品推荐
相关产品推荐

