我已经和R一起练习了一年了,现在我面临着一个新的问题:vectorization.基本上我希望我的代码更快。这是我的问题:我有一个包含0和1的矩阵,我想比较每一行和其他行,以找到相同位置的匹配。例如,我的矩阵是:a<-matrix(c(1,1,1,0,1,1,0,1,0,1,0,1,0,0,0),5,3)。在这种情况下,第一行和第二行有一个匹配,第一个和第三个匹配。我想要建立一个对称矩阵行维,并在每一个地方写的匹配和,在对角线上0。
我写的代码是:
a<-matrix(sample(c(0,1), size=18, replace=T), ncol=3) # a random matrix 6x3
mat<-diag(0,nrow=dim(a)[1])
n<-dim(a)[1]
for( i in 1:(n-1)){
for (j in (i+1):n){
mat[i,j]<-sum(ifelse(a[i,]==a[j,],1,0))
}}我正在寻找一些东西来改进这段代码并删除for循环。我当时正在申请,但除了第二行和最后一排外,一切都适用:
for( i in 1:(n-2)){
vv<-a[(i+1):n,]
mat3[i,(i+1):n]<-apply(vv,1,function(x) sum(ifelse(x==a[i,],1,0)))
}我不得不在for循环中放置2而不是1,因为应用只处理矩阵而不是数组(实际上,vv将是一个数组)。提前谢谢你。
发布于 2017-09-21 16:06:55
这个怎么样..。
a <- matrix(c(1,1,1,0,1,1,0,1,0,1,0,1,0,0,0), 5, 3)
b <- apply(a, 1, function(r) apply(a, 1, function(s) sum(r==s)))
diag(b) <- 0
b
[,1] [,2] [,3] [,4] [,5]
[1,] 0 1 3 1 3
[2,] 1 0 1 1 1
[3,] 3 1 0 1 3
[4,] 1 1 1 0 1
[5,] 3 1 3 1 0发布于 2017-09-21 16:08:06
不确定这是否比您的方法更快,但是下面是我如何处理它的方法。首先,列出您想要的所有组合的列表。
coms <- combn(1:nrow(a), 2) # combn from utils package
coms
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
#[1,] 1 1 1 1 2 2 2 3 3 4
#[2,] 2 3 4 5 3 4 5 4 5 5因此,第一列将比较1比2,第二列比较1到3,等等。
现在,编写一个函数来计算公共给定向量长度2中指示行索引的元素数。
funky <- function(com){
sum(a[com[1], ] == a[com[2], ])
}
funky(c(1, 2))
# [1] 1
funky(c(1, 3))
# [1] 3现在将此函数应用于组合矩阵。
apply(coms, 2, funky)
# [1] 1 3 1 3 1 1 1 1 3 1如果您喜欢在矩阵输出中这样做的话
mat <- diag(0, nrow = nrow(a))
mat[lower.tri(mat, diag = FALSE)] <- apply(coms, 2, funky)
t(mat)
# [,1] [,2] [,3] [,4] [,5]
# [1,] 0 1 3 1 3
# [2,] 0 0 1 1 1
# [3,] 0 0 0 1 3
# [4,] 0 0 0 0 1
# [5,] 0 0 0 0 0发布于 2017-09-21 18:37:05
你可以简单地做tcrossprod(a) + tcrossprod(1 - a)
https://stackoverflow.com/questions/46347927
复制相似问题