我有以下数据框(称为cp
):
v1 v2 v3 v4
1 1 2 3 4
2 3 1 2 4
3 4 2 1 3
其中1,2,3和4是有向图上的节点。节点之间的距离由以下加权邻接矩阵给出(让我们称之为B
):
0 3 1 2
3 0 1 4
1 1 0 2
2 4 2 0
我需要使用邻接矩阵的行和列给出的节点之间的距离来扩充数据框中的列(同样是数据框cp
):
v1 v2 v3 v4 V5 V6 V7
1 1 2 3 4 3 1 2
2 3 1 2 4 1 3 4
3 4 2 1 3 4 3 1
即,列V5, V6 and V7
上的值来自查找合并v1
到v4
中相邻节点对之间的距离。例如,列V5
中的3是距节点1和2的距离 - 在矩阵B
的第一行和第二列(即3)中找到,依此类推。 / p>
我在R中编写了以下代码来实现此目的:
for (i in 1:3){
for (j in 5:7){
cp[i, j] <- B[cp[i, j - 4], cp[i, j - 3]]
}
}
该代码可以很好地处理几个观察数据框。问题是处理9列和1100万观测数据帧需要花费很多时间。你可以帮我找一个没有for循环的更有效的方法吗?
答案 0 :(得分:0)
您可以尝试使用更快的方法,因为您的数据框cp
有9列:
res <- apply(mapply(seq, seq(ncol(cp)-1), 2:ncol(cp)), 2, function(i) B[cp[,i]])
# [,1] [,2] [,3]
#[1,] 3 1 2
#[2,] 1 3 4
#[3,] 4 3 1
cbind(cp, res)
会提供您想要的输出。
您可以按cp
将数据框as.matrix(cp)
转换为矩阵。这里使用类型矩阵是因为更容易进行矢量化。
基准测试(cp
的{{1}}
1e+6 x 9
答案 1 :(得分:0)
在R中,矩阵存储在一维向量中。您可以使用此属性在矩阵中使用this和index索引对。
因此你可以这样做:
B <- as.matrix(B)
cp <- cbind(cp, sapply(1:(ncol(cp) - 1), function(ii){
B[cp[,ii] + nrow(B) * (cp[,ii+1] - 1)]
}))
cp
# v1 v2 v3 v4 1 2 3
# 1 1 2 3 4 3 1 2
# 2 3 1 2 4 1 3 4
# 3 4 2 1 3 4 3 1