R语言如何生成分组统计的科研机构合作incidence matrix
130万行的规模在R里处理完全无压力,根本不需要走两两机构配对合并的低效路线,先合并全量数据再按论文维度聚合是最优解,普通消费级笔记本跑全流程也就十几秒的事,具体实现步骤如下:
实现步骤
1. 批量读取合并所有CSV文件
直接遍历存储90份CSV的文件夹,一次性读入所有数据,仅保留分析需要的核心字段,丢弃Pages、引用量等无关字段减少内存占用。注意原数据集中机构名字段存在拼写错误(Intitute name少写了字母u),读入时直接重命名为统一的Institute字段避免后续报错:
library(tidyverse) # 替换为本地存储90份机构CSV的实际文件夹路径 csv_folder <- "your/local/csv/path" total_data <- list.files(csv_folder, pattern = "*.csv", full.names = TRUE) |> map_dfr(~read_csv( .x, col_select = c(Institute = `Intitute name`, ArticleCode, Area) ))
2. 按论文生成不重复的合作机构对
核心逻辑是按唯一的ArticleCode分组,把同一篇论文涉及的所有机构做两两不重复配对,同时绑定论文所属领域标签。过程中自动过滤单机构独发的论文,且对机构名称做排序处理,避免(In.AAA, In.BBB)和(In.BBB, In.AAA)被识别为两组不同的合作关系:
# 固定需要统计的5个细分领域,和输出要求对齐 target_areas <- c( "Arts & Humanities", "Life Sciences & Biomedicine", "Physical Sciences", "Social Sciences", "Technology" ) pair_data <- total_data |> # 去除同机构同论文的重复录入记录,避免计数错误 distinct(ArticleCode, Institute, Area) |> # 仅保留目标领域内的论文记录 filter(Area %in% target_areas) |> group_by(ArticleCode, Area) |> # 过滤掉单机构独发、无合作关系的论文 filter(n() >= 2) |> # 生成排序后的两两机构配对 summarise( inst_pair = list(as.data.frame(t(combn(sort(unique(Institute)), 2)))), .groups = "drop" ) |> unnest(inst_pair) |> rename(`Institute#1` = V1, `Institute#2` = V2)
3. 分组统计得到最终结果表
按机构对分组,分别统计合作总发文量、各细分领域合作发文量,将无合作领域的空值替换为0,最终输出的表结构完全匹配需求:
result <- pair_data |> group_by(`Institute#1`, `Institute#2`) |> summarise( TotArticles = n_distinct(ArticleCode), across(all_of(target_areas), ~n_distinct(ArticleCode[Area == .x])), .groups = "drop" ) |> # 无合作的领域计数填充为0 mutate(across(all_of(target_areas), ~replace_na(.x, 0))) # 导出结果为CSV文件 write_csv(result, "institution_cooperation_network.csv")
效率说明
- 全流程仅做一次全量文件读入,没有重复的表连接操作,不会产生冗余中间表占用内存
- 130万行数据在8G内存的普通设备上即可顺畅运行,总耗时不超过30秒,比两两遍历合并的方案效率高两个数量级以上
- 如果单篇论文同时属于多个领域,统计逻辑会自动将该论文计入对应领域的合作量,不会漏算
内容的提问来源于stack exchange,提问作者Giuseppe Caputo
相关产品推荐
相关产品推荐

