【问题标题】:Quickly generate the cartesian product of a matrix快速生成矩阵的笛卡尔积
【发布时间】:2010-11-28 12:41:35
【问题描述】:

假设我有一个矩阵x,它包含 10 行和 2 列。我想生成一个新矩阵 M,其中包含来自 x 的每一对唯一行 - 即一个具有 55 行和 4 列的新矩阵。

例如,

x <- matrix (nrow=10, ncol=2, 1:20)

M <- data.frame(matrix(ncol=4, nrow=55))
k <- 1
for (i in 1:nrow(x))
for (j in i:nrow(x))
{
    M[k,] <- unlist(cbind (x[i,], x[j,]))
    k <- k + 1
}

所以,x 是:

      [,1] [,2]
 [1,]    1   11
 [2,]    2   12
 [3,]    3   13
 [4,]    4   14
 [5,]    5   15
 [6,]    6   16
 [7,]    7   17
 [8,]    8   18
 [9,]    9   19
[10,]   10   20

然后M 有 4 列,前两列是来自 x 的一行,接下来的两列是来自 x 的另一行:

> head(M,10)
   X1 X2 X3 X4
1   1 11  1 11
2   1 11  2 12
3   1 11  3 13
4   1 11  4 14
5   1 11  5 15
6   1 11  6 16
7   1 11  7 17
8   1 11  8 18
9   1 11  9 19
10  1 11 10 20

在 R 中是否有更快或更简单(或两者兼有)的方法?

【问题讨论】:

    标签: r matrix cartesian


    【解决方案1】:

    expand.grid() 函数对此有用:

    R> GG <- expand.grid(1:10,1:10)
    R> GG <- GG[GG[,1]>=GG[,2],]     # trim it to your 55 pairs
    R> dim(GG)
    [1] 55  2
    R> head(GG)
      Var1 Var2
    1    1    1
    2    2    1
    3    3    1
    4    4    1
    5    5    1
    6    6    1
    R> 
    

    现在您有了 'n*(n+1)/2' 个子集,您可以简单地索引您的原始矩阵。

    【讨论】:

      【解决方案2】:

      我不太了解你在做什么,所以我只是扔掉一些可能有用或可能没有帮助的东西。

      这是我认为的两列的笛卡尔积:

      expand.grid(x[,1],x[,2])
      

      【讨论】:

      • 从来不知道 expand.grid()。 Dirk 的回答将这一切结合在一起(一如既往......)
      【解决方案3】:

      您也可以尝试“关系”包。 Here is the vignette. 应该是这样的:

      relation_table(x %><% x)
      

      【讨论】:

        【解决方案4】:

        使用德克的回答:

        idx <- expand.grid(1:nrow(x), 1:nrow(x))
        idx<-idx[idx[,1] >= idx[,2],]
        N <- cbind(x[idx[,2],], x[idx[,1],])
        
        > all(M == N)
        [1] TRUE
        

        谢谢大家!

        【讨论】:

          【解决方案5】:

          受其他答案的启发,这里是一个实现两个矩阵的笛卡尔积的函数,在两个矩阵的情况下,完整的笛卡尔积,只有一个参数,每对省略一个:

          cartesian_prod <- function(M1, M2) {
          if(missing(M2)) {  M2 <- M1
               ind  <- expand.grid(1:NROW(M1), 1:NROW(M2))
               ind <- ind[ind[,1] >= ind[,2],] } else {
                                                    ind  <- expand.grid(1:NROW(M1), 1:NROW(M2))}
          rbind(cbind(M1[ind[,1],], M2[ind[,2],]))
          

          }

          【讨论】:

            猜你喜欢
            • 2016-10-08
            • 1970-01-01
            • 2021-05-06
            • 2018-07-04
            • 2021-09-05
            • 1970-01-01
            • 2016-05-07
            • 2014-02-01
            • 2012-11-18
            相关资源
            最近更新 更多