在R的igraph中筛选成员数>3的课程间二分图连接
我来帮你搞定这个问题!从学生选课的二分图转换到只保留共同选课学生数>3的课程关联图,其实分几步就能完成,我给你详细拆解一下:
核心思路
我们需要先把「学生-课程」的二分图,投影成「课程-课程」的共现图(边的权重就是同时选两门课的学生数量),然后过滤掉权重≤3的边,最后移除孤立的课程节点,就能得到你想要的仅包含生物学和化学且带连线的图了。
Python 实现示例(基于igraph)
假设你的选课数据是类似(学生ID, 课程名)的格式,代码如下:
import igraph as ig # 替换成你的真实选课数据 enrollments = [ ("s1", "生物学"), ("s2", "生物学"), ("s3", "生物学"), ("s4", "生物学"), ("s5", "生物学"), ("s1", "化学"), ("s2", "化学"), ("s3", "化学"), ("s4", "化学"), ("s6", "化学"), ("s1", "数学"), ("s2", "数学"), ("s3", "数学"), ("s7", "物理"), ("s8", "物理") ] # 1. 构建二分图 g = ig.Graph.TupleList(enrollments, directed=False) # 标记节点类型:True=学生,False=课程(根据你的数据格式调整判断逻辑) g.vs["type"] = [v["name"].startswith("s") for v in g.vs] # 2. 投影为课程间的共现图,权重=共同选课的学生数 course_graph = g.bipartite_projection(types=g.vs["type"], which=1, weights="weight") # 参数说明:which=1 表示选择课程类型的节点;weights="weight" 让边权重自动计算共同邻居数 # 3. 过滤掉权重≤3的边 course_graph.delete_edges(course_graph.es.select(weight_le=3)) # 4. 移除没有关联的孤立课程节点 course_graph.delete_vertices(course_graph.vs.select(degree=0)) # 查看结果 print("剩余课程节点:", [v["name"] for v in course_graph.vs]) print("边及共同学生数:", [(e.source_vertex["name"], e.target_vertex["name"], e["weight"]) for e in course_graph.es]) # 可选:可视化结果 ig.plot(course_graph, vertex_label=course_graph.vs["name"], edge_label=course_graph.es["weight"])
R 实现示例(基于igraph)
如果你用R处理数据,代码逻辑是一致的:
library(igraph) # 替换成你的真实选课数据 enrollments <- data.frame( student = c("s1", "s2", "s3", "s4", "s5", "s1", "s2", "s3", "s4", "s6", "s1", "s2", "s3", "s7", "s8"), course = c("生物学", "生物学", "生物学", "生物学", "生物学", "化学", "化学", "化学", "化学", "化学", "数学", "数学", "数学", "物理", "物理") ) # 1. 构建二分图 g <- graph_from_data_frame(enrollments, directed = FALSE) # 标记节点类型:TRUE=学生,FALSE=课程 V(g)$type <- V(g)$name %in% enrollments$student # 2. 投影为课程共现图,权重=共同选课学生数 course_graph <- bipartite_projection(g, types = V(g)$type, which = "false") # 参数说明:which="false" 选择课程类型的节点 # 3. 过滤权重≤3的边 course_graph <- delete_edges(course_graph, E(course_graph)[weight <= 3]) # 4. 移除孤立节点 course_graph <- delete_vertices(course_graph, V(course_graph)[degree(course_graph) == 0]) # 查看结果 cat("剩余课程节点:", V(course_graph)$name, "\n") cat("边及共同学生数:", E(course_graph)$weight, "\n") # 可选:可视化 plot(course_graph, vertex.label = V(course_graph)$name, edge.label = E(course_graph)$weight)
常见问题排查
如果你的代码没得到预期结果,大概率是这几个原因:
- 二分图类型标记错误:一定要确保
type属性正确区分了学生和课程节点,否则投影会出错。 - 没开启权重计算:投影时必须指定
weights参数(Python),否则边不会带上共同学生数的权重。 - 过滤条件写反:要删除的是
weight<=3的边,别写成weight>=3了。
内容的提问来源于stack exchange,提问作者Kimberly
相关产品推荐
相关产品推荐

