在两个矩阵上使用 'apply' 而不是嵌套循环

Use 'apply' instead of a nested loop on two matrices

我有两个矩阵:

first.matrix  = matrix(c(1,1,2,3,3,2,4,1), nrow=2)
second.matrix = matrix(c(2,2,3,3,1,1,4,1), nrow=2)

并且我想找到 'first.matrix' 中的行与 second.matrix 中的行之间的相关性。在Java中,我会这样写:

results <- data.frame("first"=c(1:4),"second"=c(1:4), "cor"=c(1:4))
counter <- 1
for(i in 1:2) {
  a <- c(t(first.matrix[i,]))
  for(j in 1:2) {
    b <- c(t(second.matrix[j,]))    
    results$cor[counter] <- cor(a,b)
    results$first[counter]  <- i
    results$second[counter] <- j
    counter=counter+1
  }  
}

我正在尝试自学以 "right" 的方式在 R 中编写代码,并花时间阅读 R 教程和 Stack Overflow 上的问题。所以我知道我的解决方案需要使用 apply,但是尽我所能,我不知道如何实际编写它。我看到的所有示例都非常简单,涉及查找列或行的总和或平均值。 麻烦的是:

一个。我需要一个 'apply' 可以容纳一个函数,该函数接收两个变量,每个矩阵一行。这需要一些操作来检索行。我可以解决这个问题:

c(t(first.matrix[i,]))

但我不知道如何将其插入 'apply'

b。我需要结果告诉我第一个矩阵中的哪一行与第二个矩阵中的哪一行进行了比较,结果是什么。在我的示例中,运行 我编写的代码将导致:

 first second        cor
1     1      1  0.4000000
2     1      2 -0.6741999
3     2      1 -0.1348400
4     2      2  0.6363636

我不关心列是否有名称。

任何解决方案、提示或参考都将不胜感激:-)

一个解决方案是首先将 first.matrix 的行数与 second.matrix 的行数合并在一起以获得您想要的所有组合。基本上这只是让你得到你想要的矩阵的索引。然后你可以做一个 sapply 来获得相关性。

类似于:

    res<-merge(data.frame(first=1:nrow(first.matrix)),
               data.frame(second=1:nrow(second.matrix)))
    res$corr<-sapply(1:nrow(res),function(i) {
                        cor(first.matrix[res[i,1],],second.matrix[res[i,2],])
                        })
    res

#   first second       corr
#1     1      1  0.4000000
#2     2      1 -0.1348400
#3     1      2 -0.6741999
#4     2      2  0.6363636

您可以通过组合 expand.gridapply 来做到这一点。使用 expand.grid 得到一个 table 以及来自两个矩阵的所有可能的行组合,然后使用 apply 在这些组合上迭代你的函数。喜欢:

apply(# get a table with all possible combinations of rows
      expand.grid(seq(nrow(first.matrix)), seq(nrow(second.matrix))),
      # apply the upcoming function row-wise
      1,
      # now run cor over those combos of row
      function(x) cor(x = first.matrix[x[1],], y = second.matrix[x[2],]))

结果:

[1]  0.4000000 -0.1348400 -0.6741999  0.6363636