在R中高效地按组复制矩阵行

3

我希望你能够在R中找到一种基于分组的高效复制矩阵行的方法。假设我有以下矩阵a

a <- matrix(
  c(1, 2, 3,
    4, 5, 6,
    7, 8, 9),
  ncol = 3, byrow = TRUE
)

我希望创建一个新的矩阵,其中每一行都根据向量中指定的数字(我称之为“组”)重复a,例如:
reps <- c(2, 3, 4)

在这种情况下,得到的矩阵将是:
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    1    2    3
[3,]    4    5    6
[4,]    4    5    6
[5,]    4    5    6
[6,]    7    8    9
[7,]    7    8    9
[8,]    7    8    9
[9,]    7    8    9

这是目前我想到的唯一解决方案:

matrix(
  rep(a, times = rep(reps, times = 3)), 
  ncol = 3, byrow = FALSE
)

注意,在这个解决方案中,我必须两次使用rep() - 首先复制reps向量,然后再复制a的每一行。
这个解决方案可以正常工作,但是我正在寻找一种更有效率的解决方案,因为在我的情况下,这是在优化循环内完成的,并且在循环的每次迭代中进行计算。如果a很大,则速度相当慢。
我注意到这个问题非常相似,但它是关于重复每行相同次数的。这个问题也类似地涉及效率,但它是关于复制整个矩阵的。
更新
由于我对效率感兴趣,因此这里简单比较了迄今为止提供的解决方案...随着更多方案的出现,我将更新此内容,但总的来说,根据目前的结果,F. Privé提供的seq_along方案是最快的。
library(dplyr)
library(tidyr)

a <- matrix(seq(9), ncol = 3, byrow = TRUE)
reps <- c(2, 3, 4)

rbenchmark::benchmark(
  "original solution" = {
    result <- matrix(rep(a, times = rep(reps, times = 3)),
      ncol = 3, byrow = FALSE)
  },
  "seq_along" = {
    result <- a[rep(seq_along(reps), reps), ]
  },
  "uncount" = {
    result <- as.data.frame(a) %>%
      uncount(reps)
  },
    replications = 1000,
    columns = c("test", "replications", "elapsed", "relative")
)

               test replications elapsed relative
1 original solution         1000   0.004    1.333
2         seq_along         1000   0.003    1.000
3           uncount         1000   1.722  574.000
3个回答

4

只需使用a[rep(seq_along(reps),reps),]


1
< p > 使用uncount的另一个选项

library(dplyr)
library(tidyr)
as.data.frame(a) %>%
 uncount(reps)

-输出

V1 V2 V3
1  1  2  3
2  1  2  3
3  4  5  6
4  4  5  6
5  4  5  6
6  7  8  9
7  7  8  9
8  7  8  9
9  7  8  9

1
从你的回答中学到了 uncount,谢谢! - ThomasIsCoding
1
@ThomasIsCoding 这里有一个很棒的解决方案 链接 - akrun

1

另一种基于R的选项(不如@F. Privé@akrun的答案那样优雅)

> t(do.call(cbind, mapply(replicate, reps, asplit(a, 1))))
      [,1] [,2] [,3]
 [1,]    1    2    3
 [2,]    1    2    3
 [3,]    4    5    6
 [4,]    4    5    6
 [5,]    4    5    6
 [6,]    7    8    9
 [7,]    7    8    9
 [8,]    7    8    9
 [9,]    7    8    9

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接