两个更多的解决方案:
第一个是对问题中示例的修改。
do.call("rbind", rep(list(A), n))
第二种方法涉及到展开矩阵,复制它并重新组装它。
matrix(rep(t(A),n), ncol=ncol(A), byrow=TRUE)
由于要求效率,需要进行基准测试。
library("rbenchmark")
A <- matrix(1:15, nrow=3)
n <- 10
benchmark(rbind(A, A, A, A, A, A, A, A, A, A),
do.call("rbind", replicate(n, A, simplify=FALSE)),
do.call("rbind", rep(list(A), n)),
apply(A, 2, rep, n),
matrix(rep(t(A),n), ncol=ncol(A), byrow=TRUE),
order="relative", replications=100000)
这将会给出:
test replications elapsed
1 rbind(A, A, A, A, A, A, A, A, A, A) 100000 0.91
3 do.call("rbind", rep(list(A), n)) 100000 1.42
5 matrix(rep(t(A), n), ncol = ncol(A), byrow = TRUE) 100000 2.20
2 do.call("rbind", replicate(n, A, simplify = FALSE)) 100000 3.03
4 apply(A, 2, rep, n) 100000 7.75
relative user.self sys.self user.child sys.child
1 1.000 0.91 0 NA NA
3 1.560 1.42 0 NA NA
5 2.418 2.19 0 NA NA
2 3.330 3.03 0 NA NA
4 8.516 7.73 0 NA NA
所以最快的方法是使用原始的
rbind
调用,但这假定
n
是固定的并且提前已知。如果
n
不是固定的,则最快的方法是
do.call("rbind", rep(list(A), n)
。这些是针对3x5矩阵和10次复制的情况。不同大小的矩阵可能会给出不同的排序。
编辑:
对于n = 600,结果的顺序不同(省略显式的
rbind
版本):
A <- matrix(1:15, nrow=3)
n <- 600
benchmark(do.call("rbind", replicate(n, A, simplify=FALSE)),
do.call("rbind", rep(list(A), n)),
apply(A, 2, rep, n),
matrix(rep(t(A),n), ncol=ncol(A), byrow=TRUE),
order="relative", replications=10000)
提供
test replications elapsed
4 matrix(rep(t(A), n), ncol = ncol(A), byrow = TRUE) 10000 1.74
3 apply(A, 2, rep, n) 10000 2.57
2 do.call("rbind", rep(list(A), n)) 10000 2.79
1 do.call("rbind", replicate(n, A, simplify = FALSE)) 10000 6.68
relative user.self sys.self user.child sys.child
4 1.000 1.75 0 NA NA
3 1.477 2.54 0 NA NA
2 1.603 2.79 0 NA NA
1 3.839 6.65 0 NA NA
如果您使用明确的rbind
版本,则比do.call("rbind", rep(list(A), n))
版本稍快一些,但差别不大,并且比apply
或matrix
版本慢。因此,在这种情况下,对任意n
的泛化不需要损失速度。
rbind
只在do.call
的方式下使用了一次。可能是复制操作导致了性能问题。 - Matthew PlourdeRprof
进行了测试,结果显示rbind
所需的时间是replicate
的两倍左右。这个结果让我感到惊讶。 - Wolfgang Pößnecker