我尝试使用 igraph apckage计算 R 中的一些网络指标。 起初我读取了我的数据,而不是对其进行转换,最终将其转换为邻接矩阵形式。然后我计算这个数据集的度数值。
我想将我的代码放在循环中,因此我不需要手动更改条件 - 重新读取数据 - 并再次运行代码。但我没有运气。 " r"条件可能是" 1"或" 2",以及" g"条件是来自" 1"的数字。至" 21"。
到目前为止,我的代码看起来像这样:
p1 <- read.csv("matrix.csv")
p <- p1[p1$r=="1" & p1$g == "1",]
rownames(p) <- paste("id", p$id, sep=".")
p <- t(p[,-(1:3)])
p <- data.frame(p)
rr <- apply(p, 2, as.character)
m<-matrix(nrow=ncol(rr),ncol=ncol(rr))
for(col in 1:ncol(rr)){
matches<-rr[,col]==rr
match.counts<-colSums(matches)
match.counts[col]<-0
m[,col]<-match.counts
}
n<-graph.adjacency(m)
d<-degree(n, v=V(n))
&#34; p1&#34;的前几行:
1> p1
id g r X1 X2 X3 X4
1 1 1 1 1324;1256 1324;1256 752;1268 1892;1236
2 2 1 2 324;988 324;988 324;988 324;988
3 3 1 1 1312;1652 1312;1652 1828;608 712;656
4 4 1 2 324;988 324;988 324;988 324;988 ...
我知道我的代码非常难看......我之前没有编程经验,但我很想学习,所以我欢迎任何建议或建议。
提前致谢!
答案 0 :(得分:1)
这里我假设前3列是标识符,后面的任何列都以V1;V2
格式描述图形,其中V1
和V2
是顶点ID。
只需占用您数据框的一小部分,这就是我想出的。我认为您不需要创建邻接矩阵,因为您可以创建边缘列表。
require(igraph)
p1 <- read.csv(textConnection(
"id,g,r,X1,X2,X3,X4
1,1,1,1324;1256,1324;1256,752;1268,1892;1236
2,1,2,324;988,324;988,324;988,324;988
3,1,1,1312;1652,1312;1652,1828;608,712;656
4,1,2,324;988,324;988,324;988,324;988"))
为r和g的一个值执行此操作:
p <- p1[p1$r=="1" & p1$g == "1",] ## limit to only rows where r and g are 1
myEdges <- p[,-(1:3)] ## assuming edges are defined in all columns after the first 3
dat <- apply(myEdges, 1, function(strings) unlist(strsplit(strings, ';', fixed=TRUE)))
myGraph <- graph.data.frame(dat, directed=FALSE) # can change to directed by setting directed = TRUE
plot(myGraph) # see what the graph looks like, don't try if graph is large!
degree(myGraph)
# 1324 1256 752 1268 1892 1236 1312 1652 1828 608 712 656
# 2 2 1 1 1 1 2 2 1 1 1 1
要回答关于r和g的不同组合的过程自动化的评论,你可以使用嵌套for循环这样的方法(效率不高但可能对你的问题有效,具体取决于大小)
rVals <- 1:2
gVals <- 1:21
myGraphList <- rep( list(vector(mode = "list", length = length(gVals) )), length(rVals))
for(r in rVals) {
for(g in gVals) {
p <- p1[p1$r == r & p1$g == g,] ## limit to only certain values of r and g
myEdges <- p[,-(1:3)] ## assuming edges are defined in all columns after the first 3
if(nrow(myEdges) > 0) { ## Only need to create a graph if there are edges present
dat <- apply(myEdges, 1, function(strings) unlist(strsplit(strings, ';', fixed=TRUE)))
myGraphList[[r]][[g]] <- graph.data.frame(dat, directed=FALSE)
}
}
}
## Only 2 elements with an igraph object in this small example:
degree(myGraphList[[1]][[1]]) # when r == 1, g == 1
# 1324 1256 752 1268 1892 1236 1312 1652 1828 608 712 656
# 2 2 1 1 1 1 2 2 1 1 1 1
degree(myGraphList[[2]][[1]]) # when r == 2, g == 1
# 324 988
# 8 8