R 中是否有一种有效的方法将矩阵 M2 的每一行 "paste" 到矩阵 M1 的每一行以获得所有可能的组合?
Is there an efficient way in R to "paste" each row of a matrix M2 onto each row of a matrix M1 to obtain all possible combinations?
假设我有两个矩阵:
M1 <- matrix(letters[1:9], nrow = 3, ncol = 3, byrow = T)
M2 <- matrix(letters[10:18], nrow = 3, ncol = 3, byrow = T)
实际上我有更大的矩阵,有 1000 行。我想要的是在不使用 for
循环的情况下生成以下内容的有效方法,因为这会导致 R 崩溃。
result <- rbind(cbind(M1, matrix(rep(letters[10:12], 3), nrow = 3, ncol = 3, byrow = T)),
cbind(M1, matrix(rep(letters[13:15], 3), nrow = 3, ncol = 3, byrow = T)),
cbind(M1, matrix(rep(letters[16:18], 3), nrow = 3, ncol = 3, byrow = T)))
本质上是将 M2
的每一行“粘贴”到 M1
的每一行,这样我就有了所有可能的组合。
您可以使用 expand.grid
在 M1
和 M2
中创建所有可能的行索引组合。
mat <- expand.grid(1:nrow(M1), 1:nrow(M2))
cbind(M1[mat[[1]], ], M2[mat[[2]], ])
# [,1] [,2] [,3] [,4] [,5] [,6]
# [1,] "a" "b" "c" "j" "k" "l"
# [2,] "d" "e" "f" "j" "k" "l"
# [3,] "g" "h" "i" "j" "k" "l"
# [4,] "a" "b" "c" "m" "n" "o"
# [5,] "d" "e" "f" "m" "n" "o"
# [6,] "g" "h" "i" "m" "n" "o"
# [7,] "a" "b" "c" "p" "q" "r"
# [8,] "d" "e" "f" "p" "q" "r"
# [9,] "g" "h" "i" "p" "q" "r"
您可以尝试 RcppAlgos::permuteGeneral
,它比 expand.grid
快得多。
FUN <- function(M1, M2) {
stopifnot(all.equal(dim(M1), dim(M2)))
p <- RcppAlgos::permuteGeneral(seq.int(dim(M1)[1]), 2, repetition=T)
cbind(M1[p[,2],], M2[p[,1],])
}
FUN(M1, M2)
# [,1] [,2] [,3] [,4] [,5] [,6]
# [1,] "a" "b" "c" "j" "k" "l"
# [2,] "d" "e" "f" "j" "k" "l"
# [3,] "g" "h" "i" "j" "k" "l"
# [4,] "a" "b" "c" "m" "n" "o"
# [5,] "d" "e" "f" "m" "n" "o"
# [6,] "g" "h" "i" "m" "n" "o"
# [7,] "a" "b" "c" "p" "q" "r"
# [8,] "d" "e" "f" "p" "q" "r"
# [9,] "g" "h" "i" "p" "q" "r"
基准
# Unit: microseconds
# expr min lq mean median uq max neval cld
# expand.grid 147.724 151.4235 628.38420 154.8680 157.291 46840.374 100 a
# RcppAlgos 74.500 77.4340 84.75624 80.1125 82.409 238.807 100 a
假设我有两个矩阵:
M1 <- matrix(letters[1:9], nrow = 3, ncol = 3, byrow = T)
M2 <- matrix(letters[10:18], nrow = 3, ncol = 3, byrow = T)
实际上我有更大的矩阵,有 1000 行。我想要的是在不使用 for
循环的情况下生成以下内容的有效方法,因为这会导致 R 崩溃。
result <- rbind(cbind(M1, matrix(rep(letters[10:12], 3), nrow = 3, ncol = 3, byrow = T)),
cbind(M1, matrix(rep(letters[13:15], 3), nrow = 3, ncol = 3, byrow = T)),
cbind(M1, matrix(rep(letters[16:18], 3), nrow = 3, ncol = 3, byrow = T)))
本质上是将 M2
的每一行“粘贴”到 M1
的每一行,这样我就有了所有可能的组合。
您可以使用 expand.grid
在 M1
和 M2
中创建所有可能的行索引组合。
mat <- expand.grid(1:nrow(M1), 1:nrow(M2))
cbind(M1[mat[[1]], ], M2[mat[[2]], ])
# [,1] [,2] [,3] [,4] [,5] [,6]
# [1,] "a" "b" "c" "j" "k" "l"
# [2,] "d" "e" "f" "j" "k" "l"
# [3,] "g" "h" "i" "j" "k" "l"
# [4,] "a" "b" "c" "m" "n" "o"
# [5,] "d" "e" "f" "m" "n" "o"
# [6,] "g" "h" "i" "m" "n" "o"
# [7,] "a" "b" "c" "p" "q" "r"
# [8,] "d" "e" "f" "p" "q" "r"
# [9,] "g" "h" "i" "p" "q" "r"
您可以尝试 RcppAlgos::permuteGeneral
,它比 expand.grid
快得多。
FUN <- function(M1, M2) {
stopifnot(all.equal(dim(M1), dim(M2)))
p <- RcppAlgos::permuteGeneral(seq.int(dim(M1)[1]), 2, repetition=T)
cbind(M1[p[,2],], M2[p[,1],])
}
FUN(M1, M2)
# [,1] [,2] [,3] [,4] [,5] [,6]
# [1,] "a" "b" "c" "j" "k" "l"
# [2,] "d" "e" "f" "j" "k" "l"
# [3,] "g" "h" "i" "j" "k" "l"
# [4,] "a" "b" "c" "m" "n" "o"
# [5,] "d" "e" "f" "m" "n" "o"
# [6,] "g" "h" "i" "m" "n" "o"
# [7,] "a" "b" "c" "p" "q" "r"
# [8,] "d" "e" "f" "p" "q" "r"
# [9,] "g" "h" "i" "p" "q" "r"
基准
# Unit: microseconds
# expr min lq mean median uq max neval cld
# expand.grid 147.724 151.4235 628.38420 154.8680 157.291 46840.374 100 a
# RcppAlgos 74.500 77.4340 84.75624 80.1125 82.409 238.807 100 a