比较一个矩阵中的每一行与另一个矩阵的每一行

时间:2016-01-08 17:39:19

标签: r matrix dataframe compare rows

在对矩阵执行的过程之后(如果需要,可以将其转换为数据帧或其他形式),我想看看原始矩阵的行是否出现在新矩阵的任何位置。

E.g.Matrix1=(1,1,1,1,1;
             2,2,2,2,2;
             3,3,3,4,4;
             5,5,5,6,6)

我想知道(1,1,1,1,1),(2,2,2,2,2)和其他是否出现在Matrix2中。我还想知道矩阵2中是否出现非常相似的行,如(1,1,1,1,8)或(2,2,2,2,7)。具体来说,类似的意思是它们只有1或2个列条目不同(对于11列,它们有9个或更多列条目相同)。

我遇到的主要问题是处理时间,我只有11列我正在比较矩阵,但两个矩阵都有大约200,000行,所以我将比较200,000行和其他200,000行。 我有一个for循环的解决方案,但是需要200,000 * 200,000 ......

#Reproducible Example
Firstmatrix<-t(matrix(c(1,1,1,1,1,
                        2,2,2,2,2,
                        3,3,3,3,3,
                        0,0,0,0,0,
                        2,2,2,2,2,
                        4,4,4,4,4,
                        1,2,3,4,5,
                        1,1,1,1,6),
                        nrow=5,ncol=8))

Secondmatrix<-t(matrix(c(1,1,1,1,1,
                         1,1,1,1,1,
                         2,2,2,2,2,
                         3,3,3,3,3,
                         4,4,4,5,5,
                         5,5,5,4,4,
                         6,1,1,1,3,
                         3,1,1,1,6),
                         nrow=5,ncol=8))

#these matrices will be in a similar form to example above
#To time test larger matrices with more columns I have used:

Firstmatrix<-Firstmatrix[rep(seq_len(8), each=100),]
Secondmatrix<-Secondmatrix[rep(seq_len(8), each=100),]
#which create matrices with 100x as many rows and
t1<-Sys.time()
t2<-Sys.time()
t2-t1 
#either side of the code to measure how long it takes    

#I came up with:

Column.entries.in.common<-matrix(NA,nrow=nrow(Firstmatrix),ncol=1)
Maximum.Column.entries.in.common<-matrix(NA,nrow=nrow(Firstmatrix),ncol=1)

for (i in 1:nrow(Firstmatrix))
{
for (j in 1:nrow(Secondmatrix))
{
Column.entries.in.common[j]<-sum(Firstmatrix[i,]==Secondmatrix[j,])

Maximum.Column.entries.in.common[i]<-max(Column.entries.in.common)
}
}

生成一个向量,其中包含&#39; Firstmatrix&#39;中每一行的条目,以及它与'Secondmatrix&#39;中的任何行共有的最大列数,它适用于每个矩阵上有几千行,但运行200k * 200k是不可行的。我知道我应该使用mapply,但不确定如何指定它将对'Firstmatrix&#39;的每一行进行比较。反对每一行的第二个矩阵&#39;。之前的尝试只是将Firstmatrix的每个元素与Secondmatrix进行了比较。

非常感谢任何帮助。我知道它有很多计算,所以总是需要一段时间来运行,但是比我现在的代码更快,我认为需要大约4个月,这是朝着正确的方向迈出的一步!

1 个答案:

答案 0 :(得分:1)

这应该快得多,因为它只对一组行执行非向量化迭代,而其余行进行向量化。这使用了列连续存储的事实,因此At[, i]将被适当地回收以执行==操作。另一个好处是,获取列可能比获取行更快。

At <- t(Firstmatrix)
Bt <- t(Secondmatrix)
mx <- sapply(1:ncol(At), function(i) max(colSums(At[, i] == Bt)))

all.equal(mx, c(Maximum.Column.entries.in.common))
## [1] TRUE

<强>时序

这是一个时序比较,表明对于给定的数据,它在经过的时间的1/60左右运行。

system.time({
  Column.entries.in.common<-matrix(NA,nrow=nrow(Firstmatrix),ncol=1)
  Maximum.Column.entries.in.common<-matrix(NA,nrow=nrow(Firstmatrix),ncol=1)
  for (i in 1:nrow(Firstmatrix))
  {
    for (j in 1:nrow(Secondmatrix))
    {
    Column.entries.in.common[j]<-sum(Firstmatrix[i,]==Secondmatrix[j,])
    Maximum.Column.entries.in.common[i]<-max(Column.entries.in.common)
    }
  }
})
##   user  system elapsed 
##  10.99    0.00   11.12 


system.time({
  At <- t(Firstmatrix)
  Bt <- t(Secondmatrix)
  mx <- sapply(1:ncol(At), function(i) max(colSums(At[, i] == Bt)))
})
##   user  system elapsed 
##   0.19    0.00    0.19