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

时间:2016-01-26 21:53:18

标签: r

R是否具有从多个起点和终点生成序列的经过验证的方法?我只能弄清楚如何使用某种形式的循环,如下所示(注意:我可以使用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)

谢谢!

2 个答案:

答案 0 :(得分:2)

你喜欢这种事情:

  

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

答案 1 :(得分:0)

如果在您的示例中宽度相同(starts = 1:3; ends = 10:8; wd=10),则创建一个矩阵,其中每一行都是序列1:wd,使用R&#39; s回收规则有效填充矩阵< / p>

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

对于一百万个序列大约三分之一秒。