使用Jaccard相似度为图边分配权重时遇错误,求原因解析
问题原因与解决方案
咱们一步一步拆解你遇到的两个问题:
1. 「subscript out of bounds」错误的核心原因
similarity.jaccard(g) 返回的是一个顶点×顶点的相似度矩阵,矩阵的行和列默认按图中顶点的数字ID(即顶点在图中的顺序,从1开始)索引。但如果你原始数据里用的是自定义顶点名称(比如字符串、非连续数字),get.edgelist(g) 获取的边列表里存的就是这些名称,而非数字ID。
举个例子:假设你的图顶点是A、B、C,sim 矩阵的行/列是1、2、3对应A、B、C,但 el 里的边是[A,B],这时候用sim[el]相当于用字符串去索引数字下标的矩阵,自然会触发「下标越界」的错误。
2. 「length of NULL cannot be changed」警告的由来
这个警告是连锁反应:因为sim[el]的结果无效(比如长度为0或和边数不匹配),当你尝试把这个无效值赋值给E(g)$weight时,由于E(g)$weight原本是NULL(图一开始没有权重属性),R无法修改一个NULL对象的长度,所以抛出这个警告。
修复步骤
这里有两种简单的修复方式,选一种适合你的即可:
方式一:把边列表转换为顶点数字ID
先将边列表中的顶点名称转换成对应的数字ID,再去索引相似度矩阵:
dat <- read.delim(file.choose(), header = F) g <- graph_from_data_frame(dat, directed = F) g <- simplify(g) sim <- similarity.jaccard(g) el <- get.edgelist(g) # 把边列表中的顶点名称转换为数字ID el_ids <- apply(el, 1, function(edge) match(edge, V(g)$name)) # 赋值权重 E(g)$weight <- sim[el_ids]
方式二:给相似度矩阵添加顶点名称索引
直接把sim矩阵的行名和列名设置为顶点名称,这样边列表里的名称就能直接索引:
dat <- read.delim(file.choose(), header = F) g <- graph_from_data_frame(dat, directed = F) g <- simplify(g) sim <- similarity.jaccard(g) # 给相似度矩阵设置行/列名为顶点名称 rownames(sim) <- V(g)$name colnames(sim) <- V(g)$name el <- get.edgelist(g) # 现在可以直接用边列表索引赋值 E(g)$weight <- sim[el]
你也可以先运行head(el)和head(sim)查看两者的索引是否匹配,确认问题后再用上面的方法修复,这样更稳妥。
内容的提问来源于stack exchange,提问作者Saeed VA
相关产品推荐
相关产品推荐

