对于R中的二进制矩阵,有一种快速/有效的方法来使矩阵传递吗?也就是说,如果[i,j] == 1,并且[i,k] == 1,则设置[j,k] = 1.例如,假设我们有一个个体的方阵,并且连续1个/ column表示它们是相关的。有没有快速的方法来确定哪些人在某种程度上相关?
取矩阵Mx
Mx a b c d e
a 1 1 0 1 0
b 0 1 0 0 0
c 0 0 1 1 0
d 0 0 0 1 0
e 0 0 0 0 1
由于[a,b] == 1,[a,d] == 1,[b,d]和[d,b]应设置为1。 类似地,[c,d] == 1,并且由于a,b和d是相关的,a,b,c,d应该为1。最终矩阵看起来像这样,并且应该在对角线上对称。
Mx a b c d e
a 1 1 1 1 0
b 1 1 1 1 0
c 1 1 1 1 0
d 1 1 1 1 0
e 0 0 0 0 1
因此,对于家庭示例,这将意味着a,b,c和d以某种方式相关。 现在我有一个计算第二个矩阵的函数,但它在n ^ 3时间内运行,其中n是行/列的数量。有更快的方法吗?谢谢
n ^ 3功能:
# Repeat loop three times for completion
for (rep in 1:3) {
# For every individual i
for (i in 1:N) {
# For every individual j
for (j in 1:N) {
# For every individual k
for (k in 1:N) {
# If i and j are related and j and k are related
if (Mx[i,j] == 1 && Mx[j, k] == 1) {
#i and k are related
Mx[i,k] <- 1
Mx[k,i] <- 1
}
}
}
}
}
答案 0 :(得分:3)
找到与任意关系相关的等价关系
归结为找到相应图形的连通分量。
它可以完成
depth-first search。
它已在igraph
包中实现。
library(igraph)
n <- 5
A <- matrix( sample(0:1, n^2, prob=c(.8,.2), replace=T), n, n)
A
# [,1] [,2] [,3] [,4] [,5]
# [1,] 0 0 0 0 0
# [2,] 0 1 0 0 0
# [3,] 0 0 1 0 1
# [4,] 1 0 1 0 1
# [5,] 0 0 0 0 0
i <- clusters(graph.adjacency(A))$membership
B <- A
B[] <- i[row(A)] == i[col(A)]
B
# [,1] [,2] [,3] [,4] [,5]
# [1,] 1 0 1 1 1
# [2,] 0 1 0 0 0
# [3,] 1 0 1 1 1
# [4,] 1 0 1 1 1
# [5,] 1 0 1 1 1
如果你想要传递和反身闭包(反身,传递,但不一定是对称的 - 这个例子已经过敏,但不是反身):
library(relations)
relation_incidence( reflexive_closure( transitive_closure( as.relation(A) ) ) )
# Incidences:
# 1 2 3 4 5
# 1 1 0 0 0 0
# 2 0 1 0 0 0
# 3 0 0 1 0 1
# 4 1 0 1 1 1
# 5 0 0 0 0 1