如何避免 R 中的循环?
How to avoid loops in R?
我正在用 R 处理一个项目。该项目是给定节点之间的边的大数据,以测试测试边是否为真。在项目中,基本元素应该是"edges",这样我们就可以判断给定的边是否真实。那么问题来了。我们创建了一个包含两列 "from" 节点和 "to" 节点的数据框以指示边,即 edgesData
然后我们使用 igraph 从中创建了一个图,即graph
.我们可以计算两个特定节点的相似度,使用
similarity.jaccard(graph, vids = V(graph)[edgesData[1,1], edgesData[1,2]])
但是我们怎样才能得到所有边的table呢?我试过了
similarity.jaccard(graph, vids = V(graph)[edgesData[,1], edgesData[,2]])
但是没用。我也试过了
similarity.jaccard(graph, vids = E(graph))
也没用。一个明显的方法是使用循环,从数据框中检索每一行,但这似乎是个坏主意。那么,任何人都可以给我一些建议吗?谢谢!
编辑:
好吧,这个问题似乎有点令人困惑,所以我为此写了一个循环解决方案:
tpData <- edgesData
simList <- c()
while(nrow(tpData) > 0) {
v1 <- tpData[1,1]
v2 <- tpData[1,2]
simList <- c(simList, similarity.jaccard(graph, V(graph)[v1, v2])[1,2])
tpData <- tpData[-1,]
}
在这段代码中,我试图从每一行中获取两个元素[1]、[2],然后计算相似度。由于行数接近 2000 万,因此需要很长时间才能完成这项工作。必须有更好的方法来解决这个问题。有谁可以帮助我吗?谢谢。
不确定这是否是最有效的方法,但我自己过去曾使用过它。这是一个使用 dplyr 的简单示例:
library(igraph)
g <- graph.ring(5)
data.frame(similarity.jaccard(g)) -> dt
dt
# X1 X2 X3 X4 X5
# 1 1.0000000 0.0000000 0.3333333 0.3333333 0.0000000
# 2 0.0000000 1.0000000 0.0000000 0.3333333 0.3333333
# 3 0.3333333 0.0000000 1.0000000 0.0000000 0.3333333
# 4 0.3333333 0.3333333 0.0000000 1.0000000 0.0000000
# 5 0.0000000 0.3333333 0.3333333 0.0000000 1.0000000
library(dplyr)
data.frame(expand.grid(1:nrow(dt),1:ncol(dt))) %>% # combine all nodes (pairs)
select(node1=Var1, node2=Var2) %>% # rename
group_by(node1,node2) %>% # group in order to get each row separately
do(data.frame(simil = dt[.$node1,.$node2])) %>% # pick the corresponding similarities based on the nodes' pair
ungroup
# node1 node2 simil
# 1 1 1 1.0000000
# 2 1 2 0.0000000
# 3 1 3 0.3333333
# 4 1 4 0.3333333
# 5 1 5 0.0000000
# 6 2 1 0.0000000
# 7 2 2 1.0000000
# 8 2 3 0.0000000
# 9 2 4 0.3333333
# 10 2 5 0.3333333
# .. ... ... ...
我正在用 R 处理一个项目。该项目是给定节点之间的边的大数据,以测试测试边是否为真。在项目中,基本元素应该是"edges",这样我们就可以判断给定的边是否真实。那么问题来了。我们创建了一个包含两列 "from" 节点和 "to" 节点的数据框以指示边,即 edgesData
然后我们使用 igraph 从中创建了一个图,即graph
.我们可以计算两个特定节点的相似度,使用
similarity.jaccard(graph, vids = V(graph)[edgesData[1,1], edgesData[1,2]])
但是我们怎样才能得到所有边的table呢?我试过了
similarity.jaccard(graph, vids = V(graph)[edgesData[,1], edgesData[,2]])
但是没用。我也试过了
similarity.jaccard(graph, vids = E(graph))
也没用。一个明显的方法是使用循环,从数据框中检索每一行,但这似乎是个坏主意。那么,任何人都可以给我一些建议吗?谢谢!
编辑: 好吧,这个问题似乎有点令人困惑,所以我为此写了一个循环解决方案:
tpData <- edgesData
simList <- c()
while(nrow(tpData) > 0) {
v1 <- tpData[1,1]
v2 <- tpData[1,2]
simList <- c(simList, similarity.jaccard(graph, V(graph)[v1, v2])[1,2])
tpData <- tpData[-1,]
}
在这段代码中,我试图从每一行中获取两个元素[1]、[2],然后计算相似度。由于行数接近 2000 万,因此需要很长时间才能完成这项工作。必须有更好的方法来解决这个问题。有谁可以帮助我吗?谢谢。
不确定这是否是最有效的方法,但我自己过去曾使用过它。这是一个使用 dplyr 的简单示例:
library(igraph)
g <- graph.ring(5)
data.frame(similarity.jaccard(g)) -> dt
dt
# X1 X2 X3 X4 X5
# 1 1.0000000 0.0000000 0.3333333 0.3333333 0.0000000
# 2 0.0000000 1.0000000 0.0000000 0.3333333 0.3333333
# 3 0.3333333 0.0000000 1.0000000 0.0000000 0.3333333
# 4 0.3333333 0.3333333 0.0000000 1.0000000 0.0000000
# 5 0.0000000 0.3333333 0.3333333 0.0000000 1.0000000
library(dplyr)
data.frame(expand.grid(1:nrow(dt),1:ncol(dt))) %>% # combine all nodes (pairs)
select(node1=Var1, node2=Var2) %>% # rename
group_by(node1,node2) %>% # group in order to get each row separately
do(data.frame(simil = dt[.$node1,.$node2])) %>% # pick the corresponding similarities based on the nodes' pair
ungroup
# node1 node2 simil
# 1 1 1 1.0000000
# 2 1 2 0.0000000
# 3 1 3 0.3333333
# 4 1 4 0.3333333
# 5 1 5 0.0000000
# 6 2 1 0.0000000
# 7 2 2 1.0000000
# 8 2 3 0.0000000
# 9 2 4 0.3333333
# 10 2 5 0.3333333
# .. ... ... ...