从R中的多个起点和终点生成序列的矢量化方法

  • 本文关键字:矢量化 终点 方法 起点 r
  • 更新时间 :
  • 英文 :


R是否有从多个起点和终点生成序列的vecorized方法?我只能弄清楚如何使用某种形式的循环来做到这一点,如下所示(注意:我可以使用apply,但我希望有一个真正的矢量化解决方案)

starts <- c(1,2,3)
ends <- c(10,11,12)
mySequences <- matrix(NA, nrow = 3, ncol = 10)
for(i in 1:3){
  mySequences[i,] <- seq(starts[i], ends[i], length.out = 10)
}

但理想情况下,我希望它是以下内容:

mySequences <- seq(starts, ends, length.out = 10)

谢谢!

你觉得这种事情怎么样:

outer(X=c(1:3), Y=c(0:9), FUN="+")

如果像你的例子一样,宽度都是一样的(starts = 1:3; ends = 10:8; wd=10),那么创建一个矩阵,其中每一行都是序列1:wd使用 R 的回收规则有效地填充矩阵

m = matrix(seq(wd) - 1, length(starts), wd, byrow=TRUE)

每列需要递增的量缩放行,并添加开始,再次使用 R(逐列)回收

m * (ends - starts) / (wd - 1) + starts

作为函数

seqs_wd = function(starts, ends, wd=10) {
    m = matrix(seq(wd) - 1, length(starts), wd, byrow=TRUE)
    m * (ends - starts) / (wd - 1) + starts
}

一个简单的例子

> seqs_wd(1:3, 10:8)
     [,1]     [,2]     [,3]     [,4]     [,5]     [,6]     [,7]     [,8]
[1,]    1 2.000000 3.000000 4.000000 5.000000 6.000000 7.000000 8.000000
[2,]    2 2.777778 3.555556 4.333333 5.111111 5.888889 6.666667 7.444444
[3,]    3 3.555556 4.111111 4.666667 5.222222 5.777778 6.333333 6.888889
         [,9] [,10]
[1,] 9.000000    10
[2,] 8.222222     9
[3,] 7.444444     8

并与简单的实现相比

f0 = function(starts, ends, wd=10)
    mapply(seq, starts, ends, length.out=10)

一些时间

> library(microbenchmark)
> n = 1000
> starts = runif(n, 100, 200); ends = starts + runif(n, 100, 200)
> microbenchmark(seqs_wd(starts, ends), f0(starts, ends))
Unit: microseconds
                  expr       min         lq       mean     median         uq
 seqs_wd(starts, ends)   203.075   210.0705   219.3789   218.3225   223.8625
      f0(starts, ends) 17037.229 17370.7835 18468.4581 17862.2775 18629.8510
       max neval
   326.677   100
 32766.215   100

或与n = 1000000

> microbenchmark(seqs_wd(starts, ends), f0(starts, ends), times=10)
Unit: milliseconds
                  expr      min       lq     mean   median       uq     max
 seqs_wd(starts, ends) 318.1302 321.2502 327.4233 322.2663 326.0085 370.875
 neval
    10

所以一百万个序列大约是三分之一秒。

最新更新