You need to enable JavaScript to run this app. R语言中使用apply或循环批量生成多学校多波次邻接矩阵列表
优惠活动
大模型
产品
解决方案
定价
更多

R语言中使用apply或循环批量生成多学校多波次邻接矩阵列表

批量生成邻接矩阵的实现方案

生成的结果结构与你手动编写的代码输出完全一致:顶层为按学校命名的列表,每个学校元素下是按观测波次命名的邻接矩阵子列表,无需重复编写逐组处理代码。

方法1:base R 显式循环(无额外依赖,兼容性最好)

直接复用你现有的过滤-建图-转矩阵逻辑,通过两层循环遍历所有学校、波次,无需调整原有处理步骤:

# 加载依赖包
library(igraph)
library(dplyr)

# 初始化结果存储列表
school_list <- list()
# 提取数据中所有唯一的学校ID
all_schools <- unique(edges$school)

# 外层循环:遍历每所学校
for (current_school in all_schools) {
  # 为当前学校初始化子列表,存储3个波次的邻接矩阵
  current_wave_list <- list()
  # 内层循环:遍历所有观测波次
  for (current_wave in unique(edges$wave)) {
    # 完全复用你原本的单组处理逻辑
    adj_matrix <- edges %>%
      filter(school == current_school & wave == current_wave) %>%
      graph_from_data_frame(directed = TRUE) %>%
      as_adjacency_matrix() %>%
      as.matrix()
    # 按波次命名存入子列表
    current_wave_list[[paste0("w", current_wave)]] <- adj_matrix
  }
  # 按学校ID命名存入顶层结果列表
  school_list[[paste0("school", current_school)]] <- current_wave_list
}

运行完成后,你原本手动生成的school1对象,直接通过school_list$school1即可调用,内容和手动编写的结果完全等价。

方法2:base R 嵌套lapply(避免显式循环,代码更简洁)

如果不想维护循环状态变量,可以用两层嵌套的lapply实现,逻辑和显式循环完全一致:

# 封装单组处理逻辑为独立函数
get_single_adj <- function(school_id, wave_id) {
  edges %>%
    filter(school == school_id & wave == wave_id) %>%
    graph_from_data_frame(directed = TRUE) %>%
    as_adjacency_matrix() %>%
    as.matrix()
}

# 生成最终结果列表
school_list <- lapply(unique(edges$school), function(s) {
  # 内层:对当前学校的所有波次生成矩阵列表
  wave_res <- lapply(unique(edges$wave), function(w) get_single_adj(s, w))
  # 为波次子列表设置名称
  names(wave_res) <- paste0("w", unique(edges$wave))
  wave_res
})
# 为顶层列表的每个元素设置学校命名
names(school_list) <- paste0("school", unique(edges$school))

方法3:tidyverse/purrr 实现(和现有管道逻辑无缝衔接)

如果你日常使用tidyverse生态,用purrr系列函数可以大幅压缩代码量,和你原本的管道写法适配度最高:

library(purrr)
library(dplyr)

school_list <- edges %>%
  # 按学校、波次完成分组
  group_by(school, wave) %>%
  # 对每个分组单独执行邻接矩阵转换
  summarise(adj = list(
    graph_from_data_frame(cur_data(), directed = TRUE) %>%
      as_adjacency_matrix() %>%
      as.matrix()
  ), .groups = "drop") %>%
  # 按学校拆分数据块
  split(.$school) %>%
  # 每个学校块单独提取对应波次的矩阵,生成命名子列表
  map(~ set_names(.$adj, paste0("w", .$wave)))
# 为顶层列表元素补充学校名前缀
names(school_list) <- paste0("school", names(school_list))

常见踩坑提示:如果某所学校某一波次存在孤立节点(即没有出现在任何边中的在册学生),直接基于边列表建图会导致邻接矩阵缺失这些节点的行/列。遇到这类情况时,可提前整理每个学校的全量在册学生列表,传入graph_from_data_frame()的vertices参数补全节点即可,不需要修改循环或批量处理的整体逻辑。


内容的提问来源于stack exchange,提问作者L. Tucker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.03 13:45:11